Errors
Every error is an RFC 9457 problem, with Resend’s fields alongside, so Resend’s SDKs read it too:
{
"type": "https://heraldmail.dev/docs/errors#daily_quota_exceeded",
"title": "daily quota exceeded",
"status": 429,
"detail": "This project has reached today's limit of 1,000 recipients.",
"name": "daily_quota_exceeded",
"statusCode": 429,
"message": "This project has reached today's limit of 1,000 recipients."
}The message says what happened, then what to do. Act on name, which never changes.
| Name | Status | What to do |
|---|---|---|
missing_api_key | 401 | Send your key as Authorization: Bearer hrld_…. |
invalid_api_key | 401 | The key is wrong, revoked or expired: make a new one in Console. |
restricted_api_key | 403 | The key lacks the scope this needs: make one with more, or use another. |
ip_not_allowed | 403 | The key is limited to other addresses. |
project_suspended | 403 | The project’s sending is paused by the platform team. Nothing is sent; contact them. |
not_found | 404 | No such thing in this project and mode. |
marketing_on_hold | 409 | The project’s Proclamations are held (a breaker tripped, Gmail’s spam rate, or someone stopped them). Dispatches still go. |
suppression_kept | 409 | That address was suppressed by the person’s own choice (a complaint, an unsubscribe or an erasure): only they can change it. |
concurrent_idempotent_requests | 409 | A request with this Idempotency-Key is still being handled. Wait, then retry. |
validation_error | 422 | The request isn’t right: the message says which field, and why. |
invalid_idempotent_request | 422 | This Idempotency-Key was used with a different request. Use a new key. |
payload_too_large | 413 | The request is over 60 MB. |
rate_limit_exceeded | 429 | Over 50 requests a second for this key: wait for Retry-After. |
daily_quota_exceeded | 429 | The project has sent its recipients for the day (counted from midnight UTC). |
project_provisioning | 503 | A brand-new project is still being set up. Try again in a minute. |
internal_server_error | 500 | Our fault. Retry with the same Idempotency-Key, and quote the x-request-id if it persists. |
Retrying safely
Retry a 429 or a 5xx after the time in Retry-After, with the same Idempotency-Key: an email Herald already accepted isn’t sent twice. Don’t retry a 4xx otherwise; it will fail the same way. The SDK does all of this for you.