Errors

Errors come back as JSON with a consistent shape, so one handler covers all of them. What differs is whether the error is worth retrying — that is the distinction to build around.

The error shape

Every failure returns the same four fields:

  • Name
    statusCode
    Type
    integer
    Description

    The HTTP status code, repeated in the body.

  • Name
    error
    Type
    string
    Description

    A short, stable label for the error class, e.g. Unauthorized Request.

  • Name
    message
    Type
    string
    Description

    A human-readable description. This is the field that tells you which specific thing went wrong.

  • Name
    validation
    Type
    object
    Description

    Per-field validation detail when the request body was rejected. Empty for errors that are not about field validity.

Error response

{
  "statusCode": 401,
  "error": "Unauthorized Request",
  "message": "x-api-key must be valid",
  "validation": {}
}

Branch on statusCode for how to react, and read message for what to log or surface. error is the stable machine-readable label; message is more specific but more likely to be reworded over time, so avoid matching on its exact text.


Status codes

  • Name
    200
    Description

    Success. Note that a successful response can still contain zero matches — an empty result set is not an error.

  • Name
    400
    Description

    The request body was invalid. Check validation for the offending fields. Commonly a malformed address, a ZIP that is not five digits, or a missing geo field on a search.

  • Name
    401
    Description

    The API key was missing, malformed, or revoked. See Authentication.

  • Name
    429
    Description

    A rate limit was exceeded. See Rate limits — whether to retry depends on which limit you hit.

  • Name
    5xx
    Description

    A server-side error. Safe to retry with backoff.


What to retry

Retrying the wrong error wastes credits and can extend an outage. The rule of thumb:

StatusRetry?Why
400NoThe body is wrong. Retrying sends the same wrong body.
401NoThe key is wrong. Fix the credential.
429 per-secondYesBack off with jitter; capacity returns in seconds.
429 daily ceilingNoNothing frees up until the UTC window rolls over. Queue for the next window.
5xxYesTransient. Exponential backoff.

Both 429 cases share a status code, so distinguish them by message — a daily ceiling names the exhausted scopes, e.g. Daily usage limit exceeded for [PropertySearch, SkipTrace] scopes.

No match versus error

Worth stating plainly, because it is a common source of bad error handling: an address that does not resolve to a property is not an error. You get a 200 with no data. Code that treats "empty" as "failed" will retry lookups that are never going to succeed.

Property Detail in particular has its own documented failure modes around ambiguous and unmatched addresses — see Error handling for Property Detail.

Was this page helpful?