Migrate from Resend
Moving from Resend to SendRaven.
The send call is close to a rename, and an audience is a short list of fields (email, first name, last name, unsubscribed), so this is the smallest migration on this page. The domain is the part that takes time.
Resend's own sending history stays behind: the suppression list it built from bounces and complaints needs to come with you, or the first campaign learns it again.
Export steps checked 17 September 2026 against resend.com. Weighing it up? SendRaven vs Resend.
- Contacts, filter to the contacts you want (or a segment), and Export. Exports are limited to admins on the Resend team; a large one arrives by email as a download link.
- Or pull them from the API: GET /contacts pages through every contact with its unsubscribed flag, and write the CSV yourself. The columns below are what either gives you.
- Then the suppression list, from Email, then Suppressions, exported as a separate file. It holds the addresses Resend stopped sending to, with where each suppression came from.
Before you start
Who should switch from Resend, and who should stay.
Stay with Resend if
- You want official SDKs, or SMTP relay for software you cannot change. Resend has both on every plan; SendRaven is REST, MCP and an OpenAPI document.
- Your mail is transactional, under 100,000 a month, and nobody reads the replies. The send call is nearly identical, the bills are within a dollar of each other, and switching buys you little.
- You need a dedicated IP (Resend sells one on Scale) or more than one domain on a free plan (Resend's has three).
- You need a sending reputation with years behind it today. SendRaven is new, a new sending domain warms up over days, and we do not quote deliverability figures we have not earned.
Switch to SendRaven if
- Software reads and answers the replies. SendRaven stores a reply as part of a thread, joined on Message-ID with the quoted history stripped, and GET /v1/threads?awaiting_reply=true returns every conversation that still needs an answer.
- An AI agent holds the key. A Resend key is full access or sending access, optionally limited to one domain. A SendRaven key can also carry a daily send limit, a recipient allowlist and a hold for human approval, and cannot change its own limits.
- You send marketing to a large list. Resend's marketing plans are priced by contacts ($650 a month for 150,000). SendRaven puts transactional and marketing on one meter, emails sent, and contacts cost nothing.
- Sequences should stop when someone answers. An automation ends a person's enrolment when they reply (by default), unsubscribe, bounce or opt out of its topic.
Facts about Resend from its own documentation, last verified 17 September 2026.
Compared
What changes when you move from Resend.
| What changes the architecture or the bill | SendRaven | Resend |
|---|---|---|
| Priced per email sent, never per contact | Yes One meter. A contact is free. | Partly transactional by volume; marketing $40–$650/mo by contacts |
| Transactional, campaigns and automations on one plan | Yes One key, one plan, one dashboard, one suppression list. | No two plans, one dashboard |
| The reply is a thread, not a webhook | Yes Joined on Message-ID to the message it answers. | No a received-email event; you fetch the message and set reply headers yourself |
| One query for what is awaiting a reply | Yes GET /v1/threads?awaiting_reply=true | No |
| Per-key daily cap and recipient allowlist | Yes daily_send_limit and allowed_recipients on the key, checked on every send. | Partly keys scope to a domain and to send-only; no cap or allowlist |
| Human approval hold on a key | Yes requires_approval drafts the message and waits for a person. | No |
| Unsubscribe cancels queued sends and ends the sequence | Yes Two writes: suppress the address, cancel what is scheduled for it. | Partly an automation skips its remaining send steps for an unsubscribed contact |
From Resend's own pricing and documentation, last verified 16 September 2026. A “No” means not offered or not documented on that date. Everything else is on SendRaven vs Resend.
What moves
What comes across, and what you rebuild.
| In Resend | In SendRaven |
|---|---|
| Contacts, names | email, first_name, last_name, matched automatically. |
| Unsubscribed | The unsubscribed column, true or false. true imports as unsubscribed and suppressed for marketing. |
| Bounces and complaints | From Resend's suppression list, imported as a file with the matching status. |
| Templates | React Email renders to HTML; keep rendering it in your code and send the HTML, or store the output as a SendRaven template with {{variables}}. |
| Sending | POST /v1/emails takes from, to, subject, html or text. Same shape, different host and key. |
| Broadcasts | Rebuilt as SendRaven broadcasts against the imported audience. |
Migrate with MCP
Or hand the export to your agent.
Most of this migration is code, so it suits an agent in your editor. Connect SendRaven's MCP server to Claude Code, Cursor or another client that can read the repository and the exported files. If Resend's MCP server is connected too, the agent can read contacts from it directly instead of a CSV.
Over MCP the agent loads the suppressions (suppress_many), imports contacts (import_contacts, up to 5,000 per call), sends a test (send_email) and reads the reply back (list_threads, get_thread). In the repository it swaps the Resend send call for POST /v1/emails, which you review like any other change.
Resend exports are in ./resend-export: contacts.csv and
suppressions.csv.
1. Suppress every address in suppressions.csv with scope "all".
Report the count.
2. Import contacts.csv into the audience "Newsletter". A row
with unsubscribed true imports with status unsubscribed.
3. In this repository, replace resend.emails.send with a POST
to https://api.sendraven.ai/v1/emails using SENDRAVEN_API_KEY.
Keep rendering React Email to html and keep the
Idempotency-Key we already send. Put Resend behind an
EMAIL_PROVIDER environment variable.
4. Send a test from mail.example.com to me. When I reply, show
me the thread with get_thread.- Step 4 needs the optional MX record on the sending subdomain; without it replies go nowhere SendRaven can see. Everything else works without it.
- Resend's suppressions export from the dashboard (Email, then Suppressions). Load them before the first campaign: an address that hard bounced there will hard bounce here.
- The audience is created in the dashboard or with POST /v1/audiences; the MCP server has no tool for it.
- Contacts passed to import_contacts go through the model's context. Beyond a few thousand, ask the agent for a script against POST /v1/audiences/{id}/contacts in batches of 5,000, or use the dashboard's CSV import.
Connect the SendRaven MCP server to your client, then paste the prompt with your own audience, segment and domain names.
The file
What the export looks like, and how the import reads it.
id, email, first_name, last_name, created_at, unsubscribed. The id and created_at are ignored by default; unsubscribed is read as the person's status.
The suppression export is a list of addresses with a reason. Import it with "everyone in this file bounced", or split it by reason and import the complaints with "…reported spam" if you want the record to say why.
The part that matters
Bring the opt-outs.
The unsubscribed column brings the opt-outs across in the same import as the subscribers. The suppression list does not come with the audience export, and it is the more important of the two: an address that hard bounced at Resend will hard bounce at SendRaven, and a run of them in your first campaign is what trips the reputation gate. Import it before that campaign.
Templates and sending
The copy and the code.
The request body is the same set of fields, and both APIs honour an Idempotency-Key header, so a retry that already carries one keeps working. What changes is the host and the key. Replies come back as threads if you want them: publish the optional MX record on the sending subdomain, and each reply is joined to the message it answers on the Message-ID that message went out with.
# Resend
curl -X POST https://api.resend.com/emails \
-H "Authorization: Bearer re_..." \
-d '{ "from": "Acme <hello@acme.com>", "to": "ana@example.com", "subject": "Hi", "html": "<p>Hi</p>" }'
# SendRaven
curl -X POST https://api.sendraven.ai/v1/emails \
-H "Authorization: Bearer sk_live_..." \
-H "Idempotency-Key: hi-ana-1" \
-d '{ "from": "Acme <hello@mail.acme.com>", "to": "ana@example.com", "subject": "Hi", "html": "<p>Hi</p>" }'What it costs
Estimate the bill by emails sent, not contacts.
- Emails a month
- 200,000
- SendRaven, Standard plan
- $85.00 a month
- For the 50,000 contacts
- $0
On a new sending domain, the first campaign to all 50,000 goes out over 8 days: the warm-up pauses it at each day's ceiling and resumes it at midnight UTC. The ceiling keeps rising for 14 days from the first send, then comes off. Published plan prices, before tax. Transactional mail, if you move it too, counts on the same meter; replies are never metered.
Then, in order
The steps every migration shares.
Verify your domain first
Add the domain under Domains and publish the DNS records it gives you. Use a subdomain you have not sent from before if you can (mail.yourdomain.com for transactional, news.yourdomain.com for campaigns), so the two reputations stay separate. Nothing sends until this is green, and it can take a while for DNS to settle, so start it before the export.
Import the subscribers
Contacts → Import a CSV. Pick or create the list, upload the export, and check the column mapping: address, names, tags, and which columns become custom properties. Re-running the same file is safe: existing contacts are updated, not duplicated.
Import the opt-outs
Then the unsubscribed, bounced and complained lists, with the matching status. Each one is flagged and suppressed before your first send: unsubscribes for marketing only, bounces and complaints for everything. An import never resubscribes someone who has opted out here.
Check the counts
The audience page shows how many were imported, updated and suppressed. Compare the suppressed count to what the old provider reported. If it is far off, the status column was read differently from how you meant. The mapping step shows what each value became.
Switch the API key
For transactional mail, point the code at POST /v1/emails with a SendRaven key. The request shape is from, to, subject, html or text, and an Idempotency-Key header. Keep the old key alive for a day in case something still points at it.
Send the first campaign to the engaged part of the list
A new domain has no history, and mailbox providers judge it on the first few thousand messages. Opens and clicks start from your first SendRaven send, so use the old provider's engagement: tag the recently engaged people on import, send the first campaign to a segment on that tag, then widen. A new sending domain also warms up, so a large first campaign spreads over several days on its own. The reputation gate refuses a campaign once the bounce or complaint rate is already high; it cannot refuse the one that gets you there.
Safe cut-over
Run both for a cycle, and keep a way back.
- Keep the Resend account and key active until the switch is done. Going back is changing EMAIL_PROVIDER.
- Move one kind of transactional mail at a time, lowest stakes first, and watch its deliveries and bounces in the email log for a few days before the next.
- Move broadcasts by segment, never by sending one broadcast from both. Mail the engaged part from SendRaven while the new domain warms up, and the rest from Resend until the warm-up can carry it.
- While both send, copy opt-outs both ways: Resend's new unsubscribes and suppressions into SendRaven before each campaign here, and SendRaven's (the Suppressions page, or GET /v1/suppressions) into Resend before each broadcast there.
Questions
Asked by people leaving Resend.
Can I keep React Email?
Yes. It renders to HTML in your code; send that HTML in the html field exactly as you do now. Move it into a stored template only if you want the copy reviewed once and filled in at send time, which is what the {{variables}} are for.
Do I need to change the from address?
Only if you take the chance to split transactional and marketing onto their own subdomains, which we recommend. A complaint spike on the newsletter then cannot touch password resets.

Start with the domain.
3,000 emails a month, inbound included, and no charge until you switch paid sending on. Verify the domain today and import the list once the DNS has settled. The other guides are on the migrate page.

