Deze referentie is alleen in het Engels. Naar het Nederlandse REST API-overzicht

Diese Referenz gibt es nur auf Englisch. Zur deutschen REST-API-Übersicht

Cette référence existe uniquement en anglais. Aller à la présentation de l'API REST en français

Esta referencia solo está en inglés. Ir a la introducción de la API REST en español

POST/sales-invoices

Create a sales invoice

POSThttps://<your-url>/api/v2/sales-invoices

MCP id sales-invoices.storeAlso on this path: GET List sales invoices

View as Markdown openapi.json

Creates an invoice header and returns it in the detail view with a Location header.

Access

Token scope
api:write:sales_invoices

Without it: 403 insufficient-token-scope.

Permission
sales_invoices::create

Without it: 403 insufficient-permission.

Feature
Needs the billing feature on your organisation.

Without it: 404 endpoint-not-found.

Rate cost
1 unit, write bucket. A write costs the same whatever view you ask for.
Also
Accepts Idempotency-Key. Never cached: private, no-store. Unknown body keys are refused, never dropped.

Both are checked, scope first. A token never does more than its user. How access is checked

It has no rows yet, so subtotal, vat_total and total are 0.00: post each row to sales-invoices/{sales_invoice}/rows afterwards and the totals follow. The invoice number is allocated by the server from the organisation's yearly sequence and cannot be supplied. The server sets the status too: a caller without sales_invoices::finalize creates a pending_approval invoice that a colleague holding that permission must approve in plnnrly; no API endpoint advances it. In an organisation with the accounting integration connected the invoice starts as a draft awaiting the sync, and the customer must be linked to that system or the sync will later fail; in one without it the invoice is local, immediately settled, and never emailed. Send Idempotency-Key to make a retry safe.

Query parameters

Unknown parameters are refused with 400, naming the parameter.

viewstring

Which field set to render.

summarydetaildefault

Request headers

X-Request-Idstringpattern

A correlation id of your own. It is recorded in our logs next to the server's request id but never returned: the response header always carries the server's id. A value that does not match the pattern is discarded silently, never rejected.

Idempotency-Keystring≤ 255

A caller-chosen key that makes this POST safe to retry. Replaying it returns the original response with Idempotency-Replayed: true.

Request body

Unknown keys are refused with 422, naming the key.

customer_idinteger → Customer.idRequired

Customer this invoice is billed to.

invoice_datedate (YYYY-MM-DD)Required

Invoice date, a zone-free calendar date. Newest first is the default sort.

project_idinteger or null → Project.id

Project this invoice was raised for, when it was raised from one.

customer_subscription_idinteger or null → CustomerSubscription.id

Customer subscription this invoice was generated from, when it was generated from a renewal.

due_datedate (YYYY-MM-DD) or null

Date payment is due, a zone-free calendar date. Null when no term was applied.

Must be on or after invoice_date.

referencestring or null≤ 255

The customer's own reference, typically a purchase-order number, reproduced on the invoice.

descriptionstring or null≤ 255

One-line description of what was invoiced.

internal_notesstring or null

Notes for colleagues. Never rendered on the invoice the customer receives.

should_emailboolean

Whether the invoice is emailed to the customer when it syncs. The email is sent through the accounting integration, so it is forced to false in an organisation with no integration configured. Writing it requires sales_invoices::finalize.

Response 201

Returns a SalesInvoice in the detail view.

Headers

ETag
A strong validator of exactly this representation.
Idempotency-Replayed
true when this response was replayed from a stored Idempotency-Key rather than produced by a new write.
Location
The absolute URL of the created or queued resource.
RateLimit
The IETF httpapi-ratelimit-headers form of your remaining allowance on the tightest bucket this request touched.
RateLimit-Policy
The ceiling and window of that bucket, as <limit>;w=<seconds>.
X-Request-Id
The server-generated ULID correlating this response with our logs.

Every response also carries Cache-Control, Vary, X-Content-Type-Options, X-Plnnrly-Api-Version, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. Headers and versioning

Errors

7 errors every operation can return: 400, 401, 404, 406, 429, 500, 503

This path allows GET, POST. Anything else answers 405.