Skip to main content
Stored collections — your lists and their rows — use page-number pagination, because they live in a database where jumping to an arbitrary page is cheap. Prospect search uses scroll-token pagination, because results stream from a search index where a cursor is the way to walk a large result set. A person can still show up on more than one page, so de-duplicate the profiles you collect on linkedin_url. A few other endpoints use their own cursor or page fields, listed under Other collections.

Page-number pagination

List endpoints accept two query parameters: Paginated responses always put the records in a data array and the paging metadata in a pagination object:
To walk the whole collection, increment pageNum until it reaches totalPages. Requesting a page past the end returns an empty data array, so an off-by-one in your loop fails soft rather than erroring.
The data key is reserved for paginated collections. Non-paginated responses are keyed by entity name instead — GET /business/me returns { "user": ... }, not { "data": ... }. If you see data, expect pagination next to it. Some paginated collections are keyed by entity name too, such as campaigns or agents; see Other collections.

Counts are read-time, not snapshot

totalRecords and totalPages reflect the collection at the moment of each request. If contacts are being added or removed while you paginate — an enrichment job filling a list, a teammate deleting rows — records can shift between pages, so a full walk may see a row twice or miss one. For a point-in-time copy of a list, use an export instead of paginating rows.

Scroll-token pagination

Search endpoints return a scrollToken alongside each page of profiles. Pass it back as scrollToken in the next request body to fetch the following page. When scrollToken is null, you have reached the end of the results. The last page, usually shorter than size, carries a null token, and so does a lookup of named people (linkedinUrl, the linkedin_url filter, or the email and phone filters) when they all fit in size. Stop on the null token, not on a short page: a page can also come back a little short while more pages follow, because repeated people are removed. Treat the token as an opaque string. Do not parse it or rely on its length, and send it back exactly as you received it. A token this API did not issue, or one that was altered, is refused with 422 SCROLL_TOKEN_INVALID and nothing is billed. So is a token issued before the people search changes in the changelog. A token whose filters, or the companies they name, changed since its first page is refused with 422 SEARCH_CHANGED. In both cases, start the search again without scrollToken. Request the first page as usual — size controls the page size (default 10, maximum 100):
Then repeat the same request with the token added:
Running a saved search with POST /business/saved-searches/{savedSearchId}/run pages the same way: each response carries a scrollToken for the next page.
Scroll tokens are short-lived and tied to the query that produced them. Do not persist them, share them across queries, or resume a scroll after a long pause — start a fresh search instead. There is no way to jump to an arbitrary page mid-scroll; the token only moves forward.
If your goal is to collect search results rather than browse them, you usually do not need to scroll at all — POST /business/prospects/search/save-to-list runs the search server-side and saves the matches in one call. See build a list from search.

Other collections

Which mechanism am I looking at?

You never choose — the endpoint does. A quick way to tell from a response body:
  • data + pagination → page numbers. Iterate with pageNum.
  • profiles + scrollToken → scroll. Iterate by echoing the token.
Per-endpoint parameters and response shapes are in the API reference. Pagination requests count against your rate limit like any other call — see rate limits for budgeting long walks.