Prepare a sales invoice, a customer credit note or a customer debit note
const url = 'https://example.com/v1/receivables/invoices';const options = { method: 'POST', headers: { 'Idempotency-Key': 'example', Authorization: 'Bearer <token>', 'Content-Type': 'application/json' }, body: '{"attachment_ids":["2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"],"currency":"example","custom_fields":{"additionalProperty":"example"},"customer_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","customer_reference":"example","fx_rate":"4.2000000000","kind":"sales_invoice","lines":[{"account_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","classification_code":"example","description":"example","discount_amount":"1234.5600","quantity":"4.2000000000","shares":[{"analytic_account_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","percentage":"4.2000000000"}],"tax_code_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","tax_exemption_reason":"example","trade_line_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","unit_code":"example","unit_price":"1234.5600"}],"original_invoice_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","payment_terms_days":1,"reason":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/v1/receivables/invoices \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: example' \ --data '{ "attachment_ids": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ], "currency": "example", "custom_fields": { "additionalProperty": "example" }, "customer_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "customer_reference": "example", "fx_rate": "4.2000000000", "kind": "sales_invoice", "lines": [ { "account_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "classification_code": "example", "description": "example", "discount_amount": "1234.5600", "quantity": "4.2000000000", "shares": [ { "analytic_account_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "percentage": "4.2000000000" } ], "tax_code_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "tax_exemption_reason": "example", "trade_line_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "unit_code": "example", "unit_price": "1234.5600" } ], "original_invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "payment_terms_days": 1, "reason": "example" }'Starts as an unnumbered draft (R2). Issuing it is a person’s decision and is not part of the public API. Idempotency-Key is required when sent with an API key. Requires receivables.invoice.create.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Names this attempt. Required for every write made with an API key: reuse it to retry (the first attempt’s answer is replayed, with Idempotent-Replayed: true, and nothing runs twice); change it for a different request. The same key over a different request is 409 idempotency_key_reused. Keys are kept for 24 hours and are scoped to the API key that sent them.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Documents the caller uploaded (POST /documents), attached with the record in one step: a refusal (409 document_bound_elsewhere, 422 document_not_yours or document_unknown) rolls the record back. Create only; add later with POST …/attachments. Attachments are never detached, and an update that sends this is refused.
User-defined field values by key, checked against the active definitions (422 custom_field_invalid, each value at /custom_fields/
object
Required when currency is not the base currency.
Read on create; ignored on update.
object
E-Invoice classification; 022 is Others
A decimal amount as a string. Never a JSON number.
Example
1234.5600A decimal rate or percentage as a string, up to 10 places. Never a JSON number.
Example
4.2000000000object
A decimal rate or percentage as a string, up to 10 places. Never a JSON number.
Example
4.2000000000A delivery line (an invoice) or sales return line (a credit note) of this customer; quantity is then in base units (O3.2).
A decimal amount as a string. Never a JSON number.
Example
1234.5600A credit note’s invoice.
Absent - the customer’s own terms.
A credit note’s reason.
Responses
Section titled “Responses”The document
object
Frozen when issued; null on a draft.
object
object
The organization’s user-defined field values by key (GET /org/custom-fields); {} when none.
object
A decimal rate or percentage as a string, up to 10 places. Never a JSON number.
A decimal amount as a string. Never a JSON number.
A decimal amount as a string. Never a JSON number.
True when the party is currently mapped to a company of the organization’s group, so a consolidation run eliminates the dealing. Derived from the party map at read time, never stored on the transaction.
Brought in by a data migration (import M5)
The previous system’s number
object
A decimal amount as a string. Never a JSON number.
A decimal amount as a string. Never a JSON number.
A decimal amount as a string. Never a JSON number.
A decimal rate or percentage as a string, up to 10 places. Never a JSON number.
object
A decimal rate or percentage as a string, up to 10 places. Never a JSON number.
A decimal amount as a string. Never a JSON number.
A decimal amount as a string. Never a JSON number.
The tax code as it read when the line was priced.
A decimal rate or percentage as a string, up to 10 places. Never a JSON number.
A delivery line (an invoice) or sales return line (a credit note) of this customer; quantity is then in base units (O3.2).
A decimal amount as a string. Never a JSON number.
True when the lines charge two or more distinct projects.
A decimal amount as a string. Never a JSON number.
An opening document’s original total, for reference; gross_amount is what was outstanding at the cut-over.
Gross less allocations (a credit note - what it has left).
The project every project-charged line shares; null when none or when several (see multiple_projects).
object
Null on a draft; numbered when issued (R2).
Frozen when issued; null on a draft.
object
A decimal amount as a string. Never a JSON number.
object
A decimal amount as a string. Never a JSON number.
A decimal amount as a string. Never a JSON number.
Documents attached to the record, oldest first; readers are whoever may read the record.
object
Locale to text. “en” is required; keys are supported UI locales.
object
object
Not_reporter, no_band_covers_amount, not_in_band, self_approval, dispute_raiser or already_signed (a sign-off step, when the actor has already signed everything they may).
Reason is one of member_inactive, position_retired, vacant, no_primary_position, no_unit_head, above_root, only_the_claimant, no_band_covers_amount, unallocated (part of the amount carries no account on the step’s axis) or no_account_approver (the account, and every ancestor, has no approver).
object
The shares this edge lets the actor sign, on a sign-off step.
object
A decimal amount as a string. Never a JSON number.
Allowed only as the sole-owner exception (Ruling O-3a): the organization’s one active member deciding their own sales document. requires_reason is then true, and the decision is recorded with authority_via sole_owner_exception. The reason is English or Bahasa Malaysia, at most 500 characters (422 field=reason otherwise); a blank one is refused with 422 sole_owner_reason_required.
Gross less allocations (a credit note - what it has left).
A decimal amount as a string. Never a JSON number.
object
Example
{ "fx_rate": "4.2000000000", "gross_amount": "1234.5600", "gross_base": "1234.5600", "kind": "sales_invoice", "lines": [ { "discount_amount": "1234.5600", "net_amount": "1234.5600", "net_base": "1234.5600", "quantity": "4.2000000000", "shares": [ { "percentage": "4.2000000000" } ], "tax_amount": "1234.5600", "tax_base": "1234.5600", "tax_rate": "4.2000000000", "unit_price": "1234.5600" } ], "net_total": "1234.5600", "original_total": "1234.5600", "outstanding": "1234.5600", "semantic": "draft", "tax_total": "1234.5600", "allocations": [ { "amount": "1234.5600", "base_amount": "1234.5600", "source_kind": "receipt" } ], "available_transitions": [ { "gate": "reporter", "signs": [ { "amount": "1234.5600" } ] } ], "outstanding_base": "1234.5600"}Headers
Section titled “Headers”The record’s revision, quoted.
The body is not a single JSON object of this endpoint’s shape: it is missing, malformed, carries a field of the wrong type, or carries a field this endpoint does not accept. Unknown fields are refused, not ignored; the detail names the offending field where there is one.
object
A stable refusal code the client branches on, where the status alone is not enough: owner_role_manage_required and self_lockout on the role editor’s 409s; revision_mismatch (a stale If-Match) and document_bound_elsewhere (the document backs another record) on an expense claim’s 409s.
Example generated
{ "code": "example", "detail": "example", "instance": "example", "status": 1, "title": "example", "type": "example"}Not authenticated, or the session is no longer valid.
object
A stable refusal code the client branches on, where the status alone is not enough: owner_role_manage_required and self_lockout on the role editor’s 409s; revision_mismatch (a stale If-Match) and document_bound_elsewhere (the document backs another record) on an expense claim’s 409s.
Example generated
{ "code": "example", "detail": "example", "instance": "example", "status": 1, "title": "example", "type": "example"}The caller does not hold the permission this operation requires.
object
A stable refusal code the client branches on, where the status alone is not enough: owner_role_manage_required and self_lockout on the role editor’s 409s; revision_mismatch (a stale If-Match) and document_bound_elsewhere (the document backs another record) on an expense claim’s 409s.
Example generated
{ "code": "example", "detail": "example", "instance": "example", "status": 1, "title": "example", "type": "example"}The Idempotency-Key was already used for a different request (idempotency_key_reused), or the same request is still being processed (idempotency_in_progress; retry after Retry-After), or the records are in another state (conflict).
object
A stable refusal code the client branches on, where the status alone is not enough: owner_role_manage_required and self_lockout on the role editor’s 409s; revision_mismatch (a stale If-Match) and document_bound_elsewhere (the document backs another record) on an expense claim’s 409s.
Example generated
{ "code": "example", "detail": "example", "instance": "example", "status": 1, "title": "example", "type": "example"}The request is well-formed but refused by an AR rule (validation), or the Idempotency-Key header is missing or too long (idempotency_key_required).
object
A stable refusal code the client branches on, where the status alone is not enough: owner_role_manage_required and self_lockout on the role editor’s 409s; revision_mismatch (a stale If-Match) and document_bound_elsewhere (the document backs another record) on an expense claim’s 409s.
Example generated
{ "code": "example", "detail": "example", "instance": "example", "status": 1, "title": "example", "type": "example"}A rate limit was reached: per API key, per organization across its keys, or per source address for repeated failed key authentication. Retry after the number of seconds in Retry-After. Every answer on a key carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset.
object
A stable refusal code the client branches on, where the status alone is not enough: owner_role_manage_required and self_lockout on the role editor’s 409s; revision_mismatch (a stale If-Match) and document_bound_elsewhere (the document backs another record) on an expense claim’s 409s.
Example generated
{ "code": "example", "detail": "example", "instance": "example", "status": 1, "title": "example", "type": "example"}Headers
Section titled “Headers”Seconds until a retry may succeed.