Using the API
Errors
One error shape, standard status codes, and a stable code for every failure.
The error object
Every error from /v2 has the same shape:
json
{
"error": {
"code": "invalid_request",
"message": "sort must be one of: distance, years_licensed, -years_licensed, name",
"fields": [{ "field": "sort", "message": "sort must be one of: distance, years_licensed, -years_licensed, name" }],
"request_id": "req_5f0c1e7a9b2d4c6e8a1b3d5f"
}
}| Field | Meaning |
|---|---|
code | A stable, machine-readable identifier. Branch on this, not on the message. |
message | A sentence for a person. The wording can change. |
request_id | Identifies this request. It is also in the X-Request-Id response header, on successes too. Quote it when you contact support. |
| other fields | Details that depend on the code: fields, retry_after_seconds, resets_at, restricted_until. |
Codes
| Status | Code | Meaning | What to do |
|---|---|---|---|
400 | invalid_request | A parameter is missing or has a value it does not accept. fields names each one. | Fix the request. |
400 | invalid_cursor | The cursor does not belong to this query. | Keep filters and sort the same between pages, or start again. |
400 | search_too_deep | The page asked for is past the nearest 500 records a geographic search lists. | Narrow the search: a smaller radius, one profession, or one state. |
400 | invalid_idempotency_key | The Idempotency-Key is empty or longer than 128 characters. | Send a UUID. |
401 | unauthorized | The API key is missing, malformed, or revoked, or its account is inactive. | Check the Authorization header. |
402 | credit_exhausted | The team's credit cannot cover the request. Nothing ran. | Top up in Billing, or turn on automatic top-ups. For a practice on the plan, resets_at is when next month's plan credit arrives; otherwise it is null. |
402 | plan_required | A practice account has no live plan, so nothing metered runs. Nothing ran. | Start the practice plan in Billing (first month free). |
403 | account_restricted | The account was restricted for unusually high volume. | Wait for restricted_until, or contact support. |
403 | enrichment_unavailable | The person has asked not to be enriched. Nothing ran and nothing was charged. | Do not retry. |
404 | not_found | No record with that id, no such route, or a ZIP code that could not be located. | Check the id or the ZIP code. |
409 | idempotency_key_reused | The key was already used with a different request. | Use a new key for a new request. |
409 | request_in_progress | The first request with this key is still running. | Retry after Retry-After. |
410 | version_retired | The path is under /v1, which was retired. | Use the matching v2 resource. |
429 | rate_limited | Too many calls in a minute, by account or by address. | Wait Retry-After seconds, then retry. |
429 | daily_limit | The day's call limit for this operation was reached. | Resumes at midnight UTC. |
429 | daily_records_limit | The day's record limit was reached. | Resumes at midnight UTC. |
429 | daily_areas_limit | The day's limit on distinct search areas was reached. | Areas already searched today still work. |
429 | address_locked | Too many wrong API keys from this address. | Fix the key, then wait Retry-After. |
500 | internal_error | Something failed on our side. | Retry with back-off; report the request_id if it persists. |
502 | provider_error | The research provider failed. Enrichments only. | Retry with back-off, with the same Idempotency-Key. |
503 | unavailable | Temporarily unavailable. | Retry later. |
A miss is not an error
A search that finds nothing answers 200, because "no license on record" is an answer. Branch on the body:
- Licenses:
meta.outcomeisno_matchorjurisdiction_not_indexed, anddatais empty. - Professionals and practices:
datais empty andpagination.totalis0.
Neither is billed. Asking for one record by an id that does not exist is different: that is a 404.
What to retry
| Retry | Do not retry without changing something |
|---|---|
429 with a short Retry-After, 500, 502, 503, 504, and network failures | 400, 401, 402, 403, 404, 409 idempotency_key_reused, and a 429 whose Retry-After is hours away |
How to wait between tries is in Rate limits and retries.