Errors & limits
Every error is JSON with a stable error code and the matching HTTP status. No stack traces, no surprises.
{ "error": "validation_failed", "detail": { "code": "no_body" } }Status codes
| Status | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or unknown API key. |
422 | validation_failed | The payload is malformed — detail.code says which rule failed (no_body, invalid_recipient, …). |
429 | rate_limit_exceeded | Too many requests this minute for your tenant. |
429 | quota_exceeded | Your plan's daily send quota is used up. |
Rate limits & quotas
Limits are enforced per tenant at the edge by a Durable Object, so they're consistent across every region. A rejected request never consumes quota. Rate and daily-quota limits scale with your plan.
Suppression
If a recipient is on your suppression list, the send returns 200 with { "status": "suppressed" } and no message is sent — this protects your sender reputation and your bill.