Skip to main content
Ledger lists page with cursors and return a flat envelope, and most of them can inline related objects instead of making you fetch them. Most, not all: the exceptions are named below, and they are the ones that will quietly truncate on you.

List envelope

Every list endpoint returns a flat envelope. The data array holds the page; has_more and next_cursor drive pagination.

Cursor pagination

Request a page, and if has_more is true, pass the next_cursor value back as the cursor parameter to get the next page.
The limit parameter defaults to 50, with a minimum of 1 and a maximum of 200, on transactions, accounts and events. Two posting lists differ: GET /v1/postings and GET /v1/accounts/{id}/postings default to 100 and allow up to 500, and their cursor is a posting id rather than an opaque token. Read next_cursor and pass it back either way, and do not assume one limit across the API.
Treat every cursor as opaque even where it currently looks like an id. Do not decode or construct one; the encoding is an implementation detail that may change between releases. A cursor is a position, not a row, so one pointing at a since-deleted resource still paginates correctly. Pass it back verbatim until the list reports has_more: false.
A typical loop:

Lists that do not paginate

GET /v1/reconciliation_runs, GET /v1/webhook_endpoints and GET /v1/period_closes always answer has_more: false and next_cursor: null, whatever limit you pass. Reconciliation runs cap at 200 and default to 50. That matters because the flag lies rather than erroring: a workspace with 300 runs sees 50 and a has_more of false. Narrow with filters rather than paging, and do not build a “fetch everything” loop on these three.

Filtering lists

List endpoints accept filters in the query string. The available filters depend on the resource. For example, list transactions by metadata:
Accounts can be filtered by type, currency, and other fields; events by type and time window. See each endpoint in the API reference for its filter set. By default, a transaction’s postings reference their account by id. Use ?expand= to inline related objects in a single response instead of making follow-up calls. Two expansions are available: expand is a comma-separated list:
Expansion works on both single-resource reads and list endpoints, and is also accepted when creating a transaction so the create response can carry the inlined accounts and resulting balances.
Kordio Control paginates differently: starting_after takes a record id rather than an opaque cursor, and its has_more can be true on a final full page. See the spend control API reference.

Next steps

Webhooks

Walking the events tail after an outage.

API reference

The filter set on each list endpoint.