- Cursor (keyset) pagination — round-trip
page.next_cursor/page.prev_cursorvia?cursor=. O(page size) regardless of depth. Recommended for browsing UIs and forward/backward walking. - Offset pagination — classic
?limit=&offset=. Supports random access — jump straight to any page within your plan’s depth cap (see Per-plan caps below). Cost grows with theoffsetvalue.
?cursor=X&offset=N ignores the offset).
Need the older
offset-based shape? Send API-Version: 2026-05-22 (or any earlier date) and the response will use the legacy { limit, offset, total } envelope. Old clients keep working unchanged.Parameters
Limits
Page size and pagination depth are separate axes: page size bounds a single response, depth (offset + limit) bounds how far you can page. Each endpoint has a hard page-size ceiling:
Per-plan caps. Requests without an API key get a lower page size and a bounded pagination depth,
by plan:
Page size is clamped, not rejected — an over-limit request returns the reduced size and sets
page.capped to true (see the response shape below). The per-plan page size applies to the core
list endpoints only (companies, entities, investors, founders, transactions, valuations,
jobs, news); geo, taxonomy, and aggregate endpoints are not per-plan page-capped.
Depth applies to every list endpoint, on both the offset and cursor styles. A request beyond the cap
returns 400 with error code PAGINATION_DEPTH_EXCEEDED — the page is not silently truncated.
Response shape
page.limit— applied page size (carried by the cursor on subsequent pages)page.offset— the server’s view of where this page sits in the result set (0for the first page,limitfor the second, etc.). Use it for “showing rows X–Y of Z” displaypage.next_cursor— token to fetch the next page, ornullwhen this is the last pagepage.prev_cursor— token to fetch the previous page, ornullwhen this is the first pagepage.total— total matching records; present only wheninclude_total=truepage.capped—truewhen the requestedlimitwas reduced to the per-plan page-size cap. Present on capped list endpoints for requests without an API keypage.tier— the access tier applied to the request:anonymous,free, orpremium. Present alongsidecappedpage.ecosystem— slug of the active ecosystem when the request is scoped to one (resolved from the request origin), ornullwhen global. Present alongsidecapped
Walking forward (cursor)
Random access (offset)
offset + limit beyond your plan’s depth cap returns 400 PAGINATION_DEPTH_EXCEEDED (see Per-plan caps above).
Walking back
prev_cursor is null exactly when you’re on the first page.
For a “Page N of M” UI, read page.offset and page.limit straight from the response — the cursor token already carries the current offset, so the server reports it back without the client doing any arithmetic.
Cursor rules
- Opaque — treat the cursor as a black box. Do not decode, modify, or construct it manually.
- Carries limit/offset only — the cursor token embeds page size and offset, so
?limit=and?offset=are ignored when?cursor=is sent. To change page size, restart from the first page with the new?limit=. - Echo
sortandfilteron every request — the cursor does NOT contain the sort or filter expression. The server compares the cursor’s fingerprints against the resolved sort and filter of the current request, so the rule is “the request’s resolved sort/filter must match what minted the cursor.” In practice that means resending the same?sort=and?filter=you used on page 1. Technically, if a cursor was minted under default sort and empty filter, omitting both is fine because the defaults still match — but the safe pattern is to always echo them so client code doesn’t break the moment a non-default sort or filter is in play. Mismatch returns a 400. - Bound to sort — changing
?sort=mid-paging returns400 Invalid cursor for this sort order; restart from the first page. - Bound to filter — changing
?filter=mid-paging returns400 Cursor is bound to a different filter; restart from the first page. Currency (?currency=) is not bound — switching currencies mid-paging is safe. - No random jumps — cursors are sequential: no cursor jumps straight to an arbitrary page (e.g. “page 47”). Walk
next_cursor/prev_cursor, or restart from the first page. (Offset pagination does allow random access, but both styles are bounded by the per-plan depth cap above.)
Including the total count
By defaultpage.total is omitted — cursor pages stay cheap. Pass include_total=true to include it:
In-memory list endpoints (
/platform/ecosystems, /platform/teams, /platform/api-keys) keep the legacy { limit, offset, total } shape even on the new version — their datasets are small and bounded, so cursor pagination offers no benefit.