API reference

Invoice status

Every status code an invoice can carry, and the endpoints for reading one invoice's current state. The full list is published below and served by an unauthenticated endpoint, so a code you have not seen before never has to reach your users as an unrecognised state.

An invoice carries a status trail — an append-only array of { code, message, created_at } rows. Rows are never replaced, so the last row is the invoice's current state. Every code below can appear in that array; nothing outside this list is emitted.

Rather than matching on codes directly, switch on category and stop polling when terminal is true — the status endpoint returns both, so a new code added to a phase you already handle needs no change on your side. A code your integration does not recognise comes back as category: "unknown", never as a missing field.

What changed in catalogue 1.1.0

  • RECEIVED_SUCCESSFULLY is new. Every received invoice that passes validation for your entity gets it: the invoice is stored, ready to read and download. With an accounting system connected, SENT_TO_<ERP> follows once the invoice is synced there.
  • WAITING_FOR_ERP_CONNECTION is no longer written. It is deprecated in favour of RECEIVED_SUCCESSFULLY and re-categorised from blocked to success. Invoices received before the change still carry it, so keep recognising it and treat the two the same.
  • SENT_TO_<ERP> codes are unchanged; they are now described as the invoice being successfully synced to that system.

If your integration checks for WAITING_FOR_ERP_CONNECTION by code, add RECEIVED_SUCCESSFULLY beside it, or switch on category instead.

in progress

Work is still in flight. Keep polling; a further status row is expected.

success

The step completed successfully.

failed

The step failed. See the row's message (and errors, when present).

blocked

Nothing is wrong with the document - it is parked waiting on configuration or a human decision, and will move on once that is resolved.

Poll one invoice

bash
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
  https://dev-api.taxstar.app/einv/oauth/invoices/{invoice_id}/status

{
  "invoice_id": "68f0aabbccddeeff00112233",
  "invoice_number": "INV-1042",
  "direction": "sent",
  "status": "VALIDATION_FAILED",
  "message": "Validation failed: the invoice did not pass the re-check made just before sending, so it was not sent. ...",
  "created_at": "2026-09-11T08:14:02.911+00:00",
  "category": "failed",
  "phase": "validation",
  "terminal": true,
  "description": "The invoice failed validation and was not sent. ...",
  "final_status": "failed",
  "status_count": 3,
  "errors": [{ "rule": "ibr-173-ae", "message": "..." }]
}

49 codes · catalogue v1.1.0

Queued

PROCESSING
in progress
The invoice passed validation and was queued for processing. This is the status returned by POST /oauth/invoices and by a PATCH that re-queues an invoice; one that fails validation is answered 422 instead and never gets a status.sent · received
WEBHOOK_RECEIVED
in progress
The processing pipeline picked the queued invoice up and started work on it.sent · received

Validation

VALIDATION_IN_PROGRESS
in progress
The invoice is being checked against the PINT AE rules.sent · received
VALIDATION_SUCCEEDED
success
The invoice passed validation and moves on to XML conversion.sent · received
VALIDATION_FAILED
failedterminal
The invoice failed validation and was not sent. The status row carries an 'errors' array with the failing rules. Fix the data and PATCH the invoice to re-queue it. A sent invoice is validated twice: when it is submitted (a failure there is a 422 on the request and no invoice is created) and again just before sending. This status comes from that second check, so it usually means something changed after the invoice was accepted, typically the entity's details or the exchange rate.sent · received

XML conversion

XML_CONVERTED
success
The invoice was converted to UBL XML, ready for dispatch.sent
XML_CONVERTED_FAILED
failedterminal
UBL XML could not be produced from the invoice data. Fix the data and PATCH the invoice to re-queue it.sent
XML_VALIDATED
success
The generated UBL XML passed schema validation.sent
XML_VALIDATED_FAILED
failedterminal
The generated UBL XML failed schema validation.sent

Dispatch to Peppol

