Errors and retries
Every failed request returns the same JSON envelope, so you can branch on a stable code and build reliable error handling once.
Error envelope
Section titled “Error envelope”{ "code": "VALIDATION_ERROR", "message": "phone_number must be a valid E.164 number.", "request_id": "b3f1c8d2-2b9e-4c5e-8a1f-2c7d6a9e4b1a", "details": { "field": "phone_number" }}code: a stable, machine-readable string. Branch on this, not onmessage.message: a human-readable summary. Wording may change; do not parse it.request_id: also returned in theX-Request-Idresponse header. Quote it when you contact support.details: optional, structured context that depends on thecode.
The full list is in the errors reference.
Which errors to retry
Section titled “Which errors to retry”| Status | Retry? | Why |
|---|---|---|
400, 409, 422 | No | The request is wrong. Fix it, then resend. |
401, 403 | No | Authentication or permission issue. Check your key. |
404 | No | The resource does not exist. |
429 | Yes | Rate limited. Back off, then retry. |
500, 502, 503, 504 | Yes | Transient server-side or network issue. |
Always pair a retry of a POST with an Idempotency-Key so a retried write is never applied twice.
Recommended back-off
Section titled “Recommended back-off”Use exponential back-off with jitter, capped, with a bounded number of attempts:
async function withRetry(send, { maxAttempts = 5 } = {}) { for (let attempt = 1; ; attempt++) { const response = await send(); if (response.ok) return response;
const retriable = response.status === 429 || response.status >= 500; if (!retriable || attempt >= maxAttempts) return response;
const base = Math.min(1000 * 2 ** (attempt - 1), 30000); const jitter = Math.random() * base * 0.2; await new Promise((r) => setTimeout(r, base + jitter)); }}Start around one second, double each attempt, cap at roughly 30 seconds, and add jitter so retries from many clients do not align into a thundering herd. Give up after a handful of attempts and surface the request_id for support.
Validation errors
Section titled “Validation errors”A 400 with VALIDATION_ERROR means the request body or query is malformed. details.field points at the offending field when it can be isolated. These are never retriable: correct the payload and resend.