Get a transaction
The full lifecycle of one document — either direction, either pipeline.
/v1/api/transactions/{transaction_id}Same id, same row, whichever direction it went. An inbound document has a transaction_id too — it's
listed and read here exactly like something the taxpayer sent, just with direction: "inbound",
delivery: null, and no events (see below).
| Field | Type | Description | |
|---|---|---|---|
| taxpayer_id | uuid | optional | Query parameter. Narrows the lookup to one taxpayer; omit to search every taxpayer your organisation manages. Either way the id is scoped to your organisation before the row is read — one outside it 404s rather than being filtered after the fact |
document_id is the same value as transaction_id on every row, kept as a separate field because both
names are in use elsewhere. It does not point at a second resource — the document itself (the
transmitted XML, the Tax Data Document, or a rendered PDF) is fetched with this same id through
Download a document.
Response fields
| Field | Type | Description | |
|---|---|---|---|
| direction | enum | — | outbound — the taxpayer sent it. inbound — it arrived for them |
| source | enum | — | generated — built from JSON via Create invoice. raw — someone else's bytes: a raw send, or a document that arrived |
| status | enum | — | Outbound: queued · sent · delivered · failed · skipped. Inbound: always received. See Status values |
| delivery | object | null | — | Null on an inbound document — there is no transmission of ours to report, not a failure |
| delivery.response_code | string | — | AP accepted or RE rejected by the receiver |
| tax_report | object | null | — | Null only on a draft — nothing is reported for a document never issued. Present on both directions otherwise: we report as C2 for what a taxpayer sends and as C3 for what they receive |
| tax_report.tdd_uuid | uuid | — | Identifier of the Tax Data Document filed |
| tax_report.reason | string | — | Why the Authority refused it, when rejected |
| parse_error | string | null | — | Non-null when an inbound document arrived but couldn't be read. The row is kept regardless, so expect most other fields null alongside it |
| events | array | — | Append-only history, oldest first. Populated only here, and only for source: "generated" rows — the other two sources have no event log to draw from |
A failure is provisional
Delivery retries on a schedule, so delivery.status: "failed" with attempts remaining isn't final.
Wait for the transaction.failed webhook, or for attempts to stop rising, before treating a document
as undeliverable. A receiver actively refusing the document — a commercial decision, not a transport
one — lands at the same delivery.status: "failed"; it's told apart by the transaction.rejected
webhook firing instead of transaction.failed, not by a different status word.