Pagination
Hooksbase uses opaque cursor pagination for list endpoints. You ask for one page
at a time, receive a nextCursor when more results exist, and send
that cursor back with the exact same filter set to fetch the next page.
Cursor model
Pagination rules are consistent across the supported list routes:
limitdefaults to20limitis clamped to1..100- malformed non-integer
limitvalues return400 - cursors are opaque; do not parse or construct them yourself
- foreign or malformed cursors return
400 - cursors are scoped to the exact active filter set
Example request:
Request one page
curl -G https://api.hooksbase.com/v1/deliveries \
-H "Authorization: Bearer swk_..." \
-d webhookId=wh_... \
-d limit=20
Example response shape:
Paged list response
{
"items": [
{ "id": "del_...", "status": "succeeded" }
],
"nextCursor": "eyJ..."
}
When nextCursor is present, pass it back as the cursor
query parameter on the next request (keeping every other filter identical).
When it is null or absent, you have reached the end.
Supported endpoints
These Public API routes use cursor pagination:
-
GET /v1/webhooks -
GET /v1/project/api-keys -
GET /v1/project/audit-logs -
GET /v1/deliveries -
GET /v1/webhooks/{id}/deliveries -
GET /v1/deliveries/{id}/replay-jobs -
GET /v1/dlq -
GET /v1/dlq/export -
GET /v1/webhooks/{id}/schedules - operator alerting list and dispatch-history routes under
/v1/project
Some cursors are scoped even more tightly:
- webhook cursors include the authenticated project and webhook status filter
- project delivery cursors include the full filter set
- replay-job cursors are scoped to one source delivery
- DLQ cursors are scoped to the active DLQ filter set
- DLQ export accepts cursor pagination but caps each export page at 20 rows
Using the SDK helpers
The TypeScript SDK includes paginateCursor() and
takePages() helpers when you want to consume multiple server pages
without hand-rolling the loop.
Iterate deliveries one page at a time
import { createHooksbaseClient, paginateCursor, takePages } from '@hooksbase/sdk'
const client = createHooksbaseClient({ apiKey: process.env.HOOKSBASE_API_KEY })
const iterator = paginateCursor((cursor) =>
client.deliveries.list({
webhookId: 'wh_123',
limit: 20,
cursor: cursor ?? undefined,
}),
)
for await (const delivery of iterator) {
console.log(delivery.id, delivery.status)
}
// Or stop after the first N items:
const first100 = await takePages(iterator, 100)
Each callback receives the latest cursor (null on the
first call) and returns the raw { items, nextCursor }
response. The helper keeps requesting pages until nextCursor is
null or absent.
Common mistakes
- Reusing a cursor with a different filter set.
- Assuming cursor pagination supports arbitrary jump-to-page behavior.
- Treating the cursor as stable forever. Always read and use the latest
nextCursorfrom the response you just received.