Skip to content

Errors

Every failure carries a stable machine-readable type and a message worth putting in a log.

Shape

{
  "error": {
    "type": "invalid_parameter",
    "message": "Unknown parameter: stat. Supported: procedure, limit."
  }
}

Branch on type, never on message. Messages are written for humans and will be reworded; types are part of the contract and will not change without a version bump.

Types

TypeStatusMeaning
missing_parameter400A required parameter was absent. The message names it.
invalid_parameter400A parameter was unrecognised or malformed. Unknown parameters are rejected rather than ignored, so a typo fails loudly instead of silently returning the wrong rows.
unauthorized401The key is missing, malformed, or revoked.
not_found404The resource exists as a concept but has no data for these arguments.
rate_limit_exceeded429Too many requests. Back off until the time in X-RateLimit-Reset. This is also what you get at your monthly ceiling — we stop rather than bill an overage.
internal_error500Our fault. Safe to retry with backoff.

Which are worth retrying

  • 429 and 500 — retry with backoff
    Transient. The same request will likely succeed later.
  • 400 and 401 — do not retry
    The request is wrong, or the key is. Retrying burns quota and changes nothing. Fix the caller.
  • 404 — depends
    The endpoint is valid but has no data for those arguments. Retrying helps only if you expect the data to land later.