Skip to main content

Error Codes

The SendMero email API returns a lowercase machine-readable error.code and an HTTP status. Use these fields in application logic; human-readable messages may change.

This reference covers the implemented JSON submission endpoint. Sending over SMTP returns reply codes instead; see SMTP. The public endpoint and integrated email delivery have not been released; see the API overview for preview availability and setup.

Error response format​

An invalid recipient on a submission returns HTTP 422, for example:

{
"error": {
"code": "invalid_recipient",
"message": "The message contains a missing, invalid, or unsupported field.",
"retryable": false,
"request_id": "req_00000000000000000000000000000001",
"acceptance": "not_accepted",
"details": [
{
"field": "to[0]",
"code": "invalid_recipient"
}
]
}
}

The request ID is inside error, and matches the X-Request-Id response header. The HTTP status is returned as the HTTP status, not as a property in this JSON object.

FieldMeaning
error.codeStable error identifier from the tables below.
error.messageExplanation for troubleshooting; do not use its exact text as a programmatic identifier.
error.retryableWhether this failure allows another attempt later. Check error.acceptance as well: a POST with pending or unknown is not marked retryable.
error.request_idIdentifier for this HTTP request. Include it when reporting a problem.
error.acceptanceSubmission outcome: not_accepted, pending, or unknown. Present on submission errors; omitted on health and unmatched-route errors.
error.detailsOptional field locations and codes. For example, to[0] or attachments[0].content; rejected field values are not included.

A message-validation error rejects the whole current message request; it is not a partial-success result for individual recipients. Successful recipient statuses describe submission acceptance or test validation, not delivery failures.

All API responses include X-Request-Id and Cache-Control: no-store. Authentication errors include WWW-Authenticate: Bearer; method errors include Allow. Retryable rate and service errors include Retry-After where described below. POST errors with pending or unknown omit it. Exact remaining/reset rate counters are not currently returned on errors.

Understand the acceptance outcome​

ValueMeaning
not_acceptedThis POST is known not to have reached acceptance.
pendingThis POST has not reached a final result.
unknownThe service cannot determine whether this POST was accepted.

Each POST is independent. Errors before queue publication, including request-header, authentication, rate, and body-validation failures, describe the current request as not_accepted. An error from a later request does not cancel or reveal the result of an earlier email.

For pending or unknown, the API returns retryable: false and omits Retry-After. Do not automatically POST again; it can create another email. Retain any message ID and the request ID, and contact your administrator for investigation. There is no status lookup or recovery endpoint; see Submission Outcomes.

A network failure or unusable response is also uncertain: the API may already have queued the email. See Rate Limits & Retries for the decision rules before submitting again.

Request and authentication errors​

HTTPCodeMeaning and action
400invalid_jsonThe body is missing, malformed JSON, or invalid UTF-8. Send a valid UTF-8 JSON object.
401missing_api_keySupply Authorization: Bearer YOUR_API_KEY, replacing YOUR_API_KEY with your full workspace key.
401invalid_api_keyThe key is malformed, unknown, expired, revoked, or otherwise invalid. Use the complete dashboard-issued key for the intended workspace and confirm its current configuration is active on the endpoint. Dashboard login tokens cannot authorize this API.
404not_foundThe route or message is unavailable. Check the path and message ID. Missing messages and messages outside the authenticated workspace return the same code.
405method_not_allowedUse the method in the Allow header: POST for sending and GET for health.
408request_timeoutReading the request body exceeded the 15-second deadline. With not_accepted, this error permits another attempt after checking connectivity and body size. It may have no Retry-After header.
413message_too_largeThe encoded JSON body exceeds 1,000,000 UTF-8 bytes, or the submission's metadata exceeds the supported size. Reduce the payload; Base64 and JSON escaping count toward the limit. Do not retry the unchanged oversized request.
415unsupported_media_typeSend Content-Type: application/json and an uncompressed body. Omit Content-Encoding or use identity.

The Authentication reference explains key setup and workspace scope. The Send Email reference describes supported request headers.

Sender permissions and readiness​

