Hillwinds API
Core Concepts

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:

ParameterTypeDefaultDescription
pageinteger0Page number (0-indexed)
page_sizeinteger25Results per page (max 500). Sandbox/test keys are capped at 100. Over-max -> 400.
bash
GET /v1/companies?states=CA&page=0&page_size=25
GET /v1/companies?states=CA&page=1&page_size=25   # next page
A filter is required above 25 rows
Requests with page_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:

json
"meta": {
  "total_count": 1523,
  "page": 0,
  "page_size": 25,
  "returned": 25,
  "has_more": true
}
count_pending: true on first call
On the first request for a new filter combination, 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_count is omitted.
  • The backend internally fetches page_size + 1 rows; the (n+1)-th row is used only to set meta.has_more. It is not returned in data.
  • This is materially faster than running a separate COUNT(*) query, and is the recommended pattern for any pagination loop.
Recommended pagination flow
  1. Optionally call once with count_only=true (0 credits) to size the segment.
  2. Call once with dry_run=true (0 credits) to confirm credit cost before committing.
  3. Loop page=0, 1, 2, ... with include_count=false, stopping when meta.has_more === false.

Count-only mode: Use count_only=true to get just the count without any data rows. Costs 0 credits.

Sorting

ParameterTypeDefaultDescription
sort_bystringEntity name fieldColumn to sort by — must be on the entity's allowlist (below)
sort_dirasc | descascSort direction
bash
GET /v1/companies?states=CA&sort_by=total_premiums&sort_dir=desc

Sorting 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

EntityDefaultAllowlisted columns
Companiescompany_name ASCcompany_name, total_premiums, total_number_of_employees, participants, participant_growth, filing_year
Personnellast_name ASClast_name, company_name, total_number_of_employees
Broker Officesoffice_name ASCoffice_name, client_count, total_commissions, total_premiums
Brokersbroker_name ASCbroker_name, total_clients, total_offices, total_commissions
Tier-gated sort columns
Some allowlisted columns (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).

Deduplicate across pages
Offset pagination does not provide a snapshot of a changing dataset. Rows can move while you paginate, and some resource IDs are not yet stable enough to serve as a universal pagination key. Consumers should deduplicate collected rows by the returned id(or the resource's documented natural identifier) before writing or billing downstream.
Need a key?

Keys are issued by our team, not a signup form. Book a 25-minute walkthrough and you'll leave with sandbox and live credentials.