Cloudflare Email
Business email without SMTP or IMAP for Frappe, ERPNext, Odoo and WordPress, built on the Cloudflare Email Sending API and a store-first relay Worker.
On this page
Cloudflare Email is a set of four open-source projects that give business systems email without SMTP credentials or IMAP polling. Outgoing mail goes from your system straight to the Cloudflare Email Sending API. Incoming mail goes through Cloudflare Email Routing to a relay Worker, which stores every message in R2 before it delivers it to the Odoo or Frappe system that owns the recipient's domain as a signed HTTPS request. An outage on your side delays a message instead of losing it.
This site documents the whole suite. The relay is the project in this repository, cloudflare-email-relay; the three adapters live in their own repositories and are covered by the adapter guides.
The four projects
| Project | What it does |
|---|---|
| cloudflare-email-relay | The inbound Worker: stores each message in R2, then delivers it to the right system with signed retries. See Deploying the relay. |
| cloudflare_email_delivery | The Frappe and ERPNext adapter: sends through the API and receives from the relay. See Frappe and ERPNext. |
| mail_cloudflare | The Odoo adapter: sends through the API and receives from the relay. See Odoo. |
| wordpress-cloudflare-email | The WordPress plugin: sends every wp_mail() message through the API and keeps a log, outbound only. See WordPress. |
Which ones you need depends on the system and on whether it must receive mail:
| System | Sending | Receiving |
|---|---|---|
| Odoo 18 | mail_cloudflare | mail_cloudflare plus the relay |
| Frappe 16 and ERPNext | cloudflare_email_delivery | cloudflare_email_delivery plus the relay |
| WordPress | cloudflare-email plugin | Not supported: the plugin is send-only |
How a message travels
OUTBOUND
Odoo / Frappe / WordPress
-> Cloudflare Email Sending API (one HTTPS call per message or recipient)
-> the recipient's mail server
INBOUND
sender's mail server
-> Cloudflare Email Routing ("Send to a Worker")
-> relay Worker: look up the domain, store the message in R2, queue it
-> that tenant's Durable Object: signed HTTPS POST to the system
-> Odoo or Frappe answers; the relay marks the message delivered,
retries it later, or parks it for an operatorThe ordering on the inbound path is the point of the design: the message is on disk before anything tries to deliver it. How the suite works explains each step and the limits to plan around.
Start here
Understand the design first. Read How the suite works.
Stand up the relay. Follow Deploying the relay, then describe each system as a tenant in Tenants and secrets.
Connect a system. Pick the Frappe and ERPNext, Odoo or WordPress guide.
Something is not arriving. Go to Troubleshooting, which starts from the symptom.
Operate a running relay. The Ops API reference lists every route, row field and log event.
Build another receiver. The Inbound contract specifies the request the relay sends and the answers it understands.
What you need
A Cloudflare account with the domains you send and receive for. Email Routing can only hand mail to a Worker in the same account as the zone, which decides between a shared relay and a dedicated Worker for a client who owns their own Cloudflare account.
The Workers Paid plan for the relay, because it uses Durable Objects. The Odoo and Frappe adapters also list the Workers Paid plan as a requirement for Email Sending.
For the adapters: Odoo 18, Frappe 16, or WordPress 7.0 with PHP 8.4 (the versions the projects declare today).
Cloudflare's own documentation covers onboarding a domain for Email Sending and enabling Email Routing: see the Cloudflare Email Service documentation. These guides cover the Avunu projects and link to Cloudflare for the rest.
Need it set up?
Avunu runs this suite for clients as part of managed infrastructure and can wire it into an Odoo, ERPNext or WordPress site: see avunu.net.