Migrate from SendGrid
Moving from SendGrid to SendRaven.
SendGrid keeps contacts in Marketing Campaigns and opt-outs in five suppression lists (global unsubscribes, group unsubscribes, bounces, spam reports, invalid emails), and each exports separately. The migration is one contact import and a few suppression imports with the right status.
Unsubscribe groups map onto topics: a person's group opt-outs become topic preferences, so the preference page still shows them what they chose.
Export steps checked 6 September 2026 against sendgrid.com. Weighing it up? SendRaven vs SendGrid.
- Marketing → Contacts. Export All Contacts for everything, or open a list and export it alone. SendGrid prepares the file and emails a download link.
- Suppressions. Each list (Global Unsubscribes, Group Unsubscribes, Bounces, Spam Reports, Invalid Emails) has its own export. Download each as CSV.
- Import the contacts first, then each suppression file with its status. Group unsubscribes go through the topics endpoint instead, one topic per group.
Before you start
Who should switch from SendGrid, and who should stay.
Stay with SendGrid if
- You send over SMTP from software you cannot change. SendRaven is a REST API and an MCP server, with no SMTP relay.
- You need dedicated IPs (SendGrid includes them from Email API Pro and Marketing Campaigns Advanced) or subusers to separate many customers under one account.
- A marketing team designs campaigns in SendGrid's visual editor and has nobody to write HTML. SendRaven has no visual builder.
- The rest of your messaging is on Twilio, and one vendor matters more to you than one email bill.
Switch to SendRaven if
- You pay for two products to send one company's email. SendGrid prices the Email API by monthly volume and Marketing Campaigns by contact storage, volume and features. SendRaven is one plan on one meter, emails sent, and contacts cost nothing.
- Replies should come back as conversations your code or agent can act on: joined to the message they answer, with the quoted history stripped, and one query for everything awaiting a reply.
- An AI agent holds the API key. A SendRaven key can carry a daily send limit, a recipient allowlist and an approval hold, checked before each send; a SendGrid key carries permissions.
- You are on the free trial, or it ended. New SendGrid accounts get 60 days at 100 emails a day, after which API and SMTP sending stops without a paid plan. SendRaven's Free plan is 3,000 emails a month with no expiry.
Facts about SendGrid from its own documentation, last verified 17 September 2026.
Compared
What changes when you move from SendGrid.
| What changes the architecture or the bill | SendRaven | SendGrid |
|---|---|---|
| Priced per email sent, never per contact | Yes One meter. A contact is free. | Partly Email API by volume; Marketing Campaigns by contacts |
| Transactional, campaigns and automations on one plan | Yes One key, one plan, one dashboard, one suppression list. | No two products |
| The reply is a thread, not a webhook | Yes Joined on Message-ID to the message it answers. | No Inbound Parse posts to a webhook |
| 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 key permissions; 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. | No not documented |
From SendGrid'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 SendGrid.
What moves
What comes across, and what you rebuild.
| In SendGrid | In SendRaven |
|---|---|
| Contacts, names | EMAIL, FIRST_NAME, LAST_NAME, matched automatically. |
| Custom fields | Every custom field is a column and becomes a custom property, typed from its values. SendGrid's reserved fields (address lines, phone, CONTACT_ID, timestamps) are ignored by default. |
| Lists | Export per list and import each into its own SendRaven audience, or export everything into one. |
| Global unsubscribes | Imported as "everyone in this file is unsubscribed". |
| Bounces, invalid emails | Imported as "…bounced". |
| Spam reports | Imported as "…reported spam". |
| Group unsubscribes | One topic per group, loaded with POST /v1/topics/{key}/import and subscribed: false. |
| Dynamic templates | Handlebars HTML, moved into SendRaven templates with {{variables}}. |
Migrate with MCP
Or hand the export to your agent.
This is the migration an agent in your editor is best at, because half of it is code. Connect SendRaven's MCP server to Claude Code, Cursor or another client that can read your repository and the exported files, and ask for the whole thing.
Over MCP the agent adds and verifies the sending domain (add_sending_domain, verify_sending_domain), loads the suppression files (suppress_many, up to 10,000 addresses per call), imports Marketing Campaigns contacts (import_contacts, up to 5,000 per call) and sends a test (send_email). In the repository it replaces the SendGrid send calls with POST /v1/emails, which you review like any other change.
The SendGrid exports are in ./sendgrid-export.
1. Suppress everything in bounces.csv, spam_reports.csv and
invalid_emails.csv with scope "all", and everything in
global_unsubscribes.csv with scope "marketing" and reason
"unsubscribe". Report the counts per file.
2. Import contacts.csv into the audience "Customers" with
names and custom fields.
3. In this repository, replace every @sendgrid/mail send with
a POST to https://api.sendraven.ai/v1/emails using
SENDRAVEN_API_KEY and an Idempotency-Key header. Keep the
SendGrid path behind an EMAIL_PROVIDER environment variable.
4. Send one test email from mail.example.com to me.- Load the suppressions before anything sends. Re-running the same file is safe: each address is written once, however many times it is loaded.
- Group unsubscribes are topic preferences, not suppressions. Load them with POST /v1/topics/{key}/import (one call per group); the MCP server only sets one person's preferences at a time.
- The audience is created in the dashboard or with POST /v1/audiences; the MCP server has no tool for it.
- Everything passed to a tool goes through the model's context. For contact files beyond a few thousand rows, ask the agent to write 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.
The contact export: EMAIL, FIRST_NAME, LAST_NAME, ALTERNATE_EMAILS, ADDRESS_LINE_1, ADDRESS_LINE_2, CITY, STATE_PROVINCE_REGION, POSTAL_CODE, COUNTRY, PHONE_NUMBER, WHATSAPP, LINE, FACEBOOK, UNIQUE_NAME, CONTACT_ID, CREATED_AT, UPDATED_AT, then one column per custom field. Alternate emails are not the address column, and the import knows.
A suppression export is a list of addresses with a created time and, for bounces, the reason. There is no status column because the file is the status: choose it at import.
The part that matters
Bring the opt-outs.
Five files, three statuses. Global unsubscribes are "unsubscribed": marketing suppressed, transactional untouched. Bounces and invalid emails are "bounced", spam reports are "reported spam"; both suppress everything. Bring all of them before the first campaign. SendGrid learned that list at the cost of its reputation; you can have it for the cost of an upload.
Group unsubscribes are per group, so they are topic preferences rather than suppressions: create a topic for each group and load the members with subscribed false. Someone who left the promotions group still gets the product update, which is what they asked for.
Templates and sending
The copy and the code.
Dynamic templates are Handlebars over HTML. Copy the HTML out of the editor into a SendRaven template. Plain {{substitutions}} carry over as they are; conditionals and loops do not, so flatten those in the code that fills the variables. Remove the unsubscribe tags and footer; SendRaven adds the link and the List-Unsubscribe headers to marketing sends.
The v3 mail send call, with personalizations and content arrays, becomes POST /v1/emails with from, to, subject and html or text, or a template slug and variables. One recipient per call for transactional; POST /v1/emails/batch for a small fan-out; a broadcast for a campaign.
# Group unsubscribes → one topic per group, members opted out
curl -X POST https://api.sendraven.ai/v1/topics/promotions/import \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "emails": ["ana@example.com", "bo@example.com"], "subscribed": false }'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 SendGrid account and its API key active until the switch is done. Nothing in SendRaven touches them, so going back is changing EMAIL_PROVIDER.
- Move transactional mail one kind at a time, the lowest-stakes first: a notification before a receipt, a receipt before a password reset. Watch each one's bounces and delivery in the email log for a few days before moving the next.
- Move campaigns by splitting the list, never by sending one campaign from both. The engaged part goes from SendRaven while the new domain warms up; the rest stays on SendGrid until the warm-up can carry it.
- While both send, bounces and opt-outs have to travel both ways. Re-export SendGrid's suppression lists and load them again before each SendRaven campaign, and add SendRaven's new ones (the Suppressions page, or GET /v1/suppressions) to SendGrid before each of its sends.
Questions
Asked by people leaving SendGrid.
Do I need Marketing Campaigns contacts if I only send transactional?
No. Import the bounce and spam report suppressions so the addresses SendGrid already gave up on are refused here too, verify the domain, and switch the send call. There is nothing else to move.
What about IP warm-up?
There is no IP to warm: SendRaven sends from shared IPs. The domain is what mailbox providers judge, so a new sending domain still warms up. Its daily marketing ceiling rises step by step and a large first campaign spreads over several days on its own. Send it to the engaged part of the list first.

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.

