Skip to main content

Send error codes

The full list of errors of POST /api/v1/public/emails and the email read endpoints. An error comes in the standard public API format; errors in the request body also list every violation in details[].

Error format​

{
"ok": false,
"error": {
"code": "BAD_REQUEST",
"message": "The request failed validation.",
"details": [
{ "field": "to[1].email", "reason": "INVALID_EMAIL", "value": "not-an-email" },
{ "field": "subject", "reason": "REQUIRED" }
]
},
"meta": { "requestId": "01JB2W...", "timestamp": "2026-09-30T10:15:00.120Z" }
}
  • error.code — a machine-readable code; handle errors by it, not by message.
  • error.message — a description in English.
  • error.details[] — not every error has it. An item is { field?, reason, value? }:
    • field — the path to the field inside data: to[1].email, headers.Message-ID, attachments[3];
    • reason — what's wrong with the field, see reason in details[];
    • value — the field value when it's safe to return: an address — yes, attachment content — no. For MAX_LENGTH and LIMIT_EXCEEDED, value holds the allowed limit.
  • meta.requestId — give it to support if you need help with a specific request.

Body format errors are returned all at once: one 400 BAD_REQUEST error lists every violation of the request in details[], including system headers and the number of attachments. If the request has no other violations, system headers come with the 400 HEADER_NOT_ALLOWED code, and extra attachments with the 400 ATTACHMENT_COUNT_EXCEEDED code.

reason in details[]​

reasonMeaning
REQUIREDA required field is missing or empty
INVALID_TYPEWrong value type
INVALID_EMAILInvalid address
MAX_LENGTHLength exceeded; value holds the limit
LIMIT_EXCEEDEDToo many items (recipients, replyTo, attachments) or the total attachment size exceeded; value holds the limit
MUTUALLY_EXCLUSIVEFields can't be combined: html/text, templateId, templateAlias
DUPLICATE_RECIPIENTAn address repeats across to, cc, and bcc
INVALID_BASE64Attachment content isn't base64
HEADER_NOT_ALLOWEDA system header in headers
INVALID_CURSORThe sending history cursor is from other filters, another list, or corrupted — start from the first page
RECIPIENT_*A rejected recipient — in RECIPIENT_SUPPRESSED and RECIPIENT_BOUNCED errors; the codes are in Email statuses and events

Error codes​

Authorization and limits​

HTTPerror.codeCauseAction
401INVALID_API_TOKENThe token is invalid, not found, or revokedCheck or reissue the token
401ACCOUNT_BANNEDThe account is blockedContact support
403SCOPE_REQUIREDThe token lacks the required scope. message names it: email.send for sending, email.read for readingAdd the scope to the token
403PUBLIC_API_DISABLEDPublic API access is disabled for the accountContact support
429RATE_LIMIT_EXCEEDEDThe API key's request limit or the sender domain's email limit is exceeded — the latter has reason: DOMAIN_RATE_LIMIT in details, see Rate limitWait Retry-After seconds and retry with the same Idempotency-Key

Idempotency​

HTTPerror.codeCauseAction
400INVALID_IDEMPOTENCY_KEYIdempotency-Key doesn't match the formatFix the key
409IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOADThe key was already used with a different bodyRetry with the same body or use a new key
409REQUEST_ALREADY_IN_PROGRESSA request with this key is still runningWait Retry-After seconds and retry with the same key

More in Idempotency and quota.

Request body​

HTTPerror.codeCauseAction
400BAD_REQUESTBody format and limits — details in details[]Fix the fields from details[]
400HEADER_NOT_ALLOWEDA system header in headers: one details[] item per headerRemove the header; for Reply-To use the replyTo field
400ATTACHMENT_COUNT_EXCEEDEDMore than 20 attachmentsReduce the number of files
400ATTACHMENT_TOO_LARGEAttachments exceed 15 MB in totalCompress the files or link to them in the email body
400ATTACHMENT_TYPE_FORBIDDENA disallowed file type — for example, an executable; the fileName extension and the content are checkedUse another format
413PAYLOAD_TOO_LARGEThe request body is larger than 32 MBReduce attachments or put a link to the file in the email body

