← All playbooks
Transactional email migration

Resend → SendGrid

Move Resend sending to SendGrid by authenticating domains again, rewriting the API client, and copying Resend’s team-wide suppressions onto SendGrid’s bounce, spam, and unsubscribe lists. React Email can keep rendering HTML. SendGrid template IDs are optional. IP reputation stays behind.

Typical timeline8–18 business days24–50 hours active work
Statusneeds review
Source profileResend suppressions and SendGrid migration pages reviewed 2026-10-31
Destination profileSendGrid bounce export and domain authentication docs reviewed 2026-10-31
Documentation date
Review window
Evidence4 sources
This route needs review.Use it as a planning baseline, then verify the dated sources and test with representative data before production.
Before you migrate

Should you make this move?

Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.

Current platform

Resend

Reasons to stay
  • A simple API, React Email, and clear domain setup make transactional sending approachable for product teams
  • Audience, campaigns, automations, and reporting live in one publishing system
Reasons to leave
  • Message streams, native template languages, and long IP history from older providers do not transfer in
  • Automation logic, analytics history, and deliverability settings are not very portable
New platform

SendGrid

What gets better
  • High-volume email APIs, templates, marketing tools, dedicated IPs, and a broad ecosystem cover many sending models
  • Audience, campaigns, automations, and reporting live in one publishing system
What gets worse
  • Account reputation, subusers, suppression scopes, and product complexity require disciplined governance
  • Automation logic, analytics history, and deliverability settings are not very portable
Best of the move

SendGrid: High-volume email APIs, templates, marketing tools, dedicated IPs, and a broad ecosystem cover many sending models. This removes a major source-side concern: Message streams, native template languages, and long IP history from older providers do not transfer in.

Worst of the move

What you lose: A simple API, React Email, and clear domain setup make transactional sending approachable for product teams. What you inherit: Account reputation, subusers, suppression scopes, and product complexity require disciplined governance.

Jump to a section
01At a glance

Know the shape of the move.

Transfer outcome12 features audited
Transfer outcome distributionClean transfer: 0, Partial transfer: 3, Manual rebuild: 6, Not transferred: 3.
Clean0
Partial3
Manual6
Lost3
Mapping route8 of 9 fields have a destination path

This timeline assumes

  • You send through Resend’s API or documented SMTP today.
  • You can add SendGrid SPF, DKIM, and optional link-branding records beside Resend DNS until cutover.
  • Resend stays able to send until SendGrid completes one production cycle.
  • The site already documents SendGrid → Resend and SendGrid → Postmark as nearby routes.
  • You export Resend suppressions before the first SendGrid production send.
02What transfers

What survives the move.

“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.

ItemOutcomeImpactWhat happensMitigation
Domains and sender identitiesmanualcriticalSendGrid authenticates domains on Sender Authentication and can also confirm individual sender identities. Resend domains do not transfer.Complete domain authentication. Send a test from each From address.
API payloadsmanualcriticalSendGrid uses its own mail send body and personalizations. Resend uses from, to, subject, and html with Bearer auth.Rewrite the client. Keep HTML output if you already render it.
Templates and mail mergepartialhighSendGrid has native templates and substitutions. Resend’s migrate page says Resend does mail merge with React Email. Those React components do not become SendGrid templates unless you port them.Keep rendering HTML, or rebuild SendGrid templates and map substitutions.
SuppressionspartialcriticalResend has one team-wide list with bounce, complaint, and manual origins. SendGrid splits bounces, spam reports, blocks, and unsubscribes. A Resend CSV is not a SendGrid import format.Download Resend’s CSV. Load bounce origins onto Bounces, complaints onto Spam Reports, and unsubscribes you track onto the unsubscribe group you use.
Link brandingmanualhighSendGrid click and open tracking can use sendgrid.net unless you add link-branding CNAMEs.Set link branding if you need on-domain click hosts. Test a live link.
Dedicated IPs and rDNSlostcriticalResend reputation does not move. SendGrid rDNS is required only when you use dedicated IPs.Warm the new IP or shared pool. Do not dump full volume on day one.
WebhooksmanualcriticalEvent names and payloads change. Resend keeps webhook and API request logs. SendGrid Activity is a different store.Point a staging consumer at SendGrid events first.
InboundmanualhighSendGrid Inbound Parse is a new MX and MIME post. It does not read Resend receiving webhooks.Rebuild inbound if you still need it.
Idempotency keyslostmediumResend documents Idempotency-Key. SendGrid mail send does not copy that header.Dedupe in the app.
Rate-limit detailspartialmediumResend documents IETF rate-limit headers. Its SendGrid guide says SendGrid errors without those details.Update retry logic for SendGrid’s error body.
Subusers and EU pinningmanualhighSendGrid subusers and EU-pinned domains are new structure. Resend multi-region is not a subuser import.Create only the subusers you need. Authenticate domains per region if you use EU pinning.
API request logslostmediumResend stores API request history. SendGrid’s migrate comparison says SendGrid returns an HTTP response without that log.Export Resend logs you still need.
03Field and feature mapping

