Email Fast Get a sandbox key
Docs

Quickstart: Node.js

Five minutes from install to a verified send — safely, against the sandbox, before any real email is involved.

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

1. Install

npm install @email-fast/nodejs

2. Send

import { EmailFast } from "@email-fast/nodejs";

const ef = new EmailFast({ apiKey: process.env.EMAILFAST_API_KEY, baseUrl: "https://api.emailfast.dev" }); // ef_sandbox_… works everywhere

const { id, status } = await ef.send({
  to: "ada@example.com",
  subject: "Welcome to the ledger",
  html: "<h1>Hi {{name}}</h1><p>Your account is ready.</p>",
  data: { name: "Ada" },
  idempotency_key: "welcome-ada-1", // retry-safe: same key can never double-send
});

console.log(id, status); // "msg_…", "queued"

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.

3. Watch it happen

const timeline = await ef.getMessage(id);
console.log(timeline.events); // admitted → rendered → (sandbox-)delivered …

With a sandbox key the message lands in your hosted capture inbox — same pipeline, nothing sent: sandbox keys (ef_sandbox_…) that run the real pipeline dry: real validation, real rendering, real events, a hosted capture inbox — and no email leaves.

4. Hear about it via webhook

// Your Express handler (raw body needed for signature verification):
import crypto from "node:crypto";

app.post("/hooks/email", express.raw({ type: "application/json" }), (req, res) => {
  // x-emailfast-signature: "t=<unix>,v1=<hex>" — HMAC-SHA256 over `<t>.<rawBody>`
  const sig = Object.fromEntries(
    req.get("x-emailfast-signature").split(",").map((p) => p.split("=")),
  );
  const expected = crypto
    .createHmac("sha256", process.env.EMAILFAST_WEBHOOK_SECRET)
    .update(`${sig.t}.${req.body}`)
    .digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(sig.v1), Buffer.from(expected))) {
    return res.sendStatus(400);
  }
  const event = JSON.parse(req.body);
  // event.type: email.sent | email.bounced | email.opened | …
  res.sendStatus(200);
});

webhooks signed with timestamped HMAC-SHA256 (Stripe-style t=…,v1=…), with delivery hardened against server-side request forgery. Reject anything older than a few minutes (compare sig.t against the clock) to close the replay window.

Next

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.