Sending key and domain​

HTTPerror.codeCauseAction
404SENDING_KEY_NOT_FOUNDNo key with this keyId in the account, it was deleted, or it's an SMTP keyCheck keyId; for HTTP sending, use a key for sending through the API
404SENDING_KEY_DOMAIN_NOT_FOUNDThe from.email domain isn't in the accountAdd and verify the domain or fix from.email
409SENDER_DOMAIN_BLOCKEDThe sender domain or the key's domain is blockedContact support
422SENDING_KEY_NOT_ACTIVEThe sending key — explicit or default — isn't in the enabled status: a new key is still awaiting moderation, or the key is disabled or bannedCheck the key status; pass another keyId or change the default key
422SENDING_KEY_DEFAULT_NOT_CONFIGUREDkeyId isn't passed and the sender domain has no default keyPass keyId or set a default key
422SENDING_KEY_DOMAIN_NOT_VERIFIEDThe key's domain isn't verifiedVerify the domain in the dashboard
422SENDER_DOMAIN_MISMATCHfrom.email isn't in the sending key's domainSend from an address in the key's domain or don't pass keyId

Template and content​

HTTPerror.codeCauseAction
404TEMPLATE_NOT_FOUNDNo template with this templateId or templateAlias in the accountCheck the id or alias
422TEMPLATE_SYNTAX_ERRORThe template doesn't compileFix the template
422CONTENT_SYNTAX_ERRORhtml or text doesn't compileFix the content

Recipients and quota​

HTTPerror.codeCauseAction
422RECIPIENT_SUPPRESSEDAll to recipients unsubscribed from the key's emails or complained. The email isn't sent to anyone, including cc and bccDon't retry: the response will be the same
422RECIPIENT_BOUNCEDNo to recipient can be sent the email, and at least one is rejected by the list of undeliverable addresses. The email isn't sent to anyone, including cc and bccDon't retry; remove the addresses from details[] with codes RECIPIENT_KNOWN_BOUNCED, RECIPIENT_BLOCKED, RECIPIENT_INVALID, RECIPIENT_DOMAIN_INVALID from your base
402PAYMENT_REQUIREDThe quota isn't enough for all recipients of the email; the current remaining quota is in X-Quota-RemainingWait for the next billing period or change your plan, then retry with the same Idempotency-Key

If only some recipients are rejected, the email is accepted with 202 and the rejected ones appear in recipients[] with their status — see When some recipients are rejected.

Reading emails​

HTTPerror.codeCauseAction
404EMAIL_NOT_FOUNDNo such email, it belongs to someone else, it was accepted before ДД.ММ.ГГГГ, or the id isn't a UUID; often recipients[].id was passed instead of data.idCheck that the path has data.id from the send response
404EMAIL_RECIPIENT_NOT_FOUNDThe email has no such recipientCheck recipientId
400BAD_REQUESTAn invalid sending history filter or cursor — the field is in details[].fieldFix the parameter; on INVALID_CURSOR, start from the first page
404SENDING_KEY_NOT_FOUNDThe sending history keyId filter has a key that isn't in the accountCheck keyId

Service failures​

HTTPerror.codeCauseAction
500INTERNAL_SERVER_ERRORAn unexpected errorRetry with the same Idempotency-Key
503SERVICE_UNAVAILABLEThe service is temporarily unavailableRetry with the same Idempotency-Key with increasing delays

On 5xx the email isn't sent and no quota is charged — retry the request with the same Idempotency-Key.

What to retry​

ResponseRetry?
429, 409 REQUEST_ALREADY_IN_PROGRESSYes, after Retry-After
500, 503, dropped connection, timeoutYes, with the same Idempotency-Key and increasing delays
402Yes, after changing your plan or when the next billing period starts, with the same Idempotency-Key
422 RECIPIENT_SUPPRESSED, 422 RECIPIENT_BOUNCEDNo — the response won't change
401, 403Yes, after fixing the token or the scope, with the same Idempotency-Key
Other 4xxNo — first fix the request or the account (key, domain, template); then send with a new Idempotency-Key

See also​