hello@yourdomain.com. Cloudflare Email Routing hands each message to a small Worker in your Cloudflare account. The Worker keeps the raw message and attachments in a private R2 bucket and the mailbox index in D1. Xem reads it through a signed API. No IMAP server, and no mail stored on Xem’s side.
Receiving and reading fit inside Cloudflare’s free allowances. Replying needs a sender, and Cloudflare’s own sending is not on the free plan. The cost section has the details.
This guide was checked against Cloudflare’s documentation on November 5, 2026.
On a self-hosted install with no billing configured, this feature has no plan requirement. On Xem Cloud, Cloudflare email comes with a paid plan.
What it costs
These are Cloudflare’s published numbers. Cloudflare bills you directly; Xem charges nothing for this on a self-hosted install.
What that means in practice:
- Receiving and reading are free within the limits above. R2 still asks you to add a payment method and complete an R2 subscription checkout before you can create a bucket, even if you stay on the free allowance (R2 get started).
- Replying is not free through Cloudflare. Cloudflare Email Sending to arbitrary recipients needs Workers Paid. You can reply through any other sender you have connected in Xem instead, such as Amazon SES.
- Newsletters and campaigns do not go through Cloudflare. Xem only uses Cloudflare Email Sending for transactional mail and rejects campaigns on that sender. Send newsletters through an SMTP provider such as Amazon SES.
- Large messages may not fit Workers Free. The Worker parses each message inside the 10 ms CPU limit of Workers Free. We have not measured where that limit bites; a message that exceeds it fails with
EXCEEDED_CPUin the Worker logs. Workers Paid raises the CPU limit. Separately, the Worker rejects raw messages over 10 MiB and messages with more than 32 attachments, below Email Routing’s own 25 MiB limit (Email Service limits). - When D1 hits its daily limit, queries fail until the limit resets (D1 pricing). The Worker writes each raw message to R2 before it touches D1 and retries pending messages every minute, so mail that arrives then is kept and indexed later.
Before you start
You need:- a Cloudflare account;
- a domain whose DNS is on Cloudflare, with Email Routing enabled;
- R2 enabled on the account (the subscription checkout mentioned above);
- a running Xem install. See Self-hosting.
1. Make a secret
Xem and the Worker share a secret that signs every request. Generate a long random one and keep it for steps 2 and 4:2. Deploy the Worker
Pick one of the two ways.With the Deploy to Cloudflare button
MAILBOX_ADDRESS: the full address you want to receive, such ashello@yourdomain.com;MAILBOX_API_SECRET: the secret from step 1.
https://xem-cloudflare-mailbox.<your-subdomain>.workers.dev.
With Wrangler
You need Node.js 24 and pnpm 10.3. Route the address to the Worker
In the Cloudflare dashboard, open your domain, then Email → Email Routing → Routing rules.- Select Create address.
- Enter the same address you used for
MAILBOX_ADDRESS. - Set the action to Send to a Worker and choose
xem-cloudflare-mailbox. - Save.
MAILBOX_ADDRESS must match exactly (case does not matter).
4. Connect it in Xem
In Xem, go to Settings → SMTP senders and select Connect Cloudflare inbox. Enter:- Worker URL: the URL from step 2;
- Mailbox address: the same address as
MAILBOX_ADDRESS; - Mailbox API secret: the secret from step 1.
5. Send yourself a message
From another mail account, send a message to the address. It shows up in Inbox under that mailbox. You can mark messages read or starred and search by subject, sender, recipients or Message-ID. To reply, pick a sender in the compose window. A Cloudflare inbox has no sender of its own. Replies keep theIn-Reply-To header, so they thread in the recipient’s mail client.
Troubleshooting
To change the address later, update the
MAILBOX_ADDRESS secret on the Worker and the routing rule, then reconnect in Xem.
What has been tested
The Worker’s test suite, awrangler deploy --dry-run, and a local wrangler dev run that delivered a message through the local email handler and read it back over the signed API. The Xem settings flow was checked against a local backend. The Xem team has not yet confirmed live Email Routing delivery through the Deploy to Cloudflare button; if something in these steps does not match what you see, please open an issue.
For how the Worker stores, retries and quarantines mail, see Cloudflare mailbox Worker.