Pagination & Sorting
How do I paginate through results?
Paginate through results by starting with page=0, requesting a supported page_size, and incrementing page until meta.has_more is false. All list endpoints use this offset-based pagination contract:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 0 | Page number (0-indexed) |
page_size | integer | 25 | Results per page (max 500). Sandbox/test keys are capped at 100. Over-max -> 400. |
GET /v1/companies?states=CA&page=0&page_size=25
GET /v1/companies?states=CA&page=1&page_size=25 # next pagepage_size > 25 must include at least one business filter, such as states, employee_bands, industries, or signals. An unfiltered request such as ?page_size=100 returns 400 FILTER_REQUIRED.Response meta tells you if there's more:
"meta": {
"total_count": 1523,
"page": 0,
"page_size": 25,
"returned": 25,
"has_more": true
}meta.total_count may be omitted with meta.count_pending: true while the count query computes in the background. Re-running the same query a second later usually returns the populated count from cache. If you need a count up-front and can't wait, prefer the explicit ?count_only=true endpoint shape — it always returns a synchronous count.include_count and has_more
Default: include_count=true — the response includes meta.total_count.
When include_count=false:
meta.total_countis omitted.- The backend internally fetches
page_size + 1rows; the (n+1)-th row is used only to setmeta.has_more. It is not returned indata. - This is materially faster than running a separate
COUNT(*)query, and is the recommended pattern for any pagination loop.
- Optionally call once with
count_only=true(0 credits) to size the segment. - Call once with
dry_run=true(0 credits) to confirm credit cost before committing. - Loop
page=0, 1, 2, ...withinclude_count=false, stopping whenmeta.has_more === false.
Count-only mode: Use count_only=true to get just the count without any data rows. Costs 0 credits.
Sorting
| Parameter | Type | Default | Description |
|---|---|---|---|
sort_by | string | Entity name field | Column to sort by — must be on the entity's allowlist (below) |
sort_dir | asc | desc | asc | Sort direction |
GET /v1/companies?states=CA&sort_by=total_premiums&sort_dir=descSorting is restricted to a per-entity allowlist of indexed, valuable columns. Requesting a non-allowlisted column returns 400 VALIDATION_ERROR with the allowlist in expected.
Sort allowlists
| Entity | Default | Allowlisted columns |
|---|---|---|
| Companies | company_name ASC | company_name, total_premiums, total_number_of_employees, participants, participant_growth, filing_year |
| Personnel | last_name ASC | last_name, company_name, total_number_of_employees |
| Broker Offices | office_name ASC | office_name, client_count, total_commissions, total_premiums |
| Brokers | broker_name ASC | broker_name, total_clients, total_offices, total_commissions |
filing_year, total_premiums, participants, participant_growth, client_count, total_commissions, Personnel total_number_of_employees) are advanced-tier fields. Basic-tier keys requesting them as sort_by get 403 FORBIDDEN.Stable pagination
Every sort uses ORDER BY <sort_field> <sort_dir>, id ASC — the requested column follows user direction, and id is always ascending as the stable tiebreaker. Tied rows always order the same way across requests, so offset pagination is deterministic.
Until stable per-entity IDs land for personnel, broker offices, and brokers, sorting by a non-unique column may cause rows with tied values to shift across pages between requests. Mitigation: prefer high-cardinality sort columns (company_name, last_name, total_premiums) over low-cardinality ones (filing_year, seniority).
id(or the resource's documented natural identifier) before writing or billing downstream.Keys are issued by our team, not a signup form. Book a 25-minute walkthrough and you'll leave with sandbox and live credentials.