Skip to main content

The error envelope

Every non-2xx response has the same shape — a single error object:
Branch on code — it is stable and machine-readable. Never match on message: it is human-facing text that may change without notice.
Some errors add context fields: balance on credit errors, limit on concurrency errors.

Codes

Handling errors

Python

Concurrency and rate limits

There is no per-second request limit on reads. The one throttle is job concurrency: how many jobs may be in flight (submitted but not yet done) at once. It’s set by your plan — free plans run one at a time. Over the limit, POST /v1/jobs returns:
Your live limit is the concurrency_limit field in GET /v1/account. Poll your in-flight jobs to completion, then submit the next — or move to a plan with a higher limit.
Re-polling a finished job is always free and never counts against your limit, so a lost response never needs a new job.

Terminal job states

Some outcomes are successful HTTP responses with a terminal job status, not error envelopes. In particular, a non-premium search above the company-size gate returns 200 with { "status": "too_large", "message": "…" }; it starts no pipeline work and costs nothing. not_found, no_employees, no_people_found, too_large, failed, and cancelled are terminal statuses to handle from the poll result. They carry numeric credits_charged: 0.