Skip to main content

Get Journal Entry

GET 

/api/ledger/entries/:entry

Journal entry detail: everything from the index row plus the detail-only sections —

Authorization

Any valid API token can call this endpoint — no specific scope required. Manage tokens.

  • lines — the GL impact rows (direction, amount, quantity, tax_amount, nominal_code, tax_rate, source_line, role)

  • invoice_view — Xero-style invoice document view, present only for invoice-style entry types (sales_order_invoice, batch_sales_order_invoice, purchase_order_invoice, sales_credit, vendor_credit, bill) that resolve at least one product line; null for manual journals and quantity-free entries. One row per source line (item, description, quantity, unit_price, discount_amount, account, tax_rate, tax_amount, amount) with a subtotal / discount_total / tax_total / total / currency_code footer. Money + quantity fields are 4dp strings; total = subtotal + tax_total. Tax and quantity are read from the primary (revenue / COGS / expense) leg only, so they are never double-counted against the auto-booked control leg.

  • sync_links — provider links with connection identity, remote document type/ID, the provider deep link (remote_url, Xero go.xero.com / QBO web-app URL patterns), link_state (unlinked, linked_current, linked_stale, linked_conflict, remote_gone), remote_status and last_remote_seen_at

  • operations — the latest 20 sync operations (state, operation create|update|void|delete|link, direction push|pull, error_class, error_payload, attempts, connection) each with its append-only transitions audit trail

  • reversal_chain — summaries of the linked reversal_of / reversed_by / replaced_by / replaces entries

counterparty — the supplier (AP) or customer (AR) the source document is against, as a cross-linkable reference: { name, id, link_type_label, link_route }. Present on the detail path (and the Invoices / Purchase Orders list lenses) whenever the eager-loaded source resolves a party. Four shapes: (1) a linked CRM party — name + numeric id + link_type_label "Supplier"/"Customer" + link_route /crm/suppliers/{id} or /crm/customers/{id}; (2) a marketplace-customer fallback for AR sources (sales order / sales credit) with no CRM customer — name is "{Integration} Customer" (e.g. "Amazon Customer", "Shopify Customer"), link_type_label "Customer", with id and link_route null (no detail page to link to); (3) a marketplace fallback for a settlement source (Amazon financial-event group, whose sale + fee legs all net against the marketplace) — name is the bare integration name (e.g. "Amazon"), link_type_label "Marketplace", with id and link_route null; (4) a provider fallback for a ShipMyOrders provider invoice (a 3PL fulfilment-provider bill carrying no CRM party and no integration instance) — name is the fixed label "SMO", link_type_label "Provider", with id and link_route null; (5) the field is absent entirely only for sources that resolve none of the above (a manual journal with no source, a native SKU.io order missing its customer, a deleted source) — match it with if (entry.counterparty).

Sync axes are null for historical entries: the sync, progress and routing objects each report null key/label/color when an entry has left the live books — it is discarded (superseded by a regenerated replacement: replaced_by_id set + discarded_at) or a reversed original (status = reversed). Such rows can never sync (the batch rollup, reports and live lists all exclude them), so a frozen enabled/synced axis would mislead; the supersession marker carries the why instead. A live reversal contra entry (reversal_of_id set, still posted) is NOT historical and keeps its axes.

Authentication: Requires Bearer token.

Returns 404 when the entry does not exist (route is numeric-constrained).

Each line also carries role — its economic role within a document-style entry (primary product leg, control A/R or A/P leg, tax leg, or discount leg), recovered from the mapped nominal code. The GL Impact table shows the invoiced quantity (and copied line description) on primary legs only: v2 copies the quantity onto the control leg too, so a role-blind column would repeat it on Accounts Payable / Receivable and read as a double-count. role is null on paths that don't load lines.

Each line also carries pushed_to_provider: false marks the control line (A/R on an Invoice/Credit Note, A/P on a Bill) that the connected provider auto-books itself — SKU omits it from the push, so the GL Impact table dims it. true = the line is pushed. null when no accounting provider is connected. The entry's sync_provider ('Xero' / 'QuickBooks', or null) names that provider for the hint.

can_sync_now (boolean) — whether a manual "Sync Now" can push this entry right now. The per-transaction-type Sync toggle, granularity opt-out and the per-type start date only gate automatic/scheduled sync; a manual push bypasses them, so can_sync_now stays true for a benign "Auto-off" entry. It is false only when a structural blocker applies (connection inactive, entry is a batch member / open batch, internal-only, or before the accounting provider's conversion/start date) — those block even a manual push. Drives the UI split between a grey "Auto-off · push anytime" chip (display_status=excluded + can_sync_now=true) and an amber "Blocked" chip (display_status=excluded + can_sync_now=false).

provider_payment — for invoice-style entries (sales/purchase invoices, bills) linked to an accounting provider, the paid status + payment metadata: normalized payment_state (paid / partially_paid / unpaid / voided), the provider invoice lifecycle provider_status (Xero DRAFT/AUTHORISED/PAID/VOIDED), amounts (total/paid/due/credited), the payments applied, and provider-dependent metadata. Xero is fully populated; QBO is header-only and flagged data_availability: limited. null for non-invoice or unlinked entries.

chain — the full reverse+replace lineage for the source document (every version, its reversal contras and the current head), oldest→newest, for a chain-of-events view. Each step: { id, document_number, reference, reference_suffix, status (draft|posted|reversed), role (original|reversal|replacement), is_current, is_viewed, reversal_of_id, replaced_by_id, effective_at, provider_link ({ remote_type, remote_id, remote_url, link_state, remote_status, badge } or null) }. [] when the entry has never been reversed or replaced.

Also returns sync_override_provenance (who/what/when set the sync override: source = user | legacy_cutover | system, set_at, set_by; null when no override) and is_settlement_sourced (boolean — a marketplace settlement posting, exempt from per-channel sync toggles).

provider_payment.unreflected_credit_notes — credit notes the accounting provider has applied to this bill that are not yet reflected in SKU as vendor-credit allocations. Empty when everything reconciles. Each item carries credit_note_id, credit_note_number, applied_amount (applied at the provider), reflected_amount (covered by SKU allocations) and shortfall (the remaining unreflected amount).

Request

Responses

OK

Response Headers
    Content-Type