SENT_TO_PEPPOL
successterminal
The invoice was accepted by the Peppol access point for delivery. This is the terminal success state of the send flow: the invoice becomes immutable and a PATCH returns 409.sent · received
SENT_TO_PEPPOL_FAILED
failedterminal
The access point rejected the invoice at dispatch. The invoice is still editable - PATCH it to re-queue.sent · received
SENT_TO_BILLBERRY
successterminallegacy
Legacy spelling of SENT_TO_PEPPOL, written before the gateway was renamed. Treat it exactly as SENT_TO_PEPPOL. Treat as SENT_TO_PEPPOL.sent · received
SENT_TO_BILLBERRY_FAILED
failedterminallegacy
Legacy spelling of SENT_TO_PEPPOL_FAILED. Treat it exactly as SENT_TO_PEPPOL_FAILED. Treat as SENT_TO_PEPPOL_FAILED.sent · received

Peppol delivery

DELIVERED_BY_PEPPOL
successterminalreserved
The receiving access point acknowledged the document. Reported asynchronously after SENT_TO_PEPPOL. Published ahead of its producer - recognise it now, do not expect it yet.sent
PEPPOL_DELIVERY_FAILED
failedterminalreserved
The receiving access point rejected the document after it had been accepted for delivery. Published ahead of its producer - recognise it now, do not expect it yet.sent

Arrival

RECEIVED_BY_PEPPOL
in progress
An invoice addressed to one of your entities arrived over the Peppol network and was stored. This is the first row on every received invoice.received
RECEIVED_SUCCESSFULLY
success
The invoice was received successfully: it passed validation for one of your entities and is stored, ready to read and download. If the entity has an ERP connected, the invoice is then synced into it (SENT_TO_<ERP>).received
WAITING_FOR_ERP_CONNECTION
successlegacy
Legacy code for RECEIVED_SUCCESSFULLY, on invoices received for an entity without an ERP before RECEIVED_SUCCESSFULLY was introduced. Treat it exactly as RECEIVED_SUCCESSFULLY. Treat as RECEIVED_SUCCESSFULLY.received
RECEIVED_BY_BILLBERRY
in progresslegacy
Legacy spelling of RECEIVED_BY_PEPPOL. Treat it exactly as RECEIVED_BY_PEPPOL. Treat as RECEIVED_BY_PEPPOL.received

Routing

WAITING_FOR_TAX_CONFIGURATION
blocked
The invoice is compliant, but its VAT treatment has no matching tax code in the receiving entity's ERP profile. Held until the tax code is configured - the document itself needs no change.received
WAITING_FOR_MAPPING
blocked
The invoice is compliant, but one or more lines could not be matched to exactly one tax code, or to one product, in the receiving entity's ERP. It is held, not posted, and the status message names each line's reason. Most are resolved by choosing (or creating) the tax code or product; a treatment the ERP cannot represent cannot be resolved by mapping.received
MAPPING_ANSWERED
in progress
A document held for mapping was answered, or its ERP's codes and products were asked to be read again. It is queued and re-processed within a minute: it posts, or is held again with the reason.received
WAITING_FOR_ERP_RATE_LIMIT
in progress
The receiving entity's ERP refused a call for its rate limit. Nothing failed: the invoice is retried automatically once the ERP's wait has passed.received
WAITING_FOR_APPROVAL
blocked
The invoice is waiting for a human approval decision. A sent invoice is held before it goes to Peppol when the entity requires approval for sending and the invoice was pushed with bypass_send_approval false; its approvers are emailed, and approving it sends it.sent · received
EXCLUDED_FROM_EINVOICING
blockedterminal
The invoice is outside UAE e-invoicing — sent through the API with einv_scope "excluded", or a sale to a private individual, Article 42 financial services or a Tax Group sale found by the platform. It was not validated, sent to Peppol or reported to the FTA. A person can reopen it from the dashboard; it is then validated and sent like any other invoice.sent
INVOICE_OPERATION_DISABLED
blockedterminal
Invoice operations are switched off for the entity, so the invoice was deliberately not processed. Neither a success nor a failure.sent · received
DATA_MISSING
failedterminal
The received document is missing data required to route it into an ERP.received
DRAFT_BLOCKED
failedterminal
The invoice was left as a draft and not processed further.received
APPROVED
success
The invoice was approved. A sent invoice is re-queued and goes to Peppol; a received one continues into the ERP.sent · received
REJECTED
failedterminal
The invoice was rejected by an approver and was not sent. Fix it and PATCH the invoice with bypass_send_approval false to submit it for approval again; a PATCH without it sends the invoice.sent · received

Delivery into your ERP

