Skip to main content
Every /data list endpoint pages by cursor: each response returns a token for the next and the previous page, and you send it back as cursor=. Performance stays the same however deep you go. That covers top-level collections, map points (/geo) and nested lists such as a company’s team, funding rounds, valuations or investors, an investor’s portfolio and funds, or a person’s career. limit sets the page size of the first request.
offset was retired in API version 2026-10-07: a /data request that sends it returns 400 VALIDATION_ERROR naming cursor as the replacement. Clients pinned to an earlier API-Version can still send limit and offset until that version is sunset — see Versioning.
page.total is omitted by default because counting every matching row requires an additional query. Add include_total=true when your interface needs the total.
The cursor changes name between the response and the request. The response returns it as page.next_cursor, but you send it back as cursor=. Unknown query parameters are ignored rather than rejected, so a request built with next_cursor= returns the first page again, with no error. A loop written that way never advances.

Parameters

Limits

Page size and pagination depth are separate axes: page size bounds a single response, depth (the page’s position, page.offset, plus limit) bounds how far you can page. Each endpoint has a hard page-size ceiling:

Limits for browser and keyless requests

Browser sessions and requests without an API key have lower page-size and depth limits. Programmatic API-key requests use the endpoint maximum above and have no pagination-depth cap. Page size is clamped, not rejected. An over-limit browser or keyless request returns the reduced size and sets page.capped to true. These session-specific caps apply to core list endpoints only; geo, taxonomy, and aggregate endpoints are not capped this way. Depth applies to every list endpoint. 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 (0 for the first page, limit for the second, etc.). Use it for “showing rows X–Y of Z” display
  • page.next_cursor — token to fetch the next page, or null when this is the last page
  • page.prev_cursor — token to fetch the previous page, or null when this is the first page
  • page.total — total matching records; present only when include_total=true
Core list endpoints that apply the session limits above also return page.capped, page.tier and page.ecosystem. page.tier names the access applied to the request: anonymous, free or premium. API-key requests report premium, because they receive every field and are not page-capped.

Walking forward (cursor)

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 page size and position — the cursor token embeds both, so ?limit= is ignored when ?cursor= is sent. To change page size, restart from the first page with the new ?limit=.
  • Echo sort and filter on 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 returns 400 Invalid cursor for this sort order; restart from the first page.
  • Bound to filter — changing ?filter= mid-paging returns 400 Cursor is bound to a different filter; restart from the first page. Currency (?currency=) and view (?view=) are not bound — switching either 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.

Including the total count

By default page.total is omitted — cursor pages stay cheap. Pass include_total=true to include it:
For large datasets, skip the total count when you don’t need it — omitting it avoids a full-table count query.
Ranked results — semantic_keyword search, /similar endpoints and news q search — stop at the first 1,000 results: a walk cannot page past position 1,000, page.total is at most 1,000, and the last page in that range returns next_cursor: null. Narrow the filter to reach other results. Cursors on a nested list are tied to its parent: a cursor from one company’s team is rejected on another company’s team.

Further reading

Filtering

Build the stable filter expression that must accompany every cursor request.

Rate limits

Design larger result walks to stay within your request budget.