Pagination
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.
{
"data": [
{ "id": "msg_01HZX…", "subject": "Receipt", "status": "delivered" },
{ "id": "msg_01HZW…", "subject": "Welcome", "status": "delivered" }
],
"nextCursor": "eyJpZCI6Im1zZ18wMUhaVyJ9"
}01 Query parameters
1–100. Defaults to a sensible value (typically 20) when omitted.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.
02 Walking a list
Request a page, process data, then repeat with ?cursor=<nextCursor> until nextCursor comes back null.
# First page
curl "https://api.drin.run/v1/emails?limit=50" \
-H "Authorization: Bearer $DRIN_API_KEY"
# Next page — feed back the previous nextCursor
curl "https://api.drin.run/v1/emails?limit=50&cursor=eyJpZCI6Im1zZ18wMUhaVyJ9" \
-H "Authorization: Bearer $DRIN_API_KEY"03 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.
{
"data": [ { "id": "msg_01HZA…", "subject": "Magic link", "status": "delivered" } ],
"nextCursor": null
}.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.