Email Domains and Setup
Pick the email setup for where you deploy: register a domain on an SDK platform, or configure email in your own Cloudflare account. To use the platform's shared sender, see Sending email.
On this pageRegister a sending domain · Configure email in your own Cloudflare account · Verify DNS records
Your own domain on the platform
Requires: login or token
Email commands need a signed-in platform or Cloudflare connection.
The shared sender uses the platform's mail domain. This step registers your own Cloudflare zone with the project, so you can send and receive on it.
void email domain add acme.comExample output: The DNS records to add for the domain.
add opens a Cloudflare API-token template. Restrict the token to the selected account and mail zone before you create it. Workers Scripts permission covers the whole account. The CLI accepts a masked paste or a newly copied token and asks you to confirm those restrictions. The platform encrypts the credential for the zone connection, so projects sharing that zone do not need separate ingress Workers.
Platform-managed custom inbound email requires the apex of a Cloudflare zone. Cloudflare’s catch-all covers only the apex. A subdomain cannot receive arbitrary addresses. Choose an apex without another mail provider, or use the platform’s shared mail address. The SDK preserves foreign MX records and enabled catch-alls. Each custom apex belongs to one project; a project can register more than one apex.
If setup stops, check the saved operation with void email domain status <domain> before you retry.
void email domain status <domain> reports three independent results:
- Inbound: whether mail can reach the project's handlers.
- Outbound: whether sending is ready, restricted to verified destinations, pending, or blocked.
- Management: whether the stored Cloudflare credential can manage the connection.
void email domain sync <domain> finishes setup and refreshes readiness. The status lists any remaining dashboard or credential steps. Use rotate-secret to rotate the connection secret after inbound is ready, or remove to detach the domain. Revoke unused API tokens in Cloudflare. See Email domain commands.
Once inbound is ready, mail to any address on that domain reaches your email/ handlers. Sending to arbitrary recipients also needs outbound readiness. A domain limited to verified destinations still needs recipient verification. Platform quotas and suspension apply to both shared and custom senders.
On an administrator-managed platform, add prints the administrator command for new domains. Existing owner-managed connections remain available to their owner. Your administrator may allow shared-sender mail to some recipient domains or to anyone. Destinations on the platform's shared mail domain still need verification.
Your own Cloudflare account
This step sets a sender on a Cloudflare zone you own.
import { defineConfig } from 'void/config';
export default defineConfig({
email: { from: 'Acme <support@mail.acme.com>' },
});Use a mail subdomain to keep existing acme.com mail with its current provider. The SDK refuses to replace another provider's MX records.
Setup
Sign in with void cloudflare login, or use a CLOUDFLARE_API_TOKEN with Email Routing Edit and Email Sending Edit in addition to deploy permissions. If your browser session lacks email permissions, log out and sign in again. Global API Keys are not supported.
Run void deploy --platform cloudflare. The SDK shows the domain, routing, sending, DNS, and handler addresses it would configure. Accept to set up email and deploy. Later deploys reuse the setup. If you decline the initial setup, the app deploys without email.
Without email.from, the SDK skips automatic setup. It keeps your own cloudflare.send_email bindings and cloudflare.addresses. Check their readiness yourself. --require-email still refuses deployment when automatic setup cannot be verified.
If subdomain setup needs a dashboard step, follow the checklist under Email → Settings → Subdomains, then retry. This step checks readiness after DNS changes.
void email status --platform cloudflareExample output: The email configuration and verification state.
Inbound addresses
With email.from on mail.acme.com, handlers receive:
| Handler | Subdomain address | Zone apex address |
|---|---|---|
support.ts, support+[ticket].ts | support@mail.acme.com | support@acme.com |
_default.ts | No catch-all rule | *@acme.com |
[user].ts, [user]+[tag].ts | Not supported | *@acme.com |
Cloudflare catch-alls cover only a zone apex. On a subdomain, _default.ts handles mail admitted by an explicit rule. It cannot receive arbitrary addresses.
Setup turns on plus addressing for the zone, so support+T-42@mail.acme.com reaches support+[ticket].ts. This setting also applies to the apex and other subdomains.
replyEmail() defaults its sender to the address that received the message. Forwarding requires a verified Cloudflare destination.
Sending
On Workers Free, sendEmail() can send to verified destinations listed under Email Routing → Destination addresses in Cloudflare.
Configure your sender domain's SPF, DKIM, and DMARC records using Cloudflare's email authentication guidance, then check the authentication results in a received message's original headers. A successful sendEmail() result confirms provider acceptance; it does not confirm delivery or authentication readiness.
Sending to arbitrary recipients requires Workers Paid and Email Sending onboarding. This step finishes onboarding after you upgrade. Ordinary deploys do not retry it.
Existing DMARC or bounce-domain records can block onboarding. The checklist names the conflicts. Inbound mail remains available.
The void email usage, logs, destinations, allow, and disallow commands apply to SDK platforms.
Configuration changes
Commit void.lock.json after setup. The SDK derives routing addresses from your handlers and creates their rules during deployment.
Existing rules owned by another Worker or forwarding service are left in place. If you manage cloudflare.addresses yourself, follow the checklist. Do not combine it with automatic setup.
After deleting a handler, review the reported stale address and set the desired cloudflare.addresses. Deleting a routing rule requires confirmation in an interactive terminal.
To remove all email setup, take three steps. Remove addresses, send_email and vars.__VOID_EMAIL_FROM from resolved in void.lock.json. Remove the matching overrides in void.config.ts. Delete the routing rules in Cloudflare.
CI
This step sets up email locally first.
void email setup --platform cloudflare
void email status --platform cloudflareExample output: Email routing configured, then its current status.
This step deploys in CI after you commit void.lock.json.
void deploy --platform cloudflare --require-emailExample output: The deploy completes, or stops if email is not ready.
CI cannot answer setup prompts. Without --require-email, an unconfigured app can deploy without email. If setup is saved but DNS has not propagated, deploy waits for a later retry. Workers Free setup for verified recipients satisfies --require-email.