Content-Type: application/problem+json and a non-2xx HTTP status. The body always
includes a machine-readable code so you can branch on the failure without parsing prose.
Error envelope
string
A URI identifying the error type. Points at the docs section for the code.
string
A short, human-readable summary of the error type (e.g.
Out of credits).number
The HTTP status code, repeated in the body.
string
The stable, machine-readable error code. Branch on this. See the table below.
string
A human-readable explanation specific to this occurrence. For
invalid_request it carries
the validation message(s).number | null
Present on
out_of_credits — your current balance, so you can tell the user how short they
are.Example: out_of_credits
Error codes
rate_limited and quota_exceeded both use HTTP 429 and both send a Retry-After
header. Distinguish them by the code field, not the status. See Rate limits.Handling guidance
4xx — your request needs a change
4xx — your request needs a change
invalid_request, invalid_key, forbidden_scope, not_found, link_removed, and
unsupported_link won’t succeed on retry. Surface them to the caller / logs and fix the
input, key, scope, or URL. For unsupported_link, validate against
/v1/providers before resolving.402 — out of credits
402 — out of credits
Stop resolving and prompt a top-up. The
balance field tells you how much is left. Top
up in the dashboard. Nothing was charged.429 — slow down
429 — slow down
Honor the
Retry-After header (seconds) before retrying. For quota_exceeded, the
window resets at UTC midnight — back off until then rather than hammering. See
Rate limits.5xx — transient, retry with backoff
5xx — transient, retry with backoff
provider_down (503) and many resolve_failed (502) cases are temporary. Retry with
exponential backoff and a cap on attempts. If a queued job ends failed, the resolver
genuinely couldn’t get through — don’t retry indefinitely.Charging on errors
A request is only charged when it produces a resolved destination. Errors — includingout_of_credits, unsupported_link, link_removed, provider_down, and resolve_failed
— do not spend credits. Cached resolves also cost 0. See How it works.
Mapping in the SDKs
Both SDKs raise a typed exception per code, all subclasses of the base API error, so you cancatch precisely or broadly.
