{"openapi":"3.1.1","info":{"title":"factuurmaken API","version":"1.0.0","description":"Create invoice drafts for review. Active API-enabled subscription required (Pro, Business, or qualifying complimentary access). All keys act in the account default administration, independent of the app selected administration. Money is integer euro cents. This is a REST API; no MCP endpoint or OAuth connection is provided."},"servers":[{"url":"https://factuurmaken.nl"}],"externalDocs":{"description":"Developer guide and invoice quickstart","url":"https://factuurmaken.nl/developers"},"security":[{"bearerAuth":[]}],"paths":{"/api/v1/clients":{"get":{"operationId":"listClients","summary":"Find clients","description":"Clients in the account default administration, newest first. Search name/email with q. No pagination. Ask the user when multiple clients match.","x-required-scopes":["clients:read"],"x-openai-isConsequential":false,"parameters":[{"name":"q","in":"query","required":false,"description":"Case-insensitive name or email search.","schema":{"type":"string"}}],"responses":{"200":{"description":"Matching clients.","content":{"application/json":{"schema":{"type":"object","properties":{"clients":{"type":"array","items":{"$ref":"#/components/schemas/Client"}}},"required":["clients"]}}}},"401":{"description":"invalid_api_key: missing, malformed, unknown or revoked Bearer key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"subscription_inactive, plan_not_allowed or insufficient_scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createClient","summary":"Create a client","description":"Creates a saved client. Omit number to assign the next client number. Search first to avoid duplicates; name/email are not unique. Retries are not deduplicated. Individual clients discard business-only fields.","x-required-scopes":["clients:write"],"x-openai-isConsequential":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientCreate"},"example":{"name":"Acme B.V.","email":"administratie@example.com","type":"business","vatMode":"standard"}}}},"responses":{"201":{"description":"Created client; null if removed before read-back.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"anyOf":[{"$ref":"#/components/schemas/Client"},{"type":"null"}]}},"required":["client"]}}}},"400":{"description":"invalid_json or validation; issues groups messages by top-level field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"invalid_api_key: missing, malformed, unknown or revoked Bearer key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"subscription_inactive, plan_not_allowed or insufficient_scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"duplicate_number: client number already exists or automatic numbering could not find a free number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/clients/{id}":{"get":{"operationId":"getClient","summary":"Read a client","description":"Reads a client in the account default administration.","x-required-scopes":["clients:read"],"x-openai-isConsequential":false,"parameters":[{"name":"id","in":"path","required":true,"description":"ID returned by this API.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Client.","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"$ref":"#/components/schemas/Client"}},"required":["client"]}}}},"401":{"description":"invalid_api_key: missing, malformed, unknown or revoked Bearer key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"subscription_inactive, plan_not_allowed or insufficient_scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: unknown client or outside this administration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/invoices":{"get":{"operationId":"listInvoices","summary":"List invoices","description":"Invoices in the account default administration, newest first. Includes drafts and existing credit invoices.","x-required-scopes":["invoices:read"],"x-openai-isConsequential":false,"parameters":[{"name":"clientId","in":"query","required":false,"description":"Only invoices linked to this client.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Derived display status; overdue can include an unsent draft.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","enum":["draft","final","sent","overdue","paid"],"description":"Derived display status. An unpaid draft with a past due date can be overdue."}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"description":"Number of rows to skip.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Page of invoices.","content":{"application/json":{"schema":{"type":"object","properties":{"invoices":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["invoices","total","limit","offset"]}}}},"400":{"description":"invalid_status: unsupported status filter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"invalid_api_key: missing, malformed, unknown or revoked Bearer key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"subscription_inactive, plan_not_allowed or insufficient_scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createInvoiceDraft","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for this logical create/append request. Reuse on retries.","schema":{"type":"string","minLength":1,"maxLength":128}}],"summary":"Create a draft or append lines","description":"Creates an unnumbered draft for a saved client. Sender, bank account and payment term come from account settings; VAT treatment comes from the client. The server calculates totals. Use onOpenConcept=create for a separate draft. append may change a draft scheduled for delivery until its delivery attempt starts. Send a unique Idempotency-Key header for each logical request and reuse it on retries. Matching requests return the same invoice and appended flag without adding lines again; reusing a key with different input returns 409. Keys are scoped to the administration and retained until account deletion. The returned invoice reflects its current state. Dates and notes are ignored on append. A successful draft can still need details before finalization; review it in the app.","x-required-scopes":["invoices:write"],"x-openai-isConsequential":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceCreate"},"example":{"clientId":"REPLACE_WITH_CLIENT_ID","onOpenConcept":"create","lines":[{"description":"Advies","quantity":8,"unit":"uur","unitPriceCents":9500,"vatRate":21}]}}}},"responses":{"200":{"description":"Lines appended; appended=true. sendPlanned=true means these lines will join an existing scheduled send.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"anyOf":[{"$ref":"#/components/schemas/InvoiceDetail"},{"type":"null"}]},"appended":{"type":"boolean"},"sendPlanned":{"type":"boolean"}},"required":["invoice","appended","sendPlanned"]}}}},"201":{"description":"New draft; appended=false and sendPlanned=false. invoice can be null if removed before read-back.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"anyOf":[{"$ref":"#/components/schemas/InvoiceDetail"},{"type":"null"}]},"appended":{"type":"boolean"},"sendPlanned":{"type":"boolean"}},"required":["invoice","appended","sendPlanned"]}}}},"400":{"description":"invalid_json or validation; issues groups messages by top-level field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"invalid_api_key: missing, malformed, unknown or revoked Bearer key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"invoice_cap: account invoice allowance reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"subscription_inactive, plan_not_allowed or insufficient_scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"client_not_found: unknown client or outside this administration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict: this key was used with different input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"no_company_profile: complete company settings in the app. line_limit: appending would exceed the document line limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/invoices/{id}":{"get":{"operationId":"getInvoice","summary":"Read an invoice with lines","description":"Returns the invoice and calculated totals. No PDF, UBL, public recipient token or download URL is returned.","x-required-scopes":["invoices:read"],"x-openai-isConsequential":false,"parameters":[{"name":"id","in":"path","required":true,"description":"ID returned by this API.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Invoice with lines.","content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"$ref":"#/components/schemas/InvoiceDetail"}},"required":["invoice"]}}}},"401":{"description":"invalid_api_key: missing, malformed, unknown or revoked Bearer key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"subscription_inactive, plan_not_allowed or insufficient_scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: unknown invoice or outside this administration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/invoices/{id}/send":{"post":{"operationId":"scheduleInvoiceSend","summary":"Schedule invoice delivery","description":"Schedules a real email to the recipient. Only call when the user requests delivery. mode=now schedules after the 20-second undo window; delivery runs asynchronously. mode=scheduled (also an empty request body) defaults to tomorrow in the account send window. date may be at most 180 days ahead. An existing schedule is preserved with alreadyPlanned=true. After dispatch a repeat may return not_a_draft. A successful response means scheduled, not delivered. The invoice is numbered during dispatch if it is not already finalized.","x-required-scopes":["invoices:send"],"x-openai-isConsequential":true,"parameters":[{"name":"id","in":"path","required":true,"description":"ID returned by this API.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceSend"},"example":{"mode":"scheduled"}}}},"responses":{"200":{"description":"Delivery scheduled or existing schedule preserved.","content":{"application/json":{"schema":{"type":"object","properties":{"scheduledSendAt":{"type":"string","format":"date-time"},"alreadyPlanned":{"type":"boolean"}},"required":["scheduledSendAt","alreadyPlanned"]}}}},"400":{"description":"invalid_json, validation or date_too_far.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"invalid_api_key: missing, malformed, unknown or revoked Bearer key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"subscription_inactive, plan_not_allowed or insufficient_scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"not_a_draft: invoice has already been sent or paid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"email_required: recipient has no email address. vat_number_required: reverse charge requires the recipient VAT identification number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"fm_live_…","description":"Create a key at https://factuurmaken.nl/app/settings/api. Required permissions are listed per operation in x-required-scopes. Keep the key in your integration secret store, not in prompts or URLs."}},"schemas":{"ClientCreate":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"type":{"default":"business","type":"string","enum":["business","individual"]},"name":{"type":"string","minLength":1},"number":{"type":"string","maxLength":40},"vatMode":{"default":"standard","type":"string","enum":["standard","reverse_charge","vat_exempt"]},"language":{"default":"nl","type":"string","enum":["nl","en"]},"currency":{"default":"EUR","type":"string","enum":["EUR","USD","GBP","CHF","SEK","NOK","DKK","PLN","CZK","CAD","AUD"]},"gAccountPct":{"type":"string"},"bankAccountId":{"description":"An existing bank account ID from this administration. Omit to use the default; this API does not list bank accounts.","type":"string"},"paymentProvider":{"description":"'multisafepay' or 'mollie': which connected payment provider collects this client's invoice payments. Omit or empty for the administration's default; a provider that is not connected falls back to the default at payment time.","anyOf":[{"type":"string","enum":["multisafepay","mollie"]},{"type":"string","const":""}]},"contactName":{"type":"string"},"email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"string","const":""}]},"address":{"type":"string"},"postalCode":{"type":"string"},"city":{"type":"string"},"country":{"description":"Country name. Omitted or empty defaults to Nederland.","type":"string"},"kvk":{"description":"Optional KVK number: eight digits, ignoring whitespace.","type":"string"},"vatNumber":{"description":"Optional VAT number. NL numbers must match NL + 9 digits + B + 2 digits (ignoring spaces/dots/case); foreign prefixes are accepted.","type":"string"}},"required":["name"]},"InvoiceCreate":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"clientId":{"type":"string","minLength":1,"description":"ID returned by the clients API. Do not invent IDs."},"lines":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1},"details":{"type":"string","maxLength":2000},"quantity":{"description":"Quantity; rounded server-side to 3 decimal places.","type":"number","minimum":0.001,"maximum":100000},"unit":{"type":"string","maxLength":30},"unitPriceCents":{"type":"integer","minimum":-100000000,"maximum":100000000,"description":"Unit price excluding VAT, in integer euro cents. 9500 means EUR 95.00."},"vatRate":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"enum":[21,9,0],"description":"VAT percentage; the client VAT mode determines whether VAT is charged."},"discountPct":{"type":"integer","minimum":0,"maximum":100},"periodStart":{"type":"string","minLength":1},"periodEnd":{"description":"ISO timestamp; exclusive end of the service period.","type":"string","minLength":1},"kind":{"default":"standard","type":"string","enum":["standard","additional_work","reduced_work"]},"category":{"type":"string","enum":["labour","materials","other"]}},"required":["description","quantity","unitPriceCents","vatRate"]}},"issueDate":{"description":"YYYY-MM-DD. Defaults to today in UTC. Ignored when appending.","type":"string"},"dueDate":{"description":"YYYY-MM-DD. Defaults to issueDate plus the account payment term. Ignored when appending.","type":"string"},"notes":{"description":"Invoice notes. Ignored when appending to an existing draft.","type":"string","maxLength":2000},"onOpenConcept":{"default":"create","description":"create always makes a new draft. append adds lines to an existing open draft (even one scheduled for delivery), or creates one if none exists. Neither mode deduplicates retries.","type":"string","enum":["create","append"]}},"required":["clientId","lines"]},"InvoiceSend":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"mode":{"default":"scheduled","type":"string","enum":["now","scheduled"]},"date":{"type":"string"}}},"Client":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["business","individual"]},"number":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]},"address":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"kvk":{"anyOf":[{"type":"string"},{"type":"null"}]},"vatNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"vatMode":{"type":"string","enum":["standard","reverse_charge","vat_exempt"]},"createdAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","type","number","name","contactName","email","address","postalCode","city","country","kvk","vatNumber","vatMode","createdAt"],"additionalProperties":false},"Invoice":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"number":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Null until the invoice is finalized in the app or during dispatch."},"status":{"type":"string","enum":["draft","final","sent","overdue","paid"],"description":"Derived display status. An unpaid draft with a past due date can be overdue."},"invoiceType":{"type":"string","enum":["invoice","credit"]},"clientId":{"anyOf":[{"type":"string"},{"type":"null"}]},"recipient":{"type":"object","properties":{"name":{"type":"string"},"email":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name","email"],"additionalProperties":false},"issueDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"paidAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"scheduledSendAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"currency":{"type":"string"},"vatMode":{"type":"string","enum":["standard","reverse_charge","vat_exempt"]},"notes":{"anyOf":[{"type":"string"},{"type":"null"}]},"subtotalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"vatCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"updatedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","number","status","invoiceType","clientId","recipient","issueDate","dueDate","paidAt","scheduledSendAt","currency","vatMode","notes","subtotalCents","vatCents","totalCents","createdAt","updatedAt"],"additionalProperties":false},"InvoiceDetail":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"number":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Null until the invoice is finalized in the app or during dispatch."},"status":{"type":"string","enum":["draft","final","sent","overdue","paid"],"description":"Derived display status. An unpaid draft with a past due date can be overdue."},"invoiceType":{"type":"string","enum":["invoice","credit"]},"clientId":{"anyOf":[{"type":"string"},{"type":"null"}]},"recipient":{"type":"object","properties":{"name":{"type":"string"},"email":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name","email"],"additionalProperties":false},"issueDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"paidAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"scheduledSendAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"currency":{"type":"string"},"vatMode":{"type":"string","enum":["standard","reverse_charge","vat_exempt"]},"notes":{"anyOf":[{"type":"string"},{"type":"null"}]},"subtotalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"vatCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"updatedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":{"type":"string"},"details":{"anyOf":[{"type":"string"},{"type":"null"}]},"quantity":{"type":"number"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}]},"unitPriceCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"May be negative on an existing credit invoice."},"vatRate":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"discountPct":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"periodStart":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"periodEnd":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","position","description","details","quantity","unit","unitPriceCents","vatRate","discountPct","periodStart","periodEnd"],"additionalProperties":false}}},"required":["id","number","status","invoiceType","clientId","recipient","issueDate","dueDate","paidAt","scheduledSendAt","currency","vatMode","notes","subtotalCents","vatCents","totalCents","createdAt","updatedAt","lines"],"additionalProperties":false},"Error":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"string"},"issues":{"description":"Validation messages grouped by top-level field, for example lines or clientId.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["error"],"additionalProperties":false}}}}