Errors

The error envelope, every error code the API returns, and what each one means.

A refused request answers with an HTTP status and a JSON envelope. The envelope carries a stable code and a sentence for people. Branch on the code. Show or log the message.

The error envelope

{
  "error": {
    "code": "SCOPE_DENIED",
    "message": "This API key can only send email."
  }
}

Some refusals add fields beside error. A RISK_REFUSED answer carries the risk reasons, and an APPROVAL_REQUIRED answer carries the draft card and an approvalId. A refusal that tells you to wait also sends a Retry-After header in seconds.

Error codes

StatusCodeMeaning
400BAD_REQUESTThe request is invalid. The message names the field.
401UNAUTHORIZEDThe API key is missing or not valid.
402INSUFFICIENT_BALANCEThe wallet cannot cover an SMS or SMS code. Nothing was sent.
403FORBIDDENThe call is not allowed for this team or key, for example a key's approval policy that only saves drafts.
403SCOPE_DENIEDThe key's permission (full, sending or read only) does not reach this call.
403KEY_PAUSEDThe key is paused by the account owner. Nothing runs until it is resumed.
403FORBIDDEN, details.reason DOMAIN_BULK_NOT_READYA broadcast, automation or MARKETING send from a new domain whose DNS is not finished. The message names the record to fix. Transactional email still sends.
403DOMAIN_PINNEDThe key is restricted to one domain, and this call is not tied to it.
404NOT_FOUNDNothing with that id belongs to the key's team.
405METHOD_NOT_ALLOWEDThe path exists, but not with this HTTP method.
409NOT_UNIQUEAn idempotency key was reused with a different body, or is still in flight.
409CONFLICTThe thing changed under you, for example a broadcast that is no longer a draft. Nothing was written.
409NOT_IN_SEGMENTThe automation is limited to a segment, and the contact does not match it.
409APPROVAL_REQUIREDThe key's approval policy needs a person's yes for a broadcast this large. The body carries the draft card and an approvalId. Nothing was sent.
409PARTIAL_COMPLETIONAn earlier request with this idempotency key stopped part way. The body lists the email ids it sent. Nothing was sent again.
422UNPROCESSABLE_ENTITYWell formed but not processable, such as more than 50 recipients.
422RISK_REFUSEDRisk scoring refused a one-time code or SMS. The body carries the reasons.
429RATE_LIMITEDThe per second rate limit or a send limit was reached.
429RATE_LIMITED, details.reason DOMAIN_WARMUP_LIMITThe domain is warming up or on probation and has used today's limit. See Warm-up.
429RATE_LIMITED, details.reason SCHEDULED_BACKLOG_LIMITYou already have 7 days of your daily limit scheduled for later. Wait for some to send, or cancel some, then schedule more.
429LIMIT_EXCEEDEDA limit the owner set on this key (requests per minute, daily or monthly sends, SMS per day) was reached.
500INTERNAL_SERVER_ERRORSomething went wrong on our side. Retry with backoff.
503SERVICE_UNAVAILABLEA dependency is briefly unavailable. Retry with backoff.

Validation errors

A request body that fails validation answers 400 with the validation issues. Each issue names the field path and what was wrong.

Which errors to retry

  • Retry transport errors, 429, 500 and 503 with backoff. On a 429, wait for Retry-After first.
  • Do not retry other 4xx answers as they are. Fix the request first.
  • Send an Idempotency-Key on sends, so a retry never sends twice. See Idempotency.
Open in ClaudeOpen in ChatGPT