Errors
Errors are JSON with a stable machine-readable code. Branch on the code, never on the message.
Error shape
Every error is JSON with a stable code. Branch on code: messages are written for humans and they get rewritten. Always log request_id: it is the fastest way for support to find your exact call.
json
{
"error": {
"code": "insufficient_scope",
"message": "This token cannot send email.",
"request_id": "req_8c1d0a3f5b724e90"
}
}Status codes
| Status | When |
|---|---|
| 400 | Malformed body or a field that fails validation. |
| 401 | Missing, malformed or revoked token. |
| 402 | Insufficient balance (insufficient_balance): the wallet cannot cover the send or the reservation. Top up and retry the same request. |
| 403 | The token lacks the scope for this operation, or the send was refused: unverified sender (sender_not_verified), suppressed recipient (suppressed_recipient), SMS destination not enabled (destination_not_allowed), destination not verified while in evaluation mode (destination_not_verified), or a sender you cannot use (invalid_sender). |
| 404 | Resource does not exist, or belongs to another tenant. |
| 409 | Idempotency conflict: same key, different payload. |
| 422 | A field fails validation (validation_error). |
| 429 | Rate limit exceeded: per-token request rate, or an SMS anti-fraud ceiling (per-destination or daily spend). |
| 5xx | Ours. Retry with the same idempotency key. |