List ledger transactions
The ledger.transactions.list operation: GET /api/v1/ledger/transactions in the REST API and the ledger_transactions_list tool in the MCP server.
/api/v1/ledger/transactionsLists the transactions of the legal entity's ledger in the mode of the request, newest first. Every
transaction has balanced debit and credit entries (integer micros) on the entity's accounts, its kind
and status, the actor who posted it (with approvalId when a second person approved it) and the objects
it is about (links). Posted transactions are never changed: corrections are reversals (reversalOf).
Filters: accountId (an account statement), kind (one or several), status, brandId (or none), and
effectiveFrom / effectiveTo, whole days in UTC (YYYY-MM-DD, both included). Paginate with limit
(1–100, default 10) and starting_after (the next_cursor of the previous page). With a date filter, one
call reads at most 1,000 transactions, so a page can hold fewer
than limit items while has_more is true: keep paging with next_cursor.
At a glance
- REST:
GET /api/v1/ledger/transactions - MCP tool:
ledger_transactions_list - Operation ID:
ledger.transactions.list - Scope: Legal entity
- Permission:
ledger:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Pagination:
limit(at most 100) andstarting_after - Authentication: API key with the
ledger:readscope - Since: M2
Request
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
accountId | acct_… ID | No | Transactions with an entry on this account: its statement. |
kind | one of 19 values, e.g. topup, sale, grant (all in the OpenAPI document) or array of one of 19 values, e.g. topup, sale, grant (all in the OpenAPI document) | No | One kind, or several. |
status | one of pending, posted, voided | No | pending, posted or voided. |
brandId | brd_… ID or "none" | No | A brand's transactions (brd_…), or none for those of no brand. |
effectiveFrom | string | No | Effective on or after this day (YYYY-MM-DD, UTC). |
effectiveTo | string | No | Effective on or before this day (YYYY-MM-DD, UTC). |
limit | integer (1 to 100) | No | Page size, 1 to 100 (default 10). |
starting_after | txn_… ID | No | The next_cursor of the previous page. |
Response
200 OK with a JSON object, a page of the list (newest first):
| Field | Type | Description |
|---|---|---|
object | "list" | |
data | array of object | |
data[].id | txn_… ID | |
data[].object | "ledger_transaction" | |
data[].entityId | ent_… ID | |
data[].livemode | boolean | |
data[].brandId | brd_… ID or null | |
data[].kind | one of 19 values, e.g. topup, sale, grant (all in the OpenAPI document) | |
data[].status | one of pending, posted, voided | |
data[].entries | array of object | |
data[].entries[].accountId | acct_… ID | |
data[].entries[].accountCode | string | The account's code from the chart of accounts. |
data[].entries[].side | one of debit, credit | |
data[].entries[].amount | string | Integer micros, more than zero. |
data[].entries[].currency | string | |
data[].totals | array of object | Debit and credit totals per currency, always equal. |
data[].totals[].currency | string | |
data[].totals[].debits | string | |
data[].totals[].credits | string | |
data[].effectiveAt | date-time | The business date of the movement. |
data[].postedAt | date-time or null | |
data[].voidedAt | date-time or null | |
data[].reversalOf | txn_… ID or null | The posted transaction this one reverses. |
data[].links | object | Objects the transaction is about, by ID. |
data[].memo | string | The description; for a manual adjustment, its reason. |
data[].actor | object | Who posted it. approvalId names the approval request when a second person approved it. |
data[].actor.type | one of user, api_key, agent, app, system, public, customer | |
data[].actor.id | string | |
data[].actor.via | one of console, api, mcp, assistant, portal, job or null | |
data[].actor.approvalId | string or null | |
data[].actor.onBehalfOfUserId | string or null | |
data[].actor.clientId | string or null | |
data[].actor.supportGrantId | string or null | |
data[].createdAt | date-time | |
has_more | boolean | |
next_cursor | txn_… ID or null |
Examples
Manual adjustments in October 2026
GET /api/v1/ledger/transactions?kind=adjustment&effectiveFrom=2026-10-01&effectiveTo=2026-10-31
Authorization: Bearer or_test_…
Response (200):
{
"object": "list",
"data": [
{
"id": "txn_01m4tx5nj8emwbyf7y9vcf47xg",
"object": "ledger_transaction",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"livemode": true,
"brandId": null,
"kind": "adjustment",
"status": "posted",
"entries": [
{
"accountId": "acct_01m4tx5nj8emwbyf7y9vcf47xc",
"accountCode": "bank:ent_01m4tx5nj8emwbyf7y9vcf47x2:EUR",
"side": "debit",
"amount": "1500000000",
"currency": "EUR"
},
{
"accountId": "acct_01m4tx5nj8emwbyf7y9vcf47xd",
"accountCode": "opening_balances:EUR",
"side": "credit",
"amount": "1500000000",
"currency": "EUR"
}
],
"totals": [
{
"currency": "EUR",
"debits": "1500000000",
"credits": "1500000000"
}
],
"effectiveAt": "2026-10-14T09:30:00.000Z",
"postedAt": "2026-10-14T09:30:00.000Z",
"voidedAt": null,
"reversalOf": null,
"links": {},
"memo": "Opening bank balance from the 2026-09-30 statement",
"actor": {
"type": "user",
"id": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
"via": "console",
"approvalId": "apr_01m4tx5nj8emwbyf7y9vcf47xj",
"onBehalfOfUserId": null,
"clientId": null,
"supportGrantId": null
},
"createdAt": "2026-10-14T09:30:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
The statement of one account, one per page
GET /api/v1/ledger/transactions?accountId=acct_01m4tx5nj8emwbyf7y9vcf47xc&limit=1
Authorization: Bearer or_test_…
Response (200):
{
"object": "list",
"data": [
{
"id": "txn_01m4tx5nj8emwbyf7y9vcf47xg",
"object": "ledger_transaction",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"livemode": true,
"brandId": null,
"kind": "adjustment",
"status": "posted",
"entries": [
{
"accountId": "acct_01m4tx5nj8emwbyf7y9vcf47xc",
"accountCode": "bank:ent_01m4tx5nj8emwbyf7y9vcf47x2:EUR",
"side": "debit",
"amount": "1500000000",
"currency": "EUR"
},
{
"accountId": "acct_01m4tx5nj8emwbyf7y9vcf47xd",
"accountCode": "opening_balances:EUR",
"side": "credit",
"amount": "1500000000",
"currency": "EUR"
}
],
"totals": [
{
"currency": "EUR",
"debits": "1500000000",
"credits": "1500000000"
}
],
"effectiveAt": "2026-10-14T09:30:00.000Z",
"postedAt": "2026-10-14T09:30:00.000Z",
"voidedAt": null,
"reversalOf": null,
"links": {},
"memo": "Opening bank balance from the 2026-09-30 statement",
"actor": {
"type": "user",
"id": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
"via": "console",
"approvalId": "apr_01m4tx5nj8emwbyf7y9vcf47xj",
"onBehalfOfUserId": null,
"clientId": null,
"supportGrantId": null
},
"createdAt": "2026-10-14T09:30:00.000Z"
}
],
"has_more": true,
"next_cursor": "txn_01m4tx5nj8emwbyf7y9vcf47xg"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A filter or pagination value is invalid, or effectiveFrom is after effectiveTo. | Fix the fields listed in details.issues and send the request again. |
scope_required | 400 | The request names no legal entity (an org key without Ownrecord-Entity). | Call the operation with credentials or a target at its level: an organization, a legal entity, a brand or the platform (details.required_scope). |
permission_denied | 403 | You can't see this entity's ledger (brand-scoped members never can). | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, resource_not_found, dry_run_not_supported, rate_limited, internal_error.