Pagination
Every list answers one page:
limitsets the page size: 1 to 200, 50 by default.- Follow
next_cursoruntil it isnull. Send the cursor back as?cursor=on a GET list, or as"cursor"in the body ofPOST /calls/searchandPOST /usage/query. - A cursor is opaque. It is bound to your workspace, every filter, the grouping and the limit: send them unchanged with it. A changed filter or limit with an old cursor is refused.
- A cursor expires after 24 hours.
- An invalid, expired or foreign cursor answers
400 invalid_requestwithdetails.field = "cursor", and never returns another workspace’s data. Start again without the cursor.
Campaign transcript CSV pages
GET /batch-calls/{batch_id}/transcripts/export uses the same opaque-cursor rules, but each
response is a CSV file instead of a JSON page:
limitis 1 to 500 and defaults to 500. Keep it unchanged for the complete download.- Read the continuation from the
X-Next-Cursorresponse header. Its absence means the download is complete. - The first request fixes an upper watermark. Attempts created later do not enter the remaining pages of that download.
- Save each page separately or parse its CSV rows. Do not append complete page files blindly, because each page contains its own CSV header.
- If a transfer breaks, discard that incomplete page and retry it with the same cursor. For the first page, retry without a cursor.
The cursor is bound to the workspace, campaign and limit, and expires after 24 hours. See Calls and results for request examples.
Ordering
Each operation in the API reference states its order. Agent, version, secret and call lists are
newest first; GET /calls orders by creation time and then ID, both descending.
Keeping a copy in sync
GET /calls?updated_since=… switches the call list to a changes scan: items come oldest change
first, and the last page carries scanned_through, where the next scan starts. See
Calls and results.
A transcript page is bound to the transcript it came from: if a newer transcript replaces it, the
old cursor answers invalid_request with details.field = "cursor". Start again without it.
Date ranges
Operations with start and end take UTC timestamps. start is inclusive and end exclusive, a
range covers at most 93 days, and the default is the trailing 30 days.