Issue an invoice now
The accounting platform books and sends the invoice inside the request, and the answer is the issued invoice. It is the explicit "bill this one now": an invoice set not to send is issued all the same, and one with no date, or a date ahead, is dated today. **Sending it again is safe**: an invoice that is issued already is answered as it stands, 200, and nothing is booked twice. **A document that booked and could not be delivered is a 200** whose send_error says why: the invoice is in the books, so do not issue it again. Only a refusal to book is an error: ISSUE_REFUSED (422) carries the platform’s reason under refusal; HOURLY_INCOMPLETE and NOTHING_TO_BILL (409) say an hourly line is not ready; CUSTOMER_GONE and PRODUCT_GONE (409) that the platform no longer holds what the invoice names; ISSUE_IN_PROGRESS (409, with Retry-After) that another attempt holds the invoice. Metered against the platform_write bucket as well as default.
Authorization
bearerAuth An API key minted by an admin under Settings → Developers. It is bound to one company and has a scope: read, or read_write. A request without one, or with one that is not ours, is answered 401 and metered by its client address (x-rate-limits).
In: header
Path Parameters
The record's id, or ext:<external_id> for the record that carries your own key.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/invoices/string/issue"{ "object": "invoice", "id": "string", "external_id": "string", "customer_id": "string", "customer_name": "string", "currency": "string", "issue_date": "string", "title": "string", "auto_send": true, "layout_ref": "string", "status": "draft", "issued_at": "string", "platform_ref": "string", "platform_number": -9007199254740991, "send_error": { "reason": "string", "platform_reason": "string" }, "series_id": "string", "period_from": "string", "period_to": "string", "created_at": "string", "updated_at": "string", "lines": [ { "id": "string", "product_id": "string", "product_number": "string", "product_name": "string", "recognition_method": "value", "agreed_value": 0, "hourly_rate": 0, "discount": 0, "description_override": "string", "position": -9007199254740991, "assignees": [ { "user_id": "string", "distribution_percentage": 0, "hourly_rate_override": 0, "removed": true } ], "series_line_id": "string" } ]}Create a draft invoice POST
A draft is Tabba’s own record: nothing is asked of the accounting platform until the invoice is issued. With an `external_id` no invoice carries, a draft is created and the answer is 201. With one a draft carries, that draft is replaced and the answer is 200: a line that states its `id` stays the line it was, with the work registered on it; a line that states none is new; a line the body leaves out is removed. Two creates under one `external_id` at the same moment make one invoice: the second is answered that invoice, or 409 `CREATE_IN_PROGRESS` with `Retry-After` while the first is still writing it. An `external_id` an ISSUED invoice carries is refused with `INVOICE_ALREADY_ISSUED` (409): an issued invoice is frozen, and a credit note is the way to change it.
Replace a draft invoice PUT
The body is the whole draft. A line that states its `id` stays the line it was, with the work registered on it; a line that states none is new; a line of the invoice the body leaves out is removed. `external_id` left out stays as it is, and `null` clears it; `auto_send` left out stays as it is. Refused with `INVOICE_ALREADY_ISSUED` (409) once the invoice is issued, with `ISSUE_IN_PROGRESS` (409) while an issue attempt holds it, and with `INVOICE_IS_OCCURRENCE` (409) for an occurrence of a recurring series, which is changed through its series.