Developers
Show batch ingestion and synchronization guides and endpoints, core concepts, and the content hash calculator.
Explore the docs

Work with data

Read data

Retrieve records, list business IDs, and paginate with opaque cursors.

On this page

All reads below use Authorization: Bearer YOUR_API_KEY and return only that tenant's data. Use logical table names, not physical database table names. Public clients do not need an internal secret.

List records

http
GET /api/tables/payments?limit=25&sort_by=payment_date&sort_order=desc
Authorization: Bearer YOUR_API_KEY
json
{
  "data": [{"payment_id": "PAY-2024-001", "disbursement_id": "DSB-2024-001", "payment_total": 250, "currency": "USD"}],
  "pagination": {"limit": 25, "has_more": false}
}
ParameterContract
limitInteger 1-1000, default 50; invalid values return 400, not silent clamping
cursorOpaque token from pagination.next_cursor; URL-encode it
sort_byDefaults to created_at; asset_status and disbursement_status use on_date
sort_orderasc or desc, default desc
include_counttrue adds total and total_pages; counts may be cached
date_fieldRequired if either date bound is supplied
start_date, end_dateInclusive bounds on the selected date field
searchPartial match across searchable ID/status columns for the table

Sorting uses primary-key tiebreakers for deterministic pagination. Rows with a null selected sort value are excluded. Keep the same table, filters, and sort on every page. Discard legacy raw-ID/timestamp cursors and start again from the first page.

List business IDs

http
GET /api/tables/clients/ids?limit=50
Authorization: Bearer YOUR_API_KEY
json
{
  "data": ["client-001", "client-002"],
  "pagination": {
    "limit": 50,
    "has_more": true,
    "next_cursor": "eyJ2IjoxLCJzIjoiY2xpZW50LTAwMiIsImsiOltdfQ"
  }
}

The limit is 1-1000, default 50, and IDs sort ascending. Pass the returned token as cursor, not client-002 itself. The token is opaque even if you recognize how this illustrative token is encoded.

Example pagination loop (supply your environment's base URL and API key securely):

javascript
async function listClientIds(baseUrl, apiKey) {
  const ids = new Set();
  const url = new URL('/api/tables/clients/ids', baseUrl);
  url.searchParams.set('limit', '1000');
  while (true) {
    const response = await fetch(url, {headers: {Authorization: `Bearer ${apiKey}`}});
    if (!response.ok) throw new Error(`Read failed: ${response.status}`);
    const page = await response.json();
    page.data.forEach((id) => ids.add(id));
    if (!page.pagination.has_more) return ids;
    if (!page.pagination.next_cursor) throw new Error('Missing continuation token');
    url.searchParams.set('cursor', page.pagination.next_cursor);
  }
}

Choose create versus update

Compare source IDs with stored IDs: absent IDs use create; existing IDs use update. Do not probe with a create and fall back after 409: terminal failures can reserve the key and add error noise. For a single interactive record, GET /api/tables/{table}/{id} gives 200 or 404.

Use sync-state when you also need version-2 hashes to skip redundant updates. Missing source IDs should be reviewed, not automatically deleted.

Get one record

http
GET /api/tables/disbursements/DSB-2024-001
Authorization: Bearer YOUR_API_KEY
json
{"data": {"disbursement_id": "DSB-2024-001", "client_id": "BR-2024-001", "disbursement_amount": 10000, "currency": "USD"}}

For the four main tables, the path ID is the business ID (client_id, disbursement_id, payment_id, or operation_id). Other allowed tables use their table primary key. Returned database rows are not valid ingest bodies: select allowed fields and add the correct envelope/step instead of copying audit fields or content_hash back to ingestion.

Allowed tables

clients, disbursements, payments, operations, purchase_clients, asset_status, disbursement_status, write_offs, rebates, extensions, restructures.

Internal event tables, deleted mirrors, and silver/gold tables are not exposed through these routes.

Errors

  • 400: invalid table, cursor, limit, sort/date-field name, or date filters without date_field.
  • 401: missing or invalid API key.
  • 403: an unnecessary internal header failed verification; normal public requests use bearer authentication only.
  • 404: requested record does not exist.
  • 500: unexpected read failure; retain X-Correlation-ID for support.

Validate locally. Verify in sandbox.
The JSON validator checks structure and rounding. Credentials, existing records, and server-side state still require your test environment.

Search documentation

Start typing to find your next step.

    navigate Enter openLocal, private search