Skip to content

Company statements

A statement lists a company's orders and invoices for a period: what was ordered, what was paid and what is still due. Orbit builds it afresh for each request, with the store's invoice branding, then hands you a PDF to send to the company or a CSV for a spreadsheet, so it shows the records as they stand when you ask. The public API keeps nothing; the download link the dashboard and the account area use serves the copy made when the link was created.

This page covers the public API route an integration calls, the period rules it enforces, and the single-use link the dashboard and the account area use when a person asks for a statement.

Requesting a statement

GET /v1/companies/{id}/statement (company:read)

ParameterMeaning
fromThe first day the statement covers, YYYY-MM-DD. Defaults to the first day of the current month.
toThe last day the statement covers, YYYY-MM-DD, included. Defaults to today.
formatpdf or csv. Defaults to pdf.

A parameter sent blank (?from=&to=) counts as left out, so it takes its default.

HTTP
GET /v1/companies/6f2a1c3e-9d4b-4a7f-8e2c-1b3f5a7c9d0e/statement?from=2026-09-01&to=2026-09-30&format=pdf HTTP/1.1
Host: api.myorbitcommerce.net
Authorization: Bearer oc_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The answer is the file itself, streamed as an attachment, not a JSON envelope: a PDF (application/pdf) or a CSV (text/csv; charset=utf-8), with Content-Disposition: attachment and a filename built from the company name and the period, such as statement-beacon-hardware-ltd-2026-09-01-to-2026-09-30.pdf. The response carries Cache-Control: no-store.

The request is refused with a JSON answer instead of a file. These refusals carry an errorCode, a malformed date and an unknown format included:

Status and errorCodeWhen
400 B2B_STATEMENT_PERIOD_INVALIDA date is not a real calendar day written YYYY-MM-DD, or from is after to.
400 B2B_STATEMENT_PERIOD_TOO_LONGThe period is longer than 13 months.
400 B2B_STATEMENT_FORMAT_INVALIDformat is neither pdf nor csv.
404The company is not one of this store's companies.
413 B2B_STATEMENT_TOO_LARGEThe period holds more than 2,000 orders.

A company id that is not a UUID, a query parameter other than from, to and format, or one of them sent twice, answers a plain validation 400 without an errorCode.

The 413 cap is the one to plan for: a statement is a document, not a data dump, so a period with more than 2,000 orders is refused with the message "This period has more than 2,000 orders. Choose a shorter range." Split a long history into shorter periods, or sync the underlying records instead (see Statements or syncing).

The period a statement covers

Both bounds are calendar days in UTC, written YYYY-MM-DD. from must not be after to, and the period may span at most 13 months; the day after to is the exclusive end of the range, so an order placed late on to is included. With no parameters, the statement covers the current month to date.

What a statement lists

There is one line per order placed under the company in the period, leaving out drafts, orders awaiting approval, cancelled orders, fully refunded orders (an order whose status or paymentStatus is refunded) and card orders not yet paid (paymentStatus pending, failed, expired or canceled, with nothing paid and nothing due). Orders awaiting a manual payment, owed on account or on terms, part-paid or with a payment in flight are listed, and a part-refunded order is listed at its original total. Each line carries the order number, the order date, the buyer, the PO number, the branch, the cost centres charged on the order, the invoice number and its due date, and the money: goods (the total less VAT), VAT, total, paid and due. For an order billed from a B2B invoice, paid and due come from the latest live invoice; otherwise they come from the order's own record.

The lines are grouped into one section per currency, and each section closes with a total row for the period. An order on account shows its invoice and due date, so the company can see what it still owes.

The CSV statement

The CSV has one header row, one row per order and a total row per currency section. Its columns are:

ColumnHolds
Order NumberThe order's number.
Order DateYYYY-MM-DD.
BuyerThe customer's name, or their email when no name is recorded.
PO NumberThe buyer's purchase order number, when the order carries one.
BranchThe company location the order is for, when it names one.
Cost CentresThe order's cost centre codes, joined with , .
Invoice NumberThe B2B invoice that bills the order, when it has one.
Due DateThe invoice's due date, YYYY-MM-DD, when it has one.
CurrencyThe order's currency code.
GoodsThe total less VAT, as a decimal string.
VATThe VAT amount, as a decimal string.
TotalThe order total, as a decimal string.
PaidWhat has been paid.
DueWhat is still owed.

The file starts with a byte order mark so a spreadsheet opens it in the right encoding, and each currency section ends with a Total row whose first cell reads Total.

The PDF statement

The PDF is a landscape A4 document with the store's masthead (logo or name, and its VAT number when set), the company block (its name, your account reference and its tax id), the statement date and the period. Each currency gets its own table under a heading, and a bold total row closes it. The footer notes the date the amounts were recorded and reads: "Draft, cancelled and fully refunded orders, orders awaiting approval and card orders not yet paid are not included. Part-refunded orders show their original total."

The dashboard's company page and the storefront account area do not stream the file to a person; they mint a single-use link instead. The link object carries:

FieldMeaning
urlThe link to follow to download the file.
filenameThe name the browser saves it under.
formatpdf or csv.
expiresAtWhen the link stops working, ten minutes after it was created.

The link works exactly once. Following it redirects the browser to the file; following it again, or after expiresAt, answers 404 with errorCode: "B2B_STATEMENT_LINK_EXPIRED" and the message "This statement link has expired or has already been used. Create the statement again." The public API streams the file directly, so an integration does not need this flow.

Statements or syncing

A statement is a document for people. To keep a ledger in your own system, sync the records and build the view yourself: GET /v1/orders?companyId=&includeArchived=true lists the company's orders with their PO numbers, branches, cost centres and amounts due (without includeArchived=true it leaves archived orders out), and GET /v1/b2b-invoices (filter with companyId) lists its invoices with their status and due dates. See Orders, approvals and pay on account for the order fields and the B2B invoices scopes for the invoice routes.

Next steps