Skip to main content
Collection endpoints that paginate take one query parameter: page, an integer starting at 1. That’s the whole mechanism — no cursor token to store between requests, no opaque string to round-trip.

What you get back differs by endpoint

Worth reading before you write one generic paginator and point it at everything, because the response shape isn’t uniform.
GET /api/v1/accounts/{account_id}/contacts returns:
meta.count is the total number of contacts matching the query, so you can compute how many pages exist. Default page size is 15.
GET /api/v1/accounts/{account_id}/conversations returns:
Notice what’s missing: no current_page, no total for the query you actually ran. The numbers in meta are status-bucket counts — mine, unassigned, assigned, all — not a page count for whatever filters you passed. The reliable end-of-list signal is an empty payload array, not a count comparison.
These return the full collection as a bare array, every time. No page parameter does anything, and there’s no meta to read, because nothing is being paged — you get everything in one response. That’s a reasonable design for what these lists actually are today (an account’s agent roster, its teams, its canned responses). It stops being reasonable if you’re building against an account with an unusually large canned-response library; there’s no server-side limit protecting you from a large response body on these endpoints.

The exception: message history

GET /api/v1/accounts/{account_id}/conversations/{conversation_id}/messages doesn’t take a page parameter — passing one silently does nothing. Message history pages backward and forward from a message ID instead: This isn’t in the published parameter list for that endpoint, but it’s the real, load-bearing behavior underneath both the Application API’s conversation-scoped messages endpoint and the Client API’s public messages endpoint. If you’re walking a long conversation, page backward with before set to the oldest message ID you’ve seen, and stop when you get an empty array.

Iterating safely

Whatever shape you’re dealing with, the safe loop termination is the same: stop when the page comes back empty, not when you hit a count you precomputed at the start. Filters and totals can both change between your first request and your fifth.

Next

Rate limits

What happens if that loop runs faster than it should.

Errors

The shape of the body when a page request fails.