Email Fast Get a sandbox key
Migrate

Migrate from SendGrid

Keep your SendGrid SDK and change two lines, or adopt our SDK. Either way, the send you ship today keeps working.

Facts verified 2026-07-17 — corrections: hello@emailfast.dev

Two ways to switch

Email Fast speaks SendGrid's send API natively: SendGrid-, Mailgun-, and Postmark-compatible endpoints: point your existing SDK at a new base URL with a new key and keep your code. A successful call returns what your code already expects: an empty-body 202 with an X-Message-Id header.

Path 1 — keep @sendgrid/mail

  import sgMail from "@sendgrid/mail";
+ import sgClient from "@sendgrid/client";

+ sgClient.setDefaultRequest("baseUrl", "https://api.emailfast.dev");
+ sgMail.setClient(sgClient);
- sgMail.setApiKey(process.env.SENDGRID_API_KEY);
+ sgMail.setApiKey(process.env.EMAILFAST_API_KEY); // ef_sandbox_… works everywhere

  await sgMail.send({
    to: "ada@example.com",
    from: "you@yourdomain.com",
    subject: "Welcome",
    html: "<h1>Hi Ada</h1>",
+   headers: { "Idempotency-Key": "welcome-ada-1" }, // retry-safe (see below)
  });

Path 2 — adopt @email-fast/nodejs

- import sgMail from "@sendgrid/mail";
+ import { EmailFast } from "@email-fast/nodejs";

- sgMail.setApiKey(process.env.SENDGRID_API_KEY);
- await sgMail.send({
-   to: "ada@example.com",
-   from: "you@yourdomain.com",
-   subject: "Welcome",
-   html: "<h1>Hi Ada</h1>",
- });
+ const ef = new EmailFast({ apiKey: process.env.EMAILFAST_API_KEY, baseUrl: "https://api.emailfast.dev" });
+ await ef.send({
+   to: "ada@example.com",
+   subject: "Welcome",
+   html: "<h1>Hi Ada</h1>",
+   idempotency_key: "welcome-ada-1",
+ });

What maps 1:1

Every message admitted this way passes the same checkpoint as every other ingress: every send — REST, SMTP, browser SDK, compatibility endpoints, broadcasts, automations — passes through one admission gate: idempotency, suppression, quota, and content policy in a single checkpoint no ingress can skip.

What arms at launch

The hosted data importers — templates, contacts, and suppression lists pulled across from your SendGrid account — arm at launch. Today you can evaluate the whole send path with a sandbox key: sandbox keys (ef_sandbox_…) that run the real pipeline dry: real validation, real rendering, real events, a hosted capture inbox — and no email leaves.

The idempotency bonus

SendGrid's send endpoint has no idempotency. Ours does: pass an Idempotency-Key header and each recipient in a personalizations fan-out gets its own derived key, so a timeout-and-retry can never double-send part of a batch: a 202 from the API means the send is committed to a durable, partitioned outbox before we answer — a crash can't lose it, and a retry with the same idempotency key can't double-send.

Next

Questions, answered plainly

Do I need to change my application code to migrate from SendGrid?

No. POST /v3/mail/send is accepted as-is: same Bearer auth, same body shape, same 202-with-X-Message-Id response. You change the base URL and the key.

Do my SendGrid dynamic templates work?

Yes, once imported. A send that references a template_id resolves against your imported copy of that template; an unknown id returns a SendGrid-shaped 400 telling you to import it first.

How do I test before pointing production at Email Fast?

Use a sandbox key (ef_sandbox_…) in the same code. The full pipeline runs — validation, rendering, events, a hosted capture inbox — and no email leaves.

See it for yourself

Sandbox keys run the real pipeline dry — real validation, real events, a hosted inbox, no email sent. Early access is onboarding now.