Skip to main content
Every list endpoint returns a forward-only cursor page. You ask for a page size, get back a slice of results and an opaque cursor, then feed that cursor in to fetch the next slice. List responses always have the same envelope: an array of results in data, and a nextCursor you pass to the next request.
A page

Query parameters

integer
Page size, 1100. Defaults to a sensible value (typically 20) when omitted.
string
The nextCursor from the previous response. Omit it to start at the first page. Cursors are opaque — don’t construct or parse them.
Endpoint-specific filters (such as status or q on GET /v1/emails) combine with limit and cursor. Keep the filters identical across calls in a walk — a cursor is only valid for the same query it was issued from.

Walking a list

Request a page, process data, then repeat with ?cursor=<nextCursor> until nextCursor comes back null.

End of the list

When there are no more results, nextCursor is null. That is the only end-of-list signal — don’t rely on data being shorter than limit, which can happen mid-list.
The final page
Let the SDK do it. The SDK exposes .paginate() on every list resource — an async iterator that fetches each page lazily and yields one item at a time, so you never touch a cursor. The CLI auto-paginates too.
Stable ordering. Pages are ordered newest-first by creation time. Because the cursor is anchored to a row rather than an offset, inserting new rows while you paginate won’t shift or duplicate results across pages.