Migrate › SendGrid

Move from SendGrid to Relayly

A tested playbook used by 30+ migrating customers. Most teams complete the move in a single afternoon — and stop paying for credits the same day.

Why teams leave SendGrid

The most common reasons we hear:

What carries across

SendGrid conceptRelayly equivalentAuto-migrates?
Marketing Campaigns ContactscontactsYes — full CSV with custom fields
ListslistsYes — preserves names + opt-in setting
SegmentsPredicate-based segments~80% auto-translate; complex predicates flagged
Suppression GroupsSuppression list (per-tag)Yes — bounces, unsubs, complaints all carry
Dynamic Templates (Handlebars)Liquid templatesMost rules auto-translate; we flag the rest with line numbers
API Keys (scoped)Scoped API keysManual recreate (security best practice)
Event WebhooksHMAC-signed webhooksUpdate destination URLs only; payload shape similar
Inbound Parse webhooksInbound routesYes — same parsed payload shape
Single Sends (campaigns)CampaignsDrafts + scheduled migrate; sent history → archive
AutomationsFlowsLinear automations migrate; branched logic needs review
Subusers (Twilio account hierarchy)Sub-accountsYes — Scale tier and above

The export — one script

Get a SendGrid API key with full read scope (Settings → API Keys → "Full Access"). Then:

# Install the migration toolkit
curl -fsSL https://relayly.io/migrate/sendgrid-export.sh | bash

# Or directly from the repo
git clone https://github.com/relayly/migrate-sendgrid
cd migrate-sendgrid

export SENDGRID_API_KEY="SG.xxxxxxx"
export RELAYLY_API_KEY="ek_live_xxxxxxx"
export RELAYLY_ACCOUNT_ID="<uuid_from_dashboard>"

python3 sendgrid-to-relayly.py
# ↳ Reads from SendGrid, writes out/<sg_account>/ snapshot
# ↳ Then idempotent POST/SQL into Relayly

The script is read-only against SendGrid — it never mutates your account. Re-runnable safely if interrupted.

The codebase swap

SendGrid's API shape is similar enough to Relayly's that most call sites need only key-name changes. The simplest pattern:

// Before — SendGrid Node SDK
import sgMail from "@sendgrid/mail";
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
await sgMail.send({
  to:      "user@example.com",
  from:    "hello@yourdomain.com",
  subject: "Welcome",
  html:    "<p>Hi</p>",
});

// After — Relayly Node SDK
import Relayly from "@relayly/node";
const relayly = new Relayly({ apiKey: process.env.RELAYLY_API_KEY });
await relayly.email.send({
  to:      [{ email: "user@example.com" }],
  from:    { email: "hello@yourdomain.com" },
  subject: "Welcome",
  html:    "<p>Hi</p>",
});

Find / replace + a one-line shape adjustment. Most CI runs pass on the first try.

SMTP swap (if you don't use the SDK)

Same hostname pattern, just point at us:

# Before
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=SG.xxxxxxx

# After
SMTP_HOST=smtp.relayly.io
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=ek_live_xxxxxxx

No code change — just the env vars.

DNS records

SendGrid asks for CNAME-based domain authentication; Relayly uses TXT records (industry standard). You can run both side-by-side during the cutover — neither set conflicts with the other.

Webhook swap

Relayly's webhook payload is similar but not identical. The main differences:

Sample adapter snippet (Node):

// Add at the top of your existing SendGrid webhook handler
function normalize(req) {
  if (req.headers["x-relayly-signature"]) {
    // Wrap a single Relayly event into a SendGrid-shaped batch
    return [{ ...req.body, event: req.body.event.replace("email.", "") }];
  }
  return req.body; // SendGrid path
}

Cutover playbook

  1. Day 0 — verify the export. Run the script in dry-run mode (--dry). Review the manifest: contacts, lists, templates, segments. Flag anything missing.
  2. Day 1 — apply to Relayly. Run without --dry. Verify in the Relayly dashboard that contacts & templates look right.
  3. Day 2 — dual-send week. Send your next campaign through Relayly. Compare inbox-rate at Gmail / O365 / Yahoo (the dashboard exposes this). Repeat for each unique audience type.
  4. Day 7 — flip the API key. Search-and-replace your codebase. Deploy. Monitor for 24h.
  5. Day 8 — pause SendGrid. Don't delete the account yet — keep it as an unsubscribe-list reciprocity reference for 30 days. Pause all flows + future Single Sends.
  6. Day 38 — terminate SendGrid. Cancel the subscription. You're done.
Don't re-import sent campaigns as new sends. The export script keeps these as analytics-only metadata by default. If you flip --include-sent-history-as-sends, you'll re-mail people. Don't.

The dual-send overlap question

"Will running both providers for a week tank deliverability?" is the most frequent worry. The honest answer:

Pricing-side check

Quick math for a typical migrating team:

VolumeSendGridRelaylyAnnual savings
50k/mo, no dedicated IP$19.95/mo$25/mo− $60
50k/mo, with dedicated IP$99.95/mo$25/mo (IP included)+ $899
500k/mo, with dedicated IP$249.95/mo$100/mo+ $1,799
1.5M/mo, 2× IPs, EU residency$629/mo$130/mo+ $5,988

SendGrid pricing as of 2026-05 from sendgrid.com/pricing. We're pricier than SendGrid only at the lowest dedicated-IP-free tier — the moment you need one dedicated IP, the math flips.

Start the migration

Sign up free, run the export script, dual-send for a week. We'll spot you 10,000 verification sends.

Start free