Where each thing goes.

SourceDestinationMethodNotes
Resend domainSendGrid authenticated domainmanualAdd SPF and DKIM.
RESEND_API_KEYSENDGRID_API_KEYmanualRotate.
html and to arraySendGrid content and personalizationstransformKeep rendered HTML if you can.
React EmailHTML content or a SendGrid templatetransformNo automatic port.
Suppression origin bounceSendGrid BouncestransformExport CSV first.
Suppression origin complaintSendGrid Spam ReportstransformDo not mail these addresses.
Resend webhookSendGrid event webhookmanualMap event names.
Resend receivingInbound Parse, if still requiredmanualNew MX.
Idempotency-KeyNo destinationunsupportedDedupe in the app.
04Before you begin

Make the move recoverable.

Backup procedure

Create the source-of-truth backup

Keep Resend keys, suppressions, and DNS so you can send again.

  1. List domains, From addresses, templates, webhooks, and inbound.
  2. Download the Resend suppressions CSV.
  3. Archive React Email or template source.
  4. Record Resend DNS.
  5. Keep a Resend key that can still send.

Proof to capture: A manifest lists domains, the CSV hash, and the Resend key owner.

Transformation · SendGrid API or official SDK

SendGrid client

Replace Resend emails.send with SendGrid mail send.

  1. Set the SendGrid API key.
  2. Map from, to, subject, and html onto the SendGrid mail object.
  3. Drop Idempotency-Key or replace it with your own dedupe.
  4. Send a canary before you flip production.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · Resend Download CSV plus SendGrid suppression UI or API

Suppression split

Place Resend’s one list onto SendGrid’s separate lists.

  1. Split the CSV by origin.
  2. Load bounces and spam reports.
  3. Load unsubscribes you still honor.
  4. Test a known bounce.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

05Handle with care

The things most likely to hurt.

These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.

Import

A Resend bounce never reaches SendGrid Bounces

criticalpossible likelihood

You imported complaints but not bounces.

Consequence
SendGrid mails a mailbox Resend already hard-bounced.
Mitigation
Count rows by origin before and after import.

Stop if: A production send goes to an address in the Resend bounce export.

Cutover

Both keys still send

criticalpossible likelihood

A worker still has RESEND_API_KEY after SENDGRID_API_KEY is live.

Consequence
Duplicate mail.
Mitigation
One writer. Disable the old key after the queue drains.

Stop if: A canary gets two copies.

Tracking

Click hosts surprise you

highpossible likelihood

Links rewrite to sendgrid.net and fail a content check.

Consequence
Clicks look untrusted or break.
Mitigation
Enable link branding if you need on-domain hosts. Test a click.

Stop if: A production tracked link is wrong.

06Precise timeline

Do the work in this order.

