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.
| Field | Meaning |
|---|---|
error.code | Stable error identifier from the tables below. |
error.message | Explanation for troubleshooting; do not use its exact text as a programmatic identifier. |
error.retryable | Whether this failure allows another attempt later. Check error.acceptance as well: a POST with pending or unknown is not marked retryable. |
error.request_id | Identifier for this HTTP request. Include it when reporting a problem. |
error.acceptance | Submission outcome: not_accepted, pending, or unknown. Present on submission errors; omitted on health and unmatched-route errors. |
error.details | Optional 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
| Value | Meaning |
|---|---|
not_accepted | This POST is known not to have reached acceptance. |
pending | This POST has not reached a final result. |
unknown | The 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
| HTTP | Code | Meaning and action |
|---|---|---|
400 | invalid_json | The body is missing, malformed JSON, or invalid UTF-8. Send a valid UTF-8 JSON object. |
401 | missing_api_key | Supply Authorization: Bearer YOUR_API_KEY, replacing YOUR_API_KEY with your full workspace key. |
401 | invalid_api_key | The 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. |
404 | not_found | The route or message is unavailable. Check the path and message ID. Missing messages and messages outside the authenticated workspace return the same code. |
405 | method_not_allowed | Use the method in the Allow header: POST for sending and GET for health. |
408 | request_timeout | Reading 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. |
413 | message_too_large | The 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. |
415 | unsupported_media_type | Send 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
| HTTP | Code | Meaning and action |
|---|---|---|
403 | sender_not_allowed | The 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. |
403 | sending_disabled | Sending is disabled for the workspace or domain. Ask your administrator to check both sending permissions. |
403 | domain_not_verified | The exact sender domain exists in the workspace but is not verified (or is paused). Complete verification and try again; nothing was queued. |
403 | sender_not_ready | The 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. |
403 | account_suspended | An 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. |
402 | insufficient_credits | This 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.
| Code | Meaning and action |
|---|---|
missing_required_field | Supply a sender, at least one to recipient, a nonblank subject, and nonblank text or html. |
invalid_parameter | A 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_recipient | A to, cc, or bcc mailbox is malformed. Each string must contain one mailbox; use an array for multiple recipients. |
unsupported_address | The mailbox uses non-ASCII characters before @. International domain names and Unicode display names are supported, but the local part must be ASCII. |
too_many_recipients | More than 100 entries were supplied across to, cc, and bcc. The input limit applies before duplicates are removed. |
invalid_attachment | An 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_parameter | An 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_available | A 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
| HTTP | Code | Meaning and action |
|---|---|---|
429 | rate_limit_exceeded | The 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. |
429 | daily_limit_exceeded | Accepting 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. |
429 | monthly_limit_exceeded | Accepting 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. |
503 | service_unavailable | The 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.
- API Overview — preview availability and supported operations.
- Authentication — key setup and access requirements.
- Send Email — examples, fields, and successful submission responses.
- Submission Outcomes — interpret responses and handle uncertain acceptance.
- Rate Limits & Retries — counters, independent submissions, and uncertain-outcome handling.