Search the docs

Find a page, a section, or an endpoint.

Errors

One envelope, one code, and what each means.

A failure is always the same shape, with an HTTP status that means the same thing as the code inside it.

json
{
"error": {
  "code": "validation",
  "message": "Enter only the part before the @.",
  "field": "local_part"
}
}

message is written for a person and is safe to show one. It never carries a stack, a DNS response code or a provider's wording — if you are surfacing API errors in your own interface, this is the string to use.

The codes

CodeStatusWhat it means
validation400The request is malformed. field says where.
unauthenticated401No key, or a key that has been deleted.
forbidden403This key may not do that: its access or its reach.
blocked403A rule on the address refused it. Remove the rule.
not_permitted403The address's send_policy refused it.
not_found404No such resource — or one that is not yours.
conflict409It already exists, or something else changed first.
gone410It was here, and has been deleted.
resync410Too far behind to catch up: page again from the top
entitlement402Your plan does not include this.
abuse_blocked403The account is paused pending review.
rate_limited429Too many requests. See the headers below.
unavailable503Ours, and temporary. Retry.
internal500Ours, and unexpected.

forbidden and not_found deliberately return the same sentence. Confirming that a resource exists but belongs to somebody else is itself a leak, so the API does not.

gone is the one place we do distinguish existed from never existed, and it is scoped so that the distinction tells you nothing you did not already have: you get 410 only for something deleted from a resource you can already read. Asked about somebody else's, it is a 404 like anything else. It is answered for as long as the event log remembers the deletion; after that the honest answer is 404 again, because we no longer know.

Rate limit headers

Every successful response carries them, so a client can pace itself rather than discover the limit by hitting it.

http
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1757760060

Reset is unix seconds. A 429 also carries Retry-After.