Estimate forOne Resend team moving a few domains onto SendGrid with exported suppressions
Total elapsed8–18 business days
Active work24–50 hours
BufferAdd time for dedicated-IP warm-up, inbound parse, or a template port.
01
Days 1–3Inventory Resend2–3 days
02
Days 3–5Export suppressions1–2 days
03
Days 5–12Authenticate and rewrite5–7 days
04
Days 12–16Switch senders1–3 days
05
Days 16–18Watch deliverability3–5 days
  1. Days 1–3 · inventory

    Inventory Resend

    5–9 hours active2–3 days elapsedOwner review waiting
    • List domains, send paths, and inbound.
    • Decide whether you need subusers or dedicated IPs.

    Depends on: Resend and SendGrid admin access

    Stop / go checkpoint

    Export?

    Go when: Every send path has an owner.

    Stop when: A production From address is unknown.

  2. Days 3–5 · backup

    Export suppressions

    3–6 hours active1–2 days elapsedCSV download waiting
    • Download the Resend CSV.
    • Archive templates and DNS.

    Depends on: inventory

    Stop / go checkpoint

    Build SendGrid?

    Go when: The CSV hashes.

    Stop when: The export is empty and you know you have bounces.

  3. Days 5–12 · pilot

    Authenticate and rewrite

    10–22 hours active5–7 days elapsedDNS and inbox tests waiting
    • Authenticate the SendGrid domain.
    • Rewrite the client.
    • Load suppressions on a test subuser.
    • Watch events.

    Depends on: backup

    Stop / go checkpoint

    Cut over?

    Go when: Canary, skip-on-bounce, and events pass.

    Stop when: A required send path still calls Resend.

  4. Days 12–16 · cutover

    Switch senders

    3–8 hours active1–3 days elapsedQueue drain waiting
    • Load production suppressions.
    • Point the app at SendGrid.
    • Drain Resend jobs.

    Depends on: pilot

    Stop / go checkpoint

    SendGrid owns sending?

    Go when: No Resend production send remains.

    Stop when: A duplicate or a suppressed send appears.

  5. Days 16–18 · observe

    Watch deliverability

    3–6 hours active3–5 days elapsedInbox signals waiting
    • Watch bounces and complaints.
    • Keep Resend ready.

    Depends on: cutover

    Stop / go checkpoint

    Close rollback?

    Go when: One send cycle is clean.

    Stop when: Rates jump.

07The point of change

Cut over with a way back.

Go live

Cutover

Make SendGrid the only production sender after Resend suppressions are loaded.

Recommended window: A low-volume weekday with DNS and app owners on call.

  1. Split and import the Resend CSV.
  2. Switch the application to the SendGrid key.
  3. Drain Resend queues.
  4. Send canaries.
  5. Confirm a known bounce is skipped.

Proof to capture: SendGrid sends production mail. Resend is idle. Known bounces are skipped.

Return to safety

Rollback

Return sending to Resend without losing SendGrid-era suppressions you still need.

Deadline: Before you delete the Resend domain or API key.

  1. Stop SendGrid production sends.
  2. Restore the Resend key and DNS.
  3. Export new SendGrid bounces and spam reports.
  4. Import reviewed rows into Resend.
  5. Send a canary through Resend.

Proof to capture: Resend is the only production sender again.

Rollback immediately when
  • Suppressed address received mail
  • Duplicate send
  • Webhook consumer failure
  • Bounce or complaint spike
  • A From address fails authentication
08Verification report

Prove the migration worked.

Every blocking check must pass. Capture the evidence before cleanup begins.

0%
Interactive report preview0 / 8 checks passed
PassIDCheckMethodExpected resultEvidence
V-01BlockingSendGrid domain authenticatedSend from each production From address.SendGrid accepts the message. DKIM aligns.Sender Authentication page and received header.
V-02BlockingKnown bounce is skippedSend to an address from the Resend bounce export.SendGrid suppresses the message.Bounces list and Activity.
V-03BlockingMessage shapeCompare a canary with the old Resend payload.From, To, subject, and html match the approved map.Request log.
V-04BlockingEvent consumerTrigger delivered and bounce events.One mapped event each.Consumer log.
V-05BlockingClick hostOpen a tracked link.The host is the approved SendGrid or branded host.Link inspect.
V-06BlockingResend idleWatch Resend Emails after cutover.No new production sends.Emails screenshot.
V-07BlockingNo duplicate canaryRetry a send the way production does.One delivered message.Inbox.
V-08BlockingResend still sendsKeep a rollback key and send a staging message.Resend still accepts mail.Rollback send.
09Post-migration cleanup

Remove the scaffolding safely.

Safe after: One full send cycle, stable rates, and seven days without a rollback trigger.

  1. Archive the Resend CSV and SendGrid bounce export.
  2. Revoke the Resend production key.
  3. Remove Resend DNS after mail no longer uses it.
  4. Keep Resend readable through the retention window.
  5. Document the SendGrid key rotation.
  6. Schedule the next suppression review.
Sources and evidence

Verify against the primary material.

Platform behavior changes. Check these sources and the review dates above before executing a production migration.

  1. Resend: migrate from SendGridAccessed 2026-10-31
  2. SendGrid: download a bounce listAccessed 2026-10-31
  3. SendGrid: domain authenticationAccessed 2026-10-31
  4. Resend: email suppressionsAccessed 2026-10-31