Pagination

When an endpoint returns a large dataset, results are split into pages. Ocean.io uses cursor-based pagination via the searchAfter parameter. Cursor-based pagination has two key advantages over offset-based pagination:
  1. No duplicate or skipped results — even if new records are added while you paginate
  2. Consistent performance — does not degrade on large datasets

How it works#

Step 1 — Make your initial request (no searchAfter needed):

curl -X POST "https://api.ocean.io/v3/search/companies" \
  -H "X-Api-Token: YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "size": 100,
    "companiesFilters": {
      "primaryLocations": { "includeCountries": ["de"] }
    }
  }'

Step 2 — The response includes a searchAfter cursor and the total result count:

{
  "total": 48203,
  "searchAfter": "eyJzb3J0IjpbMC4wMDEsImFiYzEyMyJdfQ==",
  "companies": [ ... ]
}

Step 3 — Pass the cursor in your next request to get the next page:

curl -X POST "https://api.ocean.io/v3/search/companies" \
  -H "X-Api-Token: YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "size": 100,
    "searchAfter": "eyJzb3J0IjpbMC4wMDEsImFiYzEyMyJdfQ==",
    "companiesFilters": {
      "primaryLocations": { "includeCountries": ["de"] }
    }
  }'

Step 4 — Repeat until searchAfter is absent or null in the response. That signals the last page.

Iterating all results in code#

import requests

def fetch_all_companies(filters, api_token, page_size=100):
    url = "https://api.ocean.io/v3/search/companies"
    headers = {"X-Api-Token": api_token, "Content-Type": "application/json"}
    results = []
    search_after = None

    while True:
        payload = {"size": page_size, "companiesFilters": filters}
        if search_after:
            payload["searchAfter"] = search_after

        response = requests.post(url, headers=headers, json=payload).json()
        results.extend(response["companies"])

        search_after = response.get("searchAfter")
        if not search_after:
            break

    return results
async function fetchAllCompanies(filters, apiToken, pageSize = 100) {
  const url = 'https://api.ocean.io/v3/search/companies';
  const headers = { 'X-Api-Token': apiToken, 'Content-Type': 'application/json' };
  const results = [];
  let searchAfter;

  do {
    const body = { size: pageSize, companiesFilters: filters };
    if (searchAfter) body.searchAfter = searchAfter;

    const data = await fetch(url, {
      method: 'POST',
      headers,
      body: JSON.stringify(body),
    }).then(r => r.json());

    results.push(...data.companies);
    searchAfter = data.searchAfter;
  } while (searchAfter);

  return results;
}

Page size limits#

Use the size parameter to control how many results are returned per page:

Endpoint Min Max
Search Companies 1 10,000
Search People 1 10,000
Lookup Companies 1 1,000
Lookup People 1 1,000

Pagination with peoplePerCompany

searchAfter works together with peoplePerCompany in Search People. The cursor is an offset into the per-company result set rather than a sort position, so keep peoplePerCompany and your filters unchanged across pages.

In this mode total is capped at 10,000 and the response keeps returning a cursor past the last page. Stop when a page comes back with an empty people array instead of waiting for searchAfter to disappear.