Before you switch
- Add the domain you send from under Domains in the dashboard. Our three DKIM records (
…._domainkey) sit beside Resend’sresend._domainkey, so both can sign while you move, and those three alone verify the domain with us. - Leave Resend’s
send.records until you have moved. Both services usesend.your domain for bounces, each pointing at its own Amazon SES region. Keep Resend’s MX there until all your sending has moved, then replace it with ours. Until then we use Amazon SES’s own bounce address, and DKIM still passes DMARC. “Add to Cloudflare” leaves Resend’s records alone, and shows that MX as one for you to decide. - Make an API key under API keys. A full-access key does everything below; a sending key can only send.
- Bring your suppression list. Under Suppressions, import the addresses that bounced, complained or unsubscribed with Resend — a CSV export, or one address a line — so this account never sends to them.
A new account starts in the sandbox: it sends only to its own team until we have approved it. See the limits.
Point the SDK here
Set your new key and our base URL where Resend’s SDK looks for them. With both in the environment, new Resend() needs no change at all:
Or give them in code, before the first request:
The answer is the SDK’s own: data with the email’s id, or error with a name, a message and a statusCode.
What works
Our test suite runs Resend’s SDK, version 6.32.1, against this API on every change. These are the calls it covers.
| Call | What it does here |
|---|---|
emails.send | Every field the SDK sends: from, to, cc, bcc, replyTo, subject, html, text, headers, tags, scheduledAt and attachments — content as a Buffer or base64, contentType, and contentId for inline images — and the idempotencyKey option. |
batch.send | Up to 100 emails, queued all together or not at all. |
emails.get | The email, its status and its latest event. |
emails.list | The newest first, with limit. |
emails.update | Moves an email still waiting to its new scheduledAt. |
emails.cancel | Cancels an email still waiting. |
domains.list, domains.get | Your domains and their status. |
webhooks.verify | Checks our webhook deliveries with your endpoint’s signing secret. Our email events are email.sent, email.delivered, email.delivery_delayed, email.bounced, email.complained and email.failed; the webhooks guide shows the payload. |
What is different
| If you use | Here |
|---|---|
| scheduledAt | An ISO 8601 date and time with its zone, at most 72 hours ahead. Words like “in 1 hour” are refused. |
| Attachments by URL (path) | Not supported: send the file itself in content. |
| batch.send with batchValidation: permissive | Refused. A batch is queued whole or not at all — the SDK’s default. |
| emails.list with after or before | Refused. Ask for a larger limit, or page with the HTTP API’s cursor. |
| Custom headers | X-* (but not X-SES-*), List-Unsubscribe, List-Unsubscribe-Post, List-Id, In-Reply-To, References and Auto-Submitted. |
| Templates, contacts, segments, broadcasts, topics, receiving | Not offered. A call to one answers not_found or validation_error. |
| Open and click tracking | Not offered. |
| A new account | Starts in the sandbox, sending only to its own team, until we have approved it. |
Error names
Code that checks error.statusCode needs no change. Code that checks error.name should look for ours; the errors page explains each.
| Resend’s SDK | Here | Status |
|---|---|---|
missing_api_key, invalid_api_key | unauthorized | 401 |
restricted_api_key, invalid_access | forbidden | 403 |
invalid_from_address | domain_not_verified, validation_error | 403, 422 |
validation_error, missing_required_field, invalid_parameter, invalid_attachment, invalid_idempotency_key, invalid_idempotent_request | validation_error | 422 |
rate_limit_exceeded | rate_limited | 429 |
daily_quota_exceeded, monthly_quota_exceeded | quota_exceeded | 429 |
not_found | not_found | 404 |
application_error, internal_server_error | internal_error | 500 |
account_paused (403) is ours alone: sending is paused on the account, and the dashboard says why.
Other languages
We test Resend’s Node.js SDK only. For another language, call the HTTP API directly — the quickstart has curl, Node, Python and PHP — or write to hello@mydomainshub.com and tell us which SDK you use.
Resend is a trademark of its owner. MyDomainsHub is not affiliated with Resend.