Theme

Resend API notes

What the Resend adapter does under the hood — the endpoints, the limits, the quirks worth knowing, and the capabilities it declares.

Capabilities

Capability Value Consequence
custom_headers true Our headers are passed through.
injects_unsubscribe_headers false Nothing is auto-injected, so the RFC 8058 headers are entirely ours.
send_time_suppression true Silent, region-wide drops for bounces and complaints.
suppression_read :none No API at all. The nightly suppression sync doesn't run.
suppression_webhooks true The only route for Resend-side suppression.
engagement_webhooks false Per-domain tracking stays off — tracking is ours.
push_unsubscribe false No write API. The standing guard covers it.
remote_delete false GDPR erase can't remove the address Resend-side.

Sending

Case Endpoint
One message POST /emails
More than one POST /emails/batch, chunked at 100

Rate limit: 10 requests/second, team-wide. The adapter declares emails_per_minute: 600, and the sender's pacer counts every send against that budget — one message per request through the queue, so 600 a minute is the honest ceiling. The account-wide maximum (sending.max_emails_per_minute, 300 by default) applies on top: the effective pace is whichever of the two is lower.

Headers

"headers": {
  "List-Unsubscribe": "<https://your-mimeo.com/u/SIGNED_TOKEN>",
  "List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
}

Resend injects nothing, so these are ours. The token is the same signed token the subscription page takes, which is what attributes a header unsubscribe to the exact email it came from. Both halves matter: without List-Unsubscribe-Post, a mail client shows a link rather than its own unsubscribe button.

The mail client's POST /u/:token goes directly to Mimeo and globally unsubscribes the person. It does not first pass through Resend or depend on a Resend webhook. Hosted subscription preferences do not change this behavior; selective tag or field changes use the separate preference form.

Transactional mail carries no unsubscribe header. You can't opt out of your own password reset.

Webhooks

Resend event Normalizes to
email.delivered delivered
email.bounced bounced
email.complained complained
email.suppressed suppressed
anything else acknowledged and ignored

A bounce's type maps to our bounce kind: Permanent → hard (suppresses the person), Transient → soft (doesn't — a full mailbox is a try-again, not a dead address).

Signed with Svix: HMAC-SHA256 over svix-id.svix-timestamp.body, base64, compared in constant time, with a five-minute freshness window so a captured request can't be replayed tomorrow. Multiple v1,… signatures are accepted so a secret can be rotated without dropping anything mid-flight. See Webhooks for the shared contract.

Quirks

Credentials

Setting What
provider.resend.api_key The API key.
provider.resend.webhook_secret The Svix signing secret, whsec_….

Both are entered on the Settings page and encrypted in your Mimeo's database, and neither ever appears in a manager repo.

verify_config calls GET /domains and fails when no domain is verified, naming the ones still pending — reporting a good connection that would refuse every send isn't a verification.

See also: Resend setup · Webhooks · Write your own adapter