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.
{
"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
| Code | Status | What it means |
|---|---|---|
validation | 400 | The request is malformed. field says where. |
unauthenticated | 401 | No key, or a key that has been deleted. |
forbidden | 403 | This key may not do that: its access or its reach. |
blocked | 403 | A rule on the address refused it. Remove the rule. |
not_permitted | 403 | The address's send_policy refused it. |
not_found | 404 | No such resource — or one that is not yours. |
conflict | 409 | It already exists, or something else changed first. |
gone | 410 | It was here, and has been deleted. |
resync | 410 | Too far behind to catch up: page again from the top |
entitlement | 402 | Your plan does not include this. |
abuse_blocked | 403 | The account is paused pending review. |
rate_limited | 429 | Too many requests. See the headers below. |
unavailable | 503 | Ours, and temporary. Retry. |
internal | 500 | Ours, 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.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1757760060Reset is unix seconds. A 429 also carries Retry-After.