Email Routing (incoming)
Cloudflare Email Routing accepts mail for your domain at Cloudflare's MX servers and forwards it according to rules you configure. Lumen uses the "Send to a Worker" action: every routed message is invoked as the Worker's email() handler.
Worker handler
worker/index.ts exports an email() handler that delegates to worker/email.ts. The handler:
- Looks up the
toaddress in theaddressestable. - If no Lumen user owns the address, calls
message.setReject(...)so the sending server gets an SMTP rejection. - Otherwise parses the raw MIME with
postal-mime, stores the metadata in D1, the raw.emlin R2 underraw/<userId>/<messageId>.eml, and each attachment underatt/<userId>/<messageId>/<attachmentId>. - Updates the contact list for the recipient with the sender.
Setting up routes
In the Cloudflare dashboard:
- Email → Email Routing → enable for your domain. Cloudflare will add the MX and SPF records.
- Routes → Create address. Pick
Send to a Workerand select thelumenWorker. - To accept any address, use Catch-all address with the same destination.
Catch-all
Lumen rejects unknown recipients by default. Enabling a catch-all route is fine — Lumen will still drop messages whose To: address is not registered to a user.
Adding addresses to a user
Each Lumen user lists their accepted addresses in Settings → Addresses. The first address added is automatically the primary. The primary address is the default sender when composing.
Verified destinations
Cloudflare Email Routing only delivers to verified destination addresses for non-Worker routes. Worker routes have no verification requirement, so any domain you control on Cloudflare can be used here.
Inbound size limit
Cloudflare currently caps inbound messages at ~25 MB. Lumen stores the exact raw bytes it receives, so make sure your D1 row size budget and R2 storage are sized appropriately.