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"
      }
    }
    FieldMeaning
    codeA stable, machine-readable identifier. Branch on this, not on the message.
    messageA sentence for a person. The wording can change.
    request_idIdentifies this request. It is also in the X-Request-Id response header, on successes too. Quote it when you contact support.
    other fieldsDetails that depend on the code: fields, retry_after_seconds, resets_at, restricted_until.

    Codes

    StatusCodeMeaningWhat to do
    400invalid_requestA parameter is missing or has a value it does not accept. fields names each one.Fix the request.
    400invalid_cursorThe cursor does not belong to this query.Keep filters and sort the same between pages, or start again.
    400search_too_deepThe page asked for is past the nearest 500 records a geographic search lists.Narrow the search: a smaller radius, one profession, or one state.
    400invalid_idempotency_keyThe Idempotency-Key is empty or longer than 128 characters.Send a UUID.
    401unauthorizedThe API key is missing, malformed, or revoked, or its account is inactive.Check the Authorization header.
    402credit_exhaustedThe 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.
    402plan_requiredA practice account has no live plan, so nothing metered runs. Nothing ran.Start the practice plan in Billing (first month free).
    403account_restrictedThe account was restricted for unusually high volume.Wait for restricted_until, or contact support.
    403enrichment_unavailableThe person has asked not to be enriched. Nothing ran and nothing was charged.Do not retry.
    404not_foundNo record with that id, no such route, or a ZIP code that could not be located.Check the id or the ZIP code.
    409idempotency_key_reusedThe key was already used with a different request.Use a new key for a new request.
    409request_in_progressThe first request with this key is still running.Retry after Retry-After.
    410version_retiredThe path is under /v1, which was retired.Use the matching v2 resource.
    429rate_limitedToo many calls in a minute, by account or by address.Wait Retry-After seconds, then retry.
    429daily_limitThe day's call limit for this operation was reached.Resumes at midnight UTC.
    429daily_records_limitThe day's record limit was reached.Resumes at midnight UTC.
    429daily_areas_limitThe day's limit on distinct search areas was reached.Areas already searched today still work.
    429address_lockedToo many wrong API keys from this address.Fix the key, then wait Retry-After.
    500internal_errorSomething failed on our side.Retry with back-off; report the request_id if it persists.
    502provider_errorThe research provider failed. Enrichments only.Retry with back-off, with the same Idempotency-Key.
    503unavailableTemporarily 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.outcome is no_match or jurisdiction_not_indexed, and data is empty.
    • Professionals and practices: data is empty and pagination.total is 0.

    Neither is billed. Asking for one record by an id that does not exist is different: that is a 404.

    What to retry

    RetryDo not retry without changing something
    429 with a short Retry-After, 500, 502, 503, 504, and network failures400, 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.