Errors and rate limits
When a v2 request fails, the response body is a JSON object with one shared shape:
{
"name": "BAD_REQUEST",
"message": "\"rcpt\" must be a valid email",
"status": 400
}
name- a stable, machine-readable error identifier (BAD_REQUEST,NOT_FOUND,PAYMENT_REQUIRED,TOO_MANY_REQUESTS, …). Branch on this or on the HTTP status code in your integration.message- a human-readable explanation; validation failures name the offending field. Treat it as diagnostic text for your logs, not something to parse.status- the HTTP status code, repeated in the body.
Some errors carry an additional errors array with structured details; it is empty or absent for most.
The one exception: a failed authentication (
401from a missing or invalid token, or a token without access to the account) is not JSON - it gets the plain-text bodyUnauthorized. Endpoint-specific401s, like a failed SMTP credential check when saving a mail server, use the JSON shape.
Common status codes
| Status | Meaning |
|---|---|
400 | The request body or parameters failed validation. The message names the offending field. |
401 | The token is missing or invalid, or it is not authorized for the requested account or user. |
402 | The account is over its plan’s send limit. Sending resumes when the limit resets or the plan is upgraded. |
404 | The requested resource does not exist in this account. |
429 | Too many requests - see rate limits below. |
Each endpoint reference page lists the statuses that endpoint can return.
Rate limits
Endpoints whose abuse would send unwanted email are actively limited: inviting a user rejects re-inviting the same address within 24 hours and caps how many invitations an account can start per day, answering both with 429. Busy endpoints - the various /stats aggregations and contact /search - may also be rate limited, and abusive traffic can be throttled platform-wide.
Build your integration to treat 429 as a signal to back off and retry with an increasing delay. As a rule of thumb: cache aggregation results instead of polling them, and batch your reads with pagination rather than issuing one request per record.