Errors
Every error response carries a stable code for programmatic handling, plus a human-readable message and the originating requestId.
Error response shape
error envelope
{
"success": false,
"code": "BAD_REQUEST",
"message": "Field 'from' is required",
"requestId": "fd067654-..."
}
Codes
| Code | HTTP | Meaning |
BAD_REQUEST | 400 | Zod validation failed or invalid input shape. |
UNAUTHORIZED | 401 | Missing or invalid API key. |
FORBIDDEN | 403 | Key lacks required scope. |
NOT_FOUND | 404 | Resource doesn't exist. |
CONFLICT | 409 | Idempotency conflict or duplicate resource (e.g. stream name). |
RATE_LIMITED | 429 | Per-tenant rate limit exceeded. Retry-After header set. |
UPSTREAM_FAILED | 502 | SES, SNS, or downstream service failure. |
INTERNAL | 500 | Unexpected — check requestId against logs. |
Retrying
- 4xx — don't retry. The error is your fault and won't change.
- 429 — back off using the
Retry-After header value (seconds).
- 502 / 503 — retry with exponential backoff. Mailgrid's idempotency layer ensures no duplicate sends.
- 500 — retry once; if it persists, contact support with the
requestId.
SES-specific failures
| SES message | Likely cause |
SignatureDoesNotMatch | AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY wrong, or AWS_REGION doesn't match the verified identity's region. |
MessageRejected: From address not verified | Sender domain isn't verified in SES, or you're in the sandbox and the recipient isn't verified. |
Account in sandbox | Request production access in the SES console (~24h approval). |
FromAddress denied | IAM policy restricts ses:FromAddress to specific domains. Update the policy. |