Quickstart: SMTP relay
If your app already speaks SMTP, migration is a config change: new host, new credentials, done.
Facts verified 2026-07-17 — corrections: hello@emailfast.dev
The settings
Any framework, CMS, or legacy app with an SMTP config block can point here:
host: smtp.emailfast.dev
port: 587 (STARTTLS) — or 465 (implicit TLS)
username: your project slug
password: your API keyTwo rules worth knowing before you paste those in:
- Auth is refused before TLS. The relay will not accept
AUTHon a plaintext connection — on 587 the session must upgrade via STARTTLS first, on 465 it is encrypted from the first byte. Your API key is never on the wire in the clear. - This ingress arms at launch. The relay is built and tested, but live SMTP submission opens with GA. Today, evaluate against the sandbox via the REST API — sandbox keys (ef_sandbox_…) that run the real pipeline dry: real validation, real rendering, real events, a hosted capture inbox — and no email leaves — and stage your config change for launch day.
Nodemailer
import nodemailer from "nodemailer";
const transport = nodemailer.createTransport({
host: "smtp.emailfast.dev",
port: 587,
secure: false, // 587 = STARTTLS; set true with port 465 for implicit TLS
requireTLS: true, // never fall back to plaintext
auth: {
user: "your-project",
pass: process.env.EMAILFAST_API_KEY,
},
});
await transport.sendMail({
from: "you@yourdomain.com",
to: "ada@example.com",
subject: "Welcome",
html: "<h1>Hi Ada</h1>",
headers: { "Idempotency-Key": "welcome-ada-1" }, // retry-safe, per recipient
});Any other app
Most software takes the same five values, whatever it calls them:
SMTP_HOST=smtp.emailfast.dev
SMTP_PORT=587 ; or 465
SMTP_ENCRYPTION=starttls ; "tls"/"ssl" if your app means implicit TLS on 465
SMTP_USERNAME=your-project
SMTP_PASSWORD=ef_live_...What happens to the message
SMTP here is an ingress, not a bypass. Each recipient in the envelope is admitted individually through the same checkpoint as an API call — 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.
That per-recipient admission carries idempotent retry semantics: pass an Idempotency-Key header and a client that reconnects and resends after a dropped connection cannot double-send: 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.