What Do Invoice Status Values Mean in the Unified API?

Edited

1. Overview

The unified Accounting API uses a standardized set of status values for invoices. These statuses represent the lifecycle of an invoice from creation through to settlement, providing a consistent model across all supported accounting connectors.

Because each connector uses its own native status terminology, Apideck normalizes these into a single set of unified values so you can write consistent logic regardless of which accounting platform your users connect.


2. Status Values

The unified model supports the following 10 status values:

  • draft - The invoice has been created but is not yet finalized. It can still be edited and has not been sent, approved, or recorded in the ledger.

  • submitted - The invoice has been sent or submitted for review, approval, or processing. It is no longer a draft but has not yet been formally approved.

  • authorised - The invoice has been approved at a business level — it is cleared to proceed. However, it has not yet been recorded in the accounting ledger. Think of this as a business approval gate, not an accounting event.

  • partially_paid - Some payment has been received or allocated, but a balance still remains outstanding.

  • paid - The invoice has been fully settled. No remaining balance.

  • void - The invoice has been cancelled or invalidated. It is retained in the system for audit trail purposes but has no financial effect.

  • deleted - The invoice has been removed or soft-deleted. Exact behavior may vary by connector.


3. Lifecycle Flow

The typical happy-path progression of an invoice is:

draftsubmittedauthorisedpartially_paidpaid

Not every invoice passes through every status. Depending on the connector and business workflow:

  • An invoice may go directly from draft to authorised, skipping submitted

  • An invoice may be void or deleted from any stage

  • Some connectors don't distinguish between all statuses - see Connector Coverage below


4. Connector Coverage

Not all connectors support every status value. The table below shows how each connector's native statuses map to the unified model. A dash (—) means the connector does not have a native equivalent for that status.

Unified Status

Xero

NetSuite

Sage Intacct

FreshBooks

MYOB Acumatica

Exact Online

QuickBooks

draft

DRAFT

Open

Draft

draft

Unapplied

Draft

submitted

SUBMITTED

(fallback)

(fallback)

Pending Processing, etc.

Sent

authorised

AUTHORISED *

Partially Approved

Open, Scheduled, etc.

partially_paid

AUTHORISED *

Open-partially Paid

Partially Paid

partial, deposit-partial

paid

PAID

Paid In Full

Paid

paid

Balanced, Closed

Paid

void

VOIDED

Declined, Reversed

Voided, Rejected

deleted

DELETED

vis_state=1

* Xero note: Xero maps both authorised and partially_paid to the same native status (AUTHORISED). This means these two states cannot be distinguished on the Xero side alone.

Notable behaviors:

  • QuickBooks does not expose a status field on invoices at all, so none of the unified statuses are applicable.

  • NetSuite uses different status codes depending on the query method (SuiteQL vs Saved Search), which can result in different values being returned for the same invoice.


5. Things to Keep in Mind

  1. Not all transitions are available on all connectors. If a connector doesn't support a status, attempting to set it may be ignored or return an error.

  2. Some connectors collapse multiple unified statuses into one native status. This means round-tripping (read → write → read) may not preserve the exact status. Xero's handling of authorised and partially_paid is a good example of this.

  3. Status semantics can vary subtly between connectors. For example, Open in NetSuite maps to draft, while Open in MYOB Acumatica maps to authorised. The unified model normalizes these differences so you don't need to handle them yourself.

Was this article helpful?

Sorry about that! Care to tell us more?

Thanks for the feedback!

There was an issue submitting your feedback
Please check your connection and try again.