Skip to main content

Pagination

Four operations return more data than fits in one response and paginate with an opaque cursor:

OperationSDK method (TS / Python)Items field
listOrgAuditEventsaudit.listOrgEvents / audit.list_org_eventsevents
listMyAuditEventsaudit.listMyEvents / audit.list_my_eventsevents
listApiKeyAuditEventsaudit.listApiKeyEvents / audit.list_api_key_eventsevents
listWebhookDeliverieswebhooks.listDeliveries / webhooks.list_deliveriesdeliveries

Every other list (environments, templates, members, …) returns the whole collection in one response — no paging involved.

How the cursor works

Each request takes limit (page size) and cursor query parameters; each response carries the items plus a cursor field when there may be more. The cursor is opaque — pass it back verbatim, never parse or construct one.

One quirk worth knowing: these lists are backed by filtered scans, so a page can come back empty but still carry a cursor (the scanned range matched nothing, but the list isn't finished). "No cursor" is the only end-of-list signal — both SDKs' iteration handles this for you.

Iterate across pages

The paginated methods resolve to a page object you can iterate directly — items stream across page boundaries, and subsequent pages are fetched transparently as you go:

const page = await slothbox.audit.listOrgEvents({ orgId, query: { limit: 100 } });

for await (const event of page) {
// transparently fetches subsequent pages
console.log(event.action, event.at);
}

An AbortSignal passed in the request options also cancels the auto-pagination — the next-page fetches reuse the same options.

Query parameters you set on the first call (filters, limit) are preserved on every next-page fetch.

Manual paging

When you want page-at-a-time control — checkpointing a cursor between job runs, showing a "next page" button — use the page object's members:

let page = await slothbox.webhooks.listDeliveries({ orgId, endpointId });

page.items; // this page's deliveries
page.data; // the full typed response body
page.cursor; // the opaque cursor, or undefined on the last page

while (page.hasNextPage()) {
page = await page.getNextPage();
process(page.items);
}

getNextPage() throws if there is no next page — check hasNextPage() first.

To resume from a checkpoint, pass the saved cursor back as the cursor parameter of a fresh call.

Pace yourself

Audit and delivery histories can be long. Iterating a page to the end walks everything — fine for a backfill, wasteful in a hot path. Prefer a limit that matches what you'll actually use, filters (the audit lists take action, time-range, and resource filters) to shrink the walk, and webhooks over re-listing when what you really want is "tell me when something new happens."