HTTPCodeMeaning and action
403sender_not_allowedThe exact from domain is not set up in the key's workspace. Use a configured sender domain; a parent-domain configuration does not automatically authorize subdomains, and a subdomain does not authorize its parent. Nothing was queued.
403sending_disabledSending is disabled for the workspace or domain. Ask your administrator to check both sending permissions.
403domain_not_verifiedThe exact sender domain exists in the workspace but is not verified (or is paused). Complete verification and try again; nothing was queued.
403sender_not_readyThe domain is verified but cannot send right now (for example, the pool it sends from is not available). Nothing was queued. Contact support if it persists.
403account_suspendedAn invoice has been unpaid for more than 7 days, so new messages are paused. Update your card or pay the invoice on the Billing page and sending resumes. Messages already accepted are still sent. Nothing was queued.
402insufficient_creditsThis message would use more email credits than your workspace has. Recipients beyond your monthly allowance cost one credit each. Top up credits on the Billing page and send again; nothing was queued or charged. Retrying without topping up will fail again.

A valid API key alone is insufficient to submit from an arbitrary domain. Test mode performs the same sender-permission, verification, and readiness checks as a new production submission.

Message validation errors​

Each of these errors returns HTTP 422 and is not marked retryable. Use error.details, when present, to locate the field. Correct the cause. The rejection describes this request only; investigate any earlier uncertain POST separately.

CodeMeaning and action
missing_required_fieldSupply a sender, at least one to recipient, a nonblank subject, and nonblank text or html.
invalid_parameterA field has the wrong type, exceeds its limit, contains unsafe characters, or violates its supported format. This includes invalid sender/reply-to syntax, subject limits, options, tags, metadata, and custom headers.
invalid_recipientA to, cc, or bcc mailbox is malformed. Each string must contain one mailbox; use an array for multiple recipients.
unsupported_addressThe mailbox uses non-ASCII characters before @. International domain names and Unicode display names are supported, but the local part must be ASCII.
too_many_recipientsMore than 100 entries were supplied across to, cc, and bcc. The input limit applies before duplicates are removed.
invalid_attachmentAn attachment is missing a required field, has an invalid filename, Base64 body, media type or inline content ID, or exceeds the 20-attachment count. Use standard canonical Base64 without whitespace or a data-URL prefix.
unsupported_parameterAn unknown field was supplied, including misspellings, provider-specific parameters, or client-supplied workspace, pool, and routing identities. Unknown nested fields are also rejected.
feature_not_availableA recognized but unavailable feature was requested, such as the raw MIME route. Use the documented JSON contract and omit unavailable features.

All option values must be actual booleans. For example, "test_mode": "true" is invalid; "test_mode": true is supported. Unknown fields are not silently ignored. See Send Email — Request body for every supported field and limit.

Limits and service availability​

HTTPCodeMeaning and action
429rate_limit_exceededThe workspace's rolling request limit or additional traffic protection rejected the request. This error is retryable. Coordinate all clients using the workspace, slow down, and wait at least the returned Retry-After.
429daily_limit_exceededAccepting this message would take the workspace past its daily recipient limit or cap (UTC day). The whole request is refused and nothing is queued. Retry-After is the number of seconds until 00:00 UTC.
429monthly_limit_exceededAccepting this message would take the workspace past its monthly recipient limit or cap (UTC month). The whole request is refused and nothing is queued. Retry-After is the number of seconds until 00:00 UTC on the 1st.
503service_unavailableThe endpoint is disabled, current authorization configuration is unavailable, or submission processing could not be confirmed. For not_accepted with retryable: true, follow Retry-After. For pending or unknown, retryable is false and Retry-After is absent: retain any message/request IDs and contact your administrator instead of automatically posting again.

The normal request limit is 1,000 requests per 10 seconds per workspace (100/second on average), shared across API keys in each Cloudflare location. This approximate window permits bursts. Read the limits guide for request counting and retry guidance.

Do not assume every 4xx is permanent: 408 and both documented 429 codes permit another attempt when the current request is not_accepted. A response from one request cannot establish whether an earlier request succeeded.

Removed status lookup​

The former GET /v1/messages/{id} route is unavailable and returns 404 not_found. That response does not establish whether a previous submission was accepted. Delivery failure, bounce, open, and click codes are not reported by this preview.

See Submission Outcomes for interpreting POST results and handling uncertainty. Submission acceptance does not establish inbox delivery.

Reporting a problem​

Record the HTTP status, error.code, error.request_id, error.acceptance when present, and Retry-After. If you have a message ID, retain it with the original logical operation. Do not include API keys, message bodies, attachments, or recipient lists in logs or support screenshots.