SENT_TO_XERO_IN_PROGRESS
in progress
The received invoice is being synced to Xero.received
SENT_TO_XERO
successterminal
The received invoice was successfully synced to Xero: it is now a bill there.received
SENT_TO_XERO_FAILED
failedterminal
The received invoice could not be synced to Xero; the row's message carries the ERP's error.received
SENT_TO_QUICKBOOKS_IN_PROGRESS
in progress
The received invoice is being synced to QuickBooks.received
SENT_TO_QUICKBOOKS
successterminal
The received invoice was successfully synced to QuickBooks: it is now a bill there.received
SENT_TO_QUICKBOOKS_FAILED
failedterminal
The received invoice could not be synced to QuickBooks; the row's message carries the ERP's error.received
SENT_TO_ZOHO_IN_PROGRESS
in progress
The received invoice is being synced to Zoho.received
SENT_TO_ZOHO
successterminal
The received invoice was successfully synced to Zoho: it is now a bill there.received
SENT_TO_ZOHO_FAILED
failedterminal
The received invoice could not be synced to Zoho; the row's message carries the ERP's error.received
SENT_TO_NAQOOD_IN_PROGRESS
in progress
The received invoice is being synced to Naqood.received
SENT_TO_NAQOOD
successterminal
The received invoice was successfully synced to Naqood: it is now a bill there.received
SENT_TO_NAQOOD_FAILED
failedterminal
The received invoice could not be synced to Naqood; the row's message carries the ERP's error.received
SENT_TO_ODOO_IN_PROGRESS
in progress
The received invoice is being synced to Odoo.received
SENT_TO_ODOO
successterminal
The received invoice was successfully synced to Odoo: it is now a bill there.received
SENT_TO_ODOO_FAILED
failedterminal
The received invoice could not be synced to Odoo; the row's message carries the ERP's error.received
SENT_TO_WAFEQ_IN_PROGRESS
in progress
The received invoice is being synced to Wafeq.received
SENT_TO_WAFEQ
successterminal
The received invoice was successfully synced to Wafeq: it is now a bill there.received
SENT_TO_WAFEQ_FAILED
failedterminal
The received invoice could not be synced to Wafeq; the row's message carries the ERP's error.received

Any phase

ERROR
failedterminal
An unexpected error stopped processing. The row's message carries the detail; the invoice can be PATCHed to retry.sent · received
GET/oauth/invoices/{invoice_id}/statusAccess token

Get current status (sent)

Return ONLY the current status of a sent invoice — the last row of its status trail, plus how that code should be treated. `status` is the raw code; `category` collapses it into in_progress / success / failed / blocked so you do not have to hard-code which codes mean what; `terminal` tells you when to stop polling. A VALIDATION_FAILED response also carries the failing rules in `errors`.

Use this, not the full invoice endpoint, to follow an invoice. It projects away the invoice data and the status history, so it stays cheap to poll. Stop when the response has terminal: true.

Path parameters

invoice_idInvoice id returned by POST /oauth/invoices (also accepted at /oauth/invoices/sent/{invoice_id}/status).
GET/oauth/invoices/received/{invoice_id}/statusAccess token

Get current status (received)

Return ONLY the current status of a received invoice, in the same shape as the sent-invoice status endpoint, plus sender_registry_code and receiver_registry_code. RECEIVED_SUCCESSFULLY means the invoice was received successfully: it is complete and readable, and nothing is wrong. For an entity with no connected accounting system it is where the invoice stays; with one connected, SENT_TO_<ERP> follows once the invoice is synced to it. Invoices received before RECEIVED_SUCCESSFULLY was introduced carry the legacy WAITING_FOR_ERP_CONNECTION instead; treat it the same. An example is under Received invoices on the Invoices page.

Path parameters

invoice_idThe numeric `id` from the received-invoices list, e.g. 15231.
GET/oauth/invoices/status-codesPublic

List all status codes

The complete published catalogue of invoice status codes, machine-readable. Each entry carries `code`, `phase`, `category`, `terminal`, `applies_to` and a description; `deprecated` entries are legacy wire values still present on historical documents (with `superseded_by` naming the current code), and `reserved` entries are published ahead of their producer. No authentication required — cache the response and compare `version` to detect a change.

Query parameters

directionRestrict to codes that appear on `sent` or on `received` invoices. Defaults to all.