Skip to main content

Overview

The Explorium API supports two pagination modes for the Fetch Businesses (POST /v1/businesses) and Fetch Prospects (POST /v1/prospects) endpoints:
ModeBest ForMax Results
Offset-based (page / page_size)Small to medium datasets, random page accessUp to 60,000 records
Cursor-based (search_after)Large datasets, streaming all results efficientlyNo limit
Both modes return results in pages of up to 500 records each.

Offset-Based Pagination

Offset-based pagination uses page and page_size parameters to retrieve specific pages of results. This is the simplest approach and works well when you need random access to any page.

Parameters

ParameterTypeRequiredDescription
sizeNumberNoMaximum total records to return across all pages. Defaults to 60,000. Must be ≤ 60,000.
page_sizeNumberYesNumber of records per page. Maximum: 500.
pageNumberNoPage number to retrieve (1-based). Defaults to 1.

How It Works

  1. Send your first request with page: 1 and your desired page_size.
  2. The response includes total_results, total_pages, and page so you know how many pages are available.
  3. Increment page to retrieve subsequent pages until you reach total_pages.

Example Request

curl -X POST "https://api.explorium.ai/v1/businesses" \
  -H "api_key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": {
      "country_code": { "values": ["US"] },
      "company_size": { "values": ["51-200"] }
    },
    "mode": "full",
    "size": 500,
    "page_size": 100,
    "page": 1
  }'

Example Response

{
  "response_context": {
    "correlation_id": "abc123",
    "request_status": "success",
    "time_took_in_seconds": 0.45
  },
  "data": [ ... ],
  "total_results": 500,
  "page": 1,
  "total_pages": 5
}

Full Python Example

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.explorium.ai/v1/businesses"

headers = {
    "api_key": API_KEY,
    "Content-Type": "application/json"
}

payload = {
    "filters": {
        "country_code": {"values": ["US"]},
        "company_size": {"values": ["51-200"]}
    },
    "mode": "full",
    "size": 500,
    "page_size": 100,
    "page": 1
}

all_results = []

while True:
    response = requests.post(BASE_URL, headers=headers, json=payload)
    data = response.json()

    all_results.extend(data["data"])
    print(f"Page {data['page']}/{data['total_pages']} — fetched {len(data['data'])} records")

    if data["page"] >= data["total_pages"]:
        break

    payload["page"] += 1

print(f"Total records collected: {len(all_results)}")

Cursor-Based Pagination (Search After)

Cursor-based pagination uses an opaque next_cursor token to iterate through results sequentially. This mode is more efficient for large datasets because it avoids the performance overhead of deep page offsets.

Parameters

ParameterTypeRequiredDescription
page_sizeNumberYesNumber of records per page. Maximum: 100.
next_cursorStringYesCursor token from a previous response. Omit or set to null for the first request.
When using cursor-based pagination, the size parameter is optional and ignored. The response will return the true total_results count regardless of any size value provided.

How It Works

  1. Send your first request withnext_cursor set to null.
  2. The response includes a page object with size (number of records returned) and next_cursor.
  3. Pass the next_cursor value from the response into your next request.
  4. Repeat until next_cursor is null, which indicates you’ve reached the last page.

Example Request — First Page

curl -X POST "https://api.explorium.ai/v1/businesses" \
  -H "api_key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": {
      "country_code": { "values": ["US"] },
      "company_size": { "values": ["51-200"] }
    },
    "mode": "full",
    "page_size": 100,
    "next_cursor": null
  }'

Example Response — First Page

{
  "response_context": {
    "correlation_id": "def456",
    "request_status": "success",
    "time_took_in_seconds": 0.38
  },
  "data": [ ... ],
  "total_results": 12350,
  "page": {
    "size": 100,
    "next_cursor": "eyJzZWFyY2hfYWZ0ZXIiOiBbMTcwOTEyMzQ1Nl19"
  }
}

Example Request — Next Page

Pass the next_cursor from the previous response:
curl -X POST "https://api.explorium.ai/v1/businesses" \
  -H "api_key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": {
      "country_code": { "values": ["US"] },
      "company_size": { "values": ["51-200"] }
    },
    "mode": "full",
    "page_size": 100,
    "next_cursor": "eyJzZWFyY2hfYWZ0ZXIiOiBbMTcwOTEyMzQ1Nl19"
  }'

Example Response — Last Page

When there are no more results, next_cursor is null:
{
  "response_context": {
    "correlation_id": "ghi789",
    "request_status": "success",
    "time_took_in_seconds": 0.29
  },
  "data": [ ... ],
  "total_results": 12350,
  "page": {
    "size": 50,
    "next_cursor": null
  }
}

Full Python Example

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.explorium.ai/v1/businesses"

headers = {
    "api_key": API_KEY,
    "Content-Type": "application/json"
}

payload = {
    "filters": {
        "country_code": {"values": ["US"]},
        "company_size": {"values": ["51-200"]}
    },
    "mode": "full",
    "page_size": 100,
    "next_cursor": None
}

all_results = []
page_count = 0

while True:
    response = requests.post(BASE_URL, headers=headers, json=payload)
    data = response.json()

    all_results.extend(data["data"])
    page_count += 1

    page_info = data["page"]
    print(f"Page {page_count} — fetched {page_info['size']} records (total available: {data['total_results']})")

    if page_info["next_cursor"] is None:
        break

    payload["next_cursor"] = page_info["next_cursor"]

print(f"Total records collected: {len(all_results)}")

Response Format Comparison

The response structure differs slightly depending on which pagination mode you use.
{
  "response_context": { ... },
  "data": [ ... ],
  "total_results": 500,
  "page": 1,
  "total_pages": 5
}
FieldTypeDescription
total_resultsNumberTotal matching records (capped by size).
pageNumberCurrent page number.
total_pagesNumberTotal number of pages available.

Choosing the Right Mode

Use Offset-Based When

  • You need to jump to a specific page number.
  • Your result set is small to medium (under ~10,000 records).
  • You want to display a page selector UI (e.g., “Page 3 of 12”).
  • You need to know the total page count upfront.

Use Cursor-Based When

  • You’re iterating through all results sequentially.
  • Your result set is large (10,000+ records).
  • You want consistent performance regardless of how deep you paginate.
  • You need the true total_results count independent of the size parameter.

Best Practices

While page_size has a default, setting it explicitly (recommended: 100) ensures predictable response sizes and makes your code easier to reason about.
The last page of results will often contain fewer records than page_size. In offset mode, check page >= total_pages. In cursor mode, check next_cursor == null.
Use either page (offset-based) or next_cursor (cursor-based) in a given request — not both. If next_cursor is provided, the API uses cursor-based pagination and the page parameter is ignored.
Treat next_cursor values as opaque strings. Don’t attempt to parse, modify, or construct them. Always use the exact value returned by the API.
When paginating through results (in either mode), always send the same filters and mode parameters with each request. Changing filters mid-pagination will produce inconsistent results.
For large pagination jobs, implement retry logic with exponential backoff in case of transient errors. Save the last successful next_cursor or page number so you can resume without re-fetching.

Supported Endpoints

Both pagination modes are available on the following endpoints:
EndpointMethodPath
Fetch BusinessesPOST/v1/businesses
Fetch ProspectsPOST/v1/prospects