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.

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://api.taxstar.app/einv/oauth/invoices/{invoice_id}/status

{
  "invoice_id": "68f0aabbccddeeff00112233",
  "invoice_number": "INV-1042",
  "direction": "sent",
  "status": "VALIDATION_FAILED",
  "message": "Validation failed: 2 rules failed",
  "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": "..." }]
}

44 codes · catalogue v1.0.0

Queued

PROCESSING
in progress
The invoice was accepted and queued for processing. This is the status returned by POST /oauth/invoices and by a PATCH that re-queues an invoice.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. Run POST /oauth/invoices/validate first to see the same errors without creating an invoice.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_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_ERP_CONNECTION
blocked
The invoice was received for one of your entities, but that entity has no connected ERP to route it into. It is held and delivered once an ERP is connected.received
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_APPROVAL
blocked
The invoice is waiting for a human approval decision before it is pushed into the ERP.received
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
A received invoice was approved and continues into the ERP.received
REJECTED
failedterminal
A received invoice was rejected by the recipient.received

Delivery into your ERP

SENT_TO_XERO_IN_PROGRESS
in progress
The received invoice is being pushed into Xero.received
SENT_TO_XERO
successterminal
The received invoice was delivered into Xero.received
SENT_TO_XERO_FAILED
failedterminal
The received invoice could not be delivered into Xero; the row's message carries the ERP's error.received
SENT_TO_QUICKBOOKS_IN_PROGRESS
in progress
The received invoice is being pushed into QuickBooks.received
SENT_TO_QUICKBOOKS
successterminal
The received invoice was delivered into QuickBooks.received
SENT_TO_QUICKBOOKS_FAILED
failedterminal
The received invoice could not be delivered into QuickBooks; the row's message carries the ERP's error.received
SENT_TO_ZOHO_IN_PROGRESS
in progress
The received invoice is being pushed into Zoho.received
SENT_TO_ZOHO
successterminal
The received invoice was delivered into Zoho.received
SENT_TO_ZOHO_FAILED
failedterminal
The received invoice could not be delivered into Zoho; the row's message carries the ERP's error.received
SENT_TO_NAQOOD_IN_PROGRESS
in progress
The received invoice is being pushed into Naqood.received
SENT_TO_NAQOOD
successterminal
The received invoice was delivered into Naqood.received
SENT_TO_NAQOOD_FAILED
failedterminal
The received invoice could not be delivered into Naqood; the row's message carries the ERP's error.received
SENT_TO_ODOO_IN_PROGRESS
in progress
The received invoice is being pushed into Odoo.received
SENT_TO_ODOO
successterminal
The received invoice was delivered into Odoo.received
SENT_TO_ODOO_FAILED
failedterminal
The received invoice could not be delivered into Odoo; the row's message carries the ERP's error.received
SENT_TO_WAFEQ_IN_PROGRESS
in progress
The received invoice is being pushed into Wafeq.received
SENT_TO_WAFEQ
successterminal
The received invoice was delivered into Wafeq.received
SENT_TO_WAFEQ_FAILED
failedterminal
The received invoice could not be delivered into 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.

Path parameters

invoice_idBillberry invoice id (the `id` field from the received-invoices list).
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.