Envello
Tutorial

Migrating from SendGrid to Envello

Envello Team·2026-07-16·7 min read

SendGrid's SDK shape (msg objects, personalizations arrays, template IDs) doesn't map onto Envello's Resend-shaped API the way a Resend migration does. There's no codemod for this one. It's a real rewrite of the sending code, though a small one, plus one piece that genuinely needs manual rework: dynamic templates.

The sending call itself

SendGrid's @sendgrid/mail takes a msg object with to, from, subject, and text/html fields, sent via sgMail.send(msg). Envello's shape is close enough that this part is closer to a find-and-replace than a redesign:

  • to, from, subject, text, html map directly, field for field
  • cc and bcc accept a single address or an array in both APIs
  • attachments carry over conceptually, though check the exact encoding, SendGrid expects base64 content plus a filename and type; confirm Envello's attachment shape matches before you migrate anything with attachments

Dynamic templates: the honest answer

SendGrid's dynamic templates support Handlebars-style logic: loops, conditionals, and a visual template editor. Envello's template system does variable substitution ({{name}} style placeholders) and nothing more. If your SendGrid templates are simple substitution, this is a straightforward port. If they lean on {{#if}} blocks or {{#each}} loops for anything non-trivial, there's no automatic equivalent today.

The practical path for those templates: render them to a plain HTML string in your own application code (React Email is one option, and Envello takes a pre-rendered HTML string directly) instead of relying on server-side template logic. It's more code on your side than a hosted dynamic template, and it's worth knowing that going in rather than discovering it mid-migration.

DNS and domain verification

Same shape as any provider switch: add the SPF, DKIM, and DMARC records Envello generates, alongside your existing SendGrid records, not in place of them, until you've confirmed delivery through the new provider. Most teams keep the same from domain throughout.

API key and error handling

Swap your SendGrid API key for ENVELLO_API_KEY. Error handling needs an actual look, not just a rename: SendGrid and Envello don't return the same error codes or response shapes, so any retry or alerting logic that branches on a specific SendGrid error will need updating to Envello's equivalents (rate_limited, recipient_suppressed, invalid_api_key, and so on).

Cutover

Once the sending code and DNS are in place, route a small slice of traffic first and check delivery in Envello's log search, which keeps 90 days of history by default. Widen the rollout once you're confident, and only remove the old SendGrid DNS records after the switch has held for a few days.

Envello

EU-hosted transactional email, done right by default.