Page through Dairo lists with one cursor: the pagination block, the cursor and limit parameters, and SDK helpers that follow it for you.
Long lists come back one page at a time. The cursor pattern is the same on every list that paginates, so learn it once on messages and it works on letters, audit logs, and the event ledger.
The pagination block
Every list response carries a pagination object:
| Field | Type | Meaning |
|---|---|---|
nextCursor | string \| null | Cursor for the next page. null when there is no next page. |
hasMore | boolean | Whether another page exists. |
Treat nextCursor as opaque: it is not an offset, a timestamp, or an ID to build or
parse. Pass it back exactly as you got it. A list that fits in one response returns
nextCursor: null and hasMore: false.
Get the next page
To fetch the next page, send the previous page's nextCursor as the cursor query
parameter. Set limit (1–100, default 25) to size each page. Stop when nextCursor comes
back null.
A manual paging loop
Or let the SDK do it
The Python SDK's iter helpers follow the cursor for you and yield every item across all
pages, so you never hold a cursor yourself:
On the CLI, list commands take --limit and --cursor; pass each page's
pagination.nextCursor back as --cursor.
Which lists paginate
Cursor pagination applies to the lists that grow without bound: messages, threads, letters
and their events, storage objects, audit logs, contacts, and a contact's message history. On those,
nextCursor walks the pages. Smaller collections — domains, inboxes, webhooks, API keys,
templates, audiences — return their full set in one response, with nextCursor: null.
Filters (such as inboxId, threadId, direction, or channel=a2a on messages) compose
with pagination. Keep the same filters on every page so the cursor walks a stable result
set.
Tailing the event stream
The event stream (GET /v1/events) pages with the same pagination.nextCursor and
cursor parameter, and adds wait and tail parameters for real-time long-polling. Its
nextCursor names the last event on every non-empty page, also the last one, so a poller
keeps its place; hasMore says whether more events already exist. See
the event ledger for that pattern.
Paging with no filter walks an entire collection. For a large mailbox, add a filter
(inboxId, threadId) and a bounded loop; for live updates, use the event stream's wait
and tail rather than re-listing from the start.