Every app I’ve ever built eventually needed to send an email. A welcome message. A receipt. A password reset. A notification from an agent.
And every single time, that meant reaching for a third party: SendGrid, Mailgun, Amazon SES, Postmark. Sign up, verify a domain, generate an API key, paste it into a secrets store, install an SDK, wire up a client. Then spend an afternoon fighting SPF and DKIM records until your test emails stop landing in spam.
Cloudflare’s Email Service deletes that entire checklist. I added live, authenticated email sending to saltwaterbrc.com with one binding and one line of code — no API key, no SDK, no third party. And because Cloudflare already runs my DNS, it configured SPF, DKIM, and DMARC for me automatically.
Here’s exactly how it works — and there’s a live demo at the bottom you can try with your own inbox.
The whole integration: one binding, one line
In a normal stack, “send an email from your backend” is a project. On Workers, it’s a binding.
Here’s the entire Wrangler config change:
{
"send_email": [{ "name": "EMAIL" }]
}
And here’s the entire send:
const { messageId } = await env.EMAIL.send({
to: "you@example.com",
from: "demo@send.saltwaterbrc.com",
subject: "👋 Sent live by Cloudflare Email Service",
html: "<h1>Hello from the edge</h1>",
text: "Hello from the edge",
});
That’s it. No Authorization header. No secret to rotate. No npm install. The EMAIL binding is the credential — scoped, managed, and invisible. The Worker calls send() and Cloudflare’s network handles delivery.
When I first ran it, I genuinely double-checked that I hadn’t forgotten a step. I hadn’t.
The part that normally ruins your week: authentication
If you’ve ever set up transactional email, you know the real pain isn’t the API call — it’s deliverability. Get SPF, DKIM, or DMARC wrong and your mail silently rots in spam folders. These are fiddly DNS records that every provider documents slightly differently, and you usually only find out you got them wrong when a customer says “I never got the email.”
Because Cloudflare already manages my DNS, onboarding a sending domain added all three automatically. I picked a subdomain — send.saltwaterbrc.com — clicked through, and watched these appear in my DNS table without typing a single record:
- SPF —
v=spf1 include:_spf.mx.cloudflare.net ~all— declares Cloudflare’s servers as authorized senders - DKIM — a public key so receiving servers can verify each message is cryptographically signed and untampered
- DMARC —
p=rejecton the sending subdomain — the strictest policy, telling receivers to reject anything that fails the checks
That last one is worth a pause. I set the sending subdomain to p=reject — the most aggressive DMARC policy — without hesitation, because only Cloudflare sends from send.saltwaterbrc.com. Nothing legitimate will ever fail, so there’s no reason to be lenient. My main domain stays on a cautious p=none (it carries real Google Workspace mail), but the dedicated sending subdomain is locked down hard. Separating the two is the whole trick.
Why a subdomain, not the main domain
This is the detail that makes the whole thing safe to ship. My primary email — brandon@saltwaterbrc.com — runs on Google Workspace, with an MX record pointing at Google’s servers. Outbound sending lives entirely on the send. subdomain and never touches that MX record.
The payoff is reputation isolation. If this public demo ever gets abused, it’s send.saltwaterbrc.com that takes the deliverability hit — not my real domain. My actual inbox keeps working no matter what happens to the demo. Transactional and human email should never share a sending reputation, and a subdomain gives you that separation for free.
The agent angle
There’s a reason Email Service launched during Agents Week. AI agents running on Workers increasingly need to act — and “send the user an email” is one of the most common actions there is. A research agent emails you the report. A monitoring agent emails you the alert. A booking agent emails you the confirmation.
Before, that meant wiring an external email provider into your agent’s tool list, with all the key management that implies. Now it’s just another Worker binding the agent can call. The agent sends email as natively as it reads from a database or queries a vector index. No third party in the loop, nothing to leak, nothing to rotate.
The demo: prove it with your own inbox
Talk is cheap, so I built a live one. On the Email Service demo page, you enter your email address, and a Worker sends you a real message — right now, from the edge.
The email you receive isn’t a generic “hello.” It’s a delivery trace of the exact message you’re reading: the timestamp, the Cloudflare data center that processed your request, your connection’s HTTP and TLS versions, the sending address, and a note on how it was authenticated. Everything in it is genuinely captured at send time.
What it deliberately doesn’t do is claim “DKIM: pass ✓” in the body — because that verdict is computed by your mail provider after delivery, not by the sender. So instead, the email points you to your client’s “Show original” view, where you can see the real DKIM signature and the SPF/DMARC pass results your provider computed. Don’t take my word for it; read the headers.
Built to send safely, with the rest of the platform
A public “email anyone” endpoint is also a public spam cannon if you build it naively. So the demo is wrapped in three other Cloudflare products, each doing one job:
- Turnstile verifies you’re human before the send fires — no bot gets through.
- Rate Limiting caps it at one send per IP per 24 hours.
- Fixed templates + single recipient mean you control only the destination address — never the message content, never a list of recipients. The worst-case abuse is one branded hello-email to one address, which Cloudflare’s own suppression list then catches.
That’s four products — Email Service, Turnstile, Rate Limiting, and Workers — collaborating behind a single button. Which is really the whole point of building on one connected platform: the pieces are designed to snap together.
What got deleted
The best features are the ones that remove work. Adding email to this site didn’t add a vendor, a dashboard, a monthly bill, an API key, or a deliverability project. It added one binding and one line.
That’s product number 35 running in production on saltwaterbrc.com — and the first one whose main selling point is everything it let me not do.