Pagination

Page through search results with cursor pagination (default) or offset pagination, and choose the right mode for your use case.

Search endpoints return one page of records per request. Two pagination modes are available and you choose between them with a query parameter: send cursor (or nothing) for cursor pagination, or send offset for offset pagination. The two are mutually exclusive — a request containing both is rejected with 400.

Parameters

ParameterTypeRangeDefaultApplies to
limitinteger110050Both modes
cursorstring≤ 200 characters, opaquefirst pageCursor mode
offsetinteger0100000Offset mode

Out-of-range values are rejected with 400, not clamped. Count endpoints take no pagination parameters.

Which mode to use

Cursor (default)Offset
Request?cursor=<token>, or no pagination parameter?offset=<n>
page object in response{ limit, nextCursor, hasMore }{ limit, offset, total }
Total match countNot included — call the count endpoint onceIncluded in every response
OrderingFixed internal order. options.sortFields is ignoredSortable by headcount or revenue via options.sortFields
DepthUp to 100,000 records per journeyoffset ≤ 10,000
Jump to page nNoYes
Cost per pageLower — no total is recomputedHigher — the total is recomputed on every page

Use cursor pagination for anything that walks a result set — exports, CRM syncs, infinite scroll. It does not slow down as you go deeper and it will not skip or duplicate records the way a shifting offset can.

Use offset pagination when you need numbered pages or a ranked list (for example, the 20 largest companies by revenue). Because every offset response recomputes the total, a broad filter pays for a count on every page; if you will page more than a few times, use a cursor plus one call to the count endpoint instead.

Cursor pagination

Lifecycle

  1. First page — send the filter with no cursor. limit is optional.
  2. Next pages — copy page.nextCursor from the response into the cursor query parameter and send the identical request body again.
  3. Stop — when page.hasMore is false and page.nextCursor is null.
# First page
curl --request POST \
  --url 'https://api.cognism.com/companies/filter?limit=50' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{ "company": { "industry": { "include": ["Software"] } } }'
{
  "page": {
    "limit": 50,
    "hasMore": true,
    "nextCursor": "eyJ2IjoxLCJzIjoiLTkwOTIyNzYwNTA4NjMyNDY5NzciLCJoIjoiNWI1ODlhY2IiLCJuIjo1MH0"
  },
  "data": [ "…50 company records…" ]
}
# Next page — same body, cursor from the previous response
curl --request POST \
  --url 'https://api.cognism.com/companies/filter?limit=50&cursor=eyJ2IjoxLCJzIjoiLTkwOTIyNzYwNTA4NjMyNDY5NzciLCJoIjoiNWI1ODlhY2IiLCJuIjo1MH0' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{ "company": { "industry": { "include": ["Software"] } } }'

Rules

  • The cursor is opaque. It is a base64url token whose contents are an implementation detail and whose format is versioned. Do not parse it, modify it, construct one by hand, or store it long term.
  • The cursor is bound to your filter. The server fingerprints the request body when it issues a cursor and checks that fingerprint when the cursor comes back. Changing the filter mid-journey returns 400 cursor_filter_mismatch rather than silently mixing result sets. To search differently, start a new journey from the first page.
  • Consistency is bounded, not snapshot. Results are paged from a live index. Records that change between page requests may be skipped, duplicated or reordered.
  • options.sortFields is ignored in cursor mode. If you need a sorted result, use offset pagination.

Offset pagination

Send offset to request a specific window of the result set. Each response includes the total number of matching records.

curl --request POST \
  --url 'https://api.cognism.com/companies/filter?offset=0&limit=20' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "company": { "industry": { "include": ["Software"] } },
    "options": { "sortFields": [ { "field": "revenue", "direction": "DESC" } ] }
  }'
{
  "page": { "limit": 20, "offset": 0, "total": 48213 },
  "data": [ "…20 company records, largest revenue first…" ]
}

options.sortFields accepts headcount and revenue only, each with direction ASC or DESC. Sorting is applied only in offset mode; the same body sent with a cursor returns results in the fixed internal order.

Pagination errors

HTTPerrorWhenWhat to do
400(validation)cursor and offset sent together, or limit/offset out of range.Fix the request.
400invalid_cursorThe cursor is malformed or from an unsupported version.Restart the journey from the first page.
400cursor_filter_mismatchThe request body changed since the cursor was issued.Send the original body, or start a new journey.
422pagination_depth_exceededThe cursor journey has passed 100,000 records.Narrow the filter and start again.

None of these apply to the count endpoints. See Errors for the error envelope.


Did this page help you?