Prompt
How to send email from Cloudflare Workers
Latest observation
You can send email directly from Cloudflare Workers using Cloudflare’s native Email Service bindings. This avoids external SMTP servers and lets you send mail securely via HTTPS with built-in SPF/DKIM/DMARC support once your domain is onboarded.
🛠 Steps to Send Email from Cloudflare Workers
Onboard your domain
Go to Cloudflare Dashboard → Compute → Email Service → Email Sending.
Select your domain and let Cloudflare add DNS records:
MX for bounce handling
TXT for SPF
TXT for DKIM
TXT for DMARC
Configure Wrangler bindings
Add an email binding in your wrangler.toml or wrangler.jsonc:
toml
[[send_email]]
name = "EMAIL"
remote = true
Write Worker code
Example in src/index.ts:
ts
export default {
- async fetch(request: Request, env: Env): Promise<Response> {
const response = await env.EMAIL.send({
- to: "recipient@example.com",
- from: "welcome@yourdomain.com",
- subject: "Welcome to our service!",
- html: "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
- text: "Welcome! Thanks for signing up."
});
- return new Response("Email sent: " + response.messageId);
}
}
Handle attachments
You can include base64-encoded files in the attachments array. Total message size must not exceed 5 MB.
Monitor errors
Use try/catch around env.EMAIL.send() to log error codes and messages.
⚠️ Important Notes
-
Recipient limits: Max 50 recipients per email (including To, CC, BCC).
-
Domain requirement: You must use Cloudflare DNS for the sending domain.
-
Propagation time: DNS changes usually take 5–15 minutes, but may take up to 24 hours globally.
-
Local dev caveat: Binary attachments don’t serialize properly in wrangler dev without remote bindings.
✅ Best Use Cases
Transactional emails (welcome, password reset, invoices).
Notifications directly tied to Worker logic (alerts, confirmations).
Lightweight marketing campaigns (though transactional focus is stronger).