Pagination, ids and envelopes
The shape every response shares — how to page a list, what an id looks like, and where the data actually sits.
The envelope
Every 2xx is wrapped. The payload is always under data.
{
"status": "success",
"message": "Customers successfully retrieved",
"data": { … }
}Every error is the other shape — never a mix of the two:
{ "error": "validation_error", "error_description": "name: name is required",
"details": [ { "field": "name", "message": "name is required" } ] }Paging a list
| Parameter | Default | Range |
|---|---|---|
| page | 1 | 1 and up |
| page_size | 25 | 1 – 200; anything larger is clamped to 200 |
curl "https://api.trabalance.com/api/v1/customers?page=2&page_size=50" \
-H "Authorization: Bearer tk_live_…"Party and settlement lists return a pagination block beside items:
{ "status": "success",
"data": {
"items": [ … ],
"pagination": { "total_count": 128, "page": 2, "pageSize": 50, "has_next": true, "has_prev": true }
} }GET /items answers with a plain array filtered by type and status rather than a page block. Read the shape from the OpenAPI document rather than assuming it.
Ids
Ids are UUIDs and are accepted with or without dashes — 0f9e5c2a-… and 0f9e5c2a… reach the same record. Responses may carry either form depending on the resource, so compare ids case-insensitively with dashes stripped rather than as raw strings.
An id from another business is treated exactly like an id that does not exist: 404 not_found. This is deliberate — the API never confirms that a record exists somewhere else.
Ordering
Lists come back in the order the backend computed them, ordered by the document's own business date — an invoice by invoice_date, a bill by bill_date — never by when the row happened to be saved. Do not re-sort a page client-side and expect it to line up with the next page.