API DOCUMENTATION / PAGINATION AND CURSORS

Pagination and cursors

Understand the distinct continuation rules for jobs, companies, and usage reports.

Jobs pages use the current projection watermark

Jobs list cursors are opaque, HMAC-signed tokens bound to the projection ID, exact snapshot watermark, normalized filters, and page size. The route checks that the projection watermark has not changed. If a publication advances it, an old cursor is rejected; restart at the first page with the same filters and limit. No cursor TTL is established in the inspected code.

Companies pages pin a retained release

Company list/search cursors bind the normalized filters and page size to a retained company release. The cursor reads that release rather than requiring the active release to remain unchanged. Missing retained releases or mismatched request scope fail validation. Company ordering is normalized name, then company UUID, ascending.

Usage request cursors

Usage-request cursors are customer-bound and tied to filters, page size, a high-water row, and an admission capture time. They expire 60 minutes after the initial capture; paging does not extend expiry. The report reads ledger finalization state for captured admissions, so the capture time is not a frozen settlement snapshot.

Keep page parameters stable

When continuing, use the same endpoint, filters, and exact page size that produced the cursor. Store the complete response cursor as an opaque value. Treat the cursor as opaque; the route does not define a client-side format for decoding or creating one.

A cursor is not a durable export checkpoint

Jobs cursors do not promise continuation across projection changes. For a reliable ingestion workflow, record your own completed work and restart a changed jobs query when its cursor becomes invalid. The changes feed has its own resume cursor; see the jobs reference.

Page sizes and cursor rules

RoutePage sizeDefaultNext page
GET /v1/jobs, GET /v1/companies/{companyId}/jobs1 to 25050next_cursor → cursor
GET /v1/jobs/changes1 to 1,000100resume_cursor → after, while has_more is true
GET /v1/companies, POST /v1/companies/search1 to 10050next_cursor → cursor
GET /v1/usage/requests1 to 10050next_cursor → cursor; expires after one hour

A jobs cursor is tied to the filters, page size, sort and catalog snapshot it came from. A cursor from an older snapshot or a different query returns 400 invalid_request; start again from the first page. next_cursor is null on the last page. Cursors are up to 2,048 characters (8,192 for usage reports). For long-running syncs, see the ingestion strategy.

Continue in the reference

Check related request behavior before you build.

View route status and methods Discuss API requirements
All API documentation