Pagination & conventions

Every list endpoint behaves the same way, so a single helper in your client can cover all of them.

Cursor pagination

Lists return a data array and a next_cursor. Pass the cursor back verbatim to get the next page; when it is null you have reached the end. Offsets and page numbers are not supported — new calls arrive constantly and would shift them.

bash
curl "https://<your-api-host>/api/v1/calls?limit=50&cursor=eyJpZCI6ImNhbGxfN2I1NSJ9" \
  -H "Authorization: Bearer cak_live_..."
FieldTypeDescription
limitinteger1–100, default 25.
cursorstringOpaque cursor from the previous response.
next_cursorstring | nullPass to the next request, or null at the end of the list.
ts
async function* pages(path: string) {
  let cursor: string | null = null;
  do {
    const url = new URL(path, API);
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);
    const page = await fetch(url, { headers }).then((r) => r.json());
    yield page.data;
    cursor = page.next_cursor;
  } while (cursor);
}

Filtering and sorting

Lists are newest-first. Filters are query parameters and combine with AND: ?outcome=hot&from=2026-09-01&to=2026-09-09. from and to are inclusive dates or timestamps. q does a substring match on the fields a human would search — caller name, phone, address, postcode.

Update semantics

PATCH is a partial update: send only the fields you want changed. Omitted fields are untouched; an explicit null clears a field.

PUT is a full replacement, and the agent draft is the one place it matters. Read the draft, change what you need, and send the whole object back — anything you leave out is removed.

Read-modify-write the agent draft in a single flow. Do not build a draft object from scratch unless you intend to discard the current configuration.

Idempotency

Send Idempotency-Key on any POST you might retry. Repeating the same key within 24 hours returns the original response instead of creating a second record.

bash
curl -X POST https://<your-api-host>/api/v1/leads \
  -H "Authorization: Bearer cak_live_..." \
  -H "Idempotency-Key: 8f14e45f-ea3a-4f2c-9a1b-77c0f5a2d901" \
  -H "Content-Type: application/json" \
  -d '{"phone":"+447700900123","name":"Denise Okafor","source":"web_form"}'

Rate limits and retries

Retry 429, 502, 503 and 504 with exponential backoff and jitter, honouring Retry-After. Never retry 400, 401, 403, 404 or 422 — those need a change to the request.