Self-Hosted Email API on Cloudflare
v0.1 · public preview

Self-Hosted Email API on Cloudflare

Flowmails is a self-hosted email API that runs entirely on Cloudflare. Send and receive email through a simple REST API, with your inbox and outbox stored in your own D1 database — no SMTP server to manage, no shared inbox, and webhooks for every event.

Inbox and outbox live in your own D1, attachments in your R2, and outbound sends go through Cloudflare Email Services — no SMTP relay, no shared multi-tenant table, no third-party lock-in. The default route table catches every inbound; route templates fan out to Slack, your CRM, or any Workers webhook; AI draft + reply (Q3 2026) lives one click away from any inbound.

Built on CloudflareWorkersEmail RoutingEmail ServicesYour D1
~/flowmails — wrangler tail
[runtime] flowmails-worker connected  flowmails.net → D1 (WEUR)› inbound POST /webhook  200 OK  in 38ms› D1 row inserted: messages.id=8421› routing rule matched: support@yourdomain.com → D1› AI draft queued (Workers AI, ~1.2s)

Runtime: platform-servicesD1: PLATFORM_DBR2: unbound

Runtime · at a glance

Inbound, worker, D1. Outbound, the same worker.

Every Flowmails message traverses the same runtime: Email Routing captures inbound mail, your Worker writes it to your D1, and Email Services handles the outbound side. There is no shared multi-tenant table, no SMTP relay to operate.

Email Routing
Workers
D1
R2
Email Services
Rspamd
Flowmails runtime diagram: inbound mail, worker, D1, R2, outbound mail.Inbound mail arrives at Cloudflare Email Routing, forwards to a Worker in your account, which writes to D1 (your database) and R2 (attachments). Outbound mail flows from the Worker through Cloudflare Email Services back to the sender.SenderSMTP / HTTPEmail RoutingCloudflareEmail ServicesOutboundWorkeryour accountD1messagesR2attachmentsInboxsupport@

Why teams pick Flowmails

Self-hosted email, an API your service can call, and AI on the way.

01Setup speed
60s to first inbox
02Data residency
100% on your D1
03Automation
REST + Webhook API
04AI workflow
Draft & reply (Q3 2026)

How it works

From Cloudflare token to first inbound message in about a minute.

01

Connect your Cloudflare account

Paste a scoped API token. Flowmails provisions a Worker in your account, claims the D1 database, and prepares the R2 bucket for attachments — none of which leaves your Cloudflare.

02

Add your custom domain

Pick a zone you already host on Cloudflare. DNS records are detected automatically; you approve the routing rules and the zone flips to active in under a minute.

03

Send, receive, and automate

Use the dashboard for human workflows, or hit the REST API from your service code. Webhooks stream inbound events as they happen; messages and rules live in your D1.

Try the API

Send your first email in five minutes.

Three copy-paste examples for the runtimes you actually use — pick one, paste it, ship. Every example targets the same wire endpoint running in your Cloudflare account, with the inbox and outbox landing in your D1.

What you get

Four guarantees your email layer is built on.

01Foundation

Run a self-hosted email API on your Cloudflare account

Every inbox, outbox, and routing rule is stored in the D1 database of the Cloudflare account you control. No vendor holds your correspondence, no shared multi-tenant table, and no migration tax if you ever leave.

wranglerbash
$ wrangler d1 create flowmails
✅ Successfully created DB 'flowmails'
   id = 8421ce9c-1f44-4c8d-b9a3-d6f5fc20ab3a
02Delivery

Send and receive from your custom domain through an API on Workers

Inbound mail is captured by Cloudflare Email Routing and forwarded through your Worker. Outbound mail is sent through Cloudflare Email Services with your domain's sender reputation tied directly to your zone.

curlbash
$ curl -X POST https://flowmails.net/api/v1/messages \
    -H "Authorization: Bearer fm_live_…" \
    -d '{"to":"hi@yourdomain.com","subject":"hi"}'
{ "id": "msg_8421", "status": "queued" }
03Automation

Wire the inbox into your product with a REST API

List messages, send mail, manage routing rules, and rotate API keys over HTTPS. Webhooks fire on inbound events so your backend can react in real time without polling.

POSTbash
POST /api/v1/webhooks
{ "event": "inbound.received",
  "domain": "yourdomain.com",
  "message_id": "msg_8421" }
04AI

AI draft and reply, scoped to your data

Coming in Q3 2026: model-backed drafting, auto-reply, summarization, and routing. Inference runs on Workers AI by default; your prompt templates and history stay in your D1.

draft.jsonbash
{ "model": "@cf/meta/llama-3-8b-instruct",
  "scope": "domain:yourdomain.com",
  "prompt": "draft reply to support ticket #8421",
  "data_residency": "your-d1" }

Who it's for

Picked by teams who can't outsource the inbox.

01

Indie developers

Run a self-hosted email API on Cloudflare from a single Worker. Send transactional mail from `hello@yourdomain.com` without ever touching an SMTP relay.

02

SaaS support teams

Run a self-hosted email API for support@, billing@, and abuse@ in your own D1, then pipe events into your CRM through webhooks.

03

Agencies and studios

Manage a self-hosted email API for every client from one dashboard. Per-client Workers, per-domain API keys, and isolation you can show in a SOC 2 review.

04

Privacy-sensitive products

When the requirement is 'email data never leaves our infrastructure', a self-hosted email API on Cloudflare is the answer — not a marketing claim.

05

Transactional email API

Send order confirmations, password resets, and receipts from a self-hosted email API on Cloudflare Workers — no SMTP relay, no separate SaaS.

Coming Q3 2026

AI draft and reply, scoped to your data.

Drafting, auto-reply, and summarization run on Workers AI by default. Your prompt templates, the messages used as context, and the resulting drafts all stay inside your D1. Disable AI per-domain or wire a different model provider.

Workers AI
Per-domain
Your prompts stay in D1
draft.jsonjson
{ "model": "@cf/meta/llama-3-8b-instruct",
  "scope": "domain:yourdomain.com",
  "prompt": "draft reply to support ticket #8421",
  "data_residency": "your-d1" }
Spam filtering

Rspamd spam filtering is now live on every inbound message.

Flowmails now integrates Rspamd, the high-performance open-source spam, phishing, and malware classifier, as the default scanner for every inbound message. The moment Cloudflare Email Routing hands a message to your Worker, Rspamd scores it against its rulesets: reject-classified mail is quarantined into a dedicated Junk tab and never reaches the live inbox, while borderline messages stay in Inbox with the verdict and offending symbols surfaced in the reading pane. Classification runs inside your account — message bodies never leave your D1.

Rspamd
Spam + phishing + malware
Inline classification
Per-message audit
Fail-open

The classifier runs in ctx.waitUntil after the receive handler returns, so Inbox latency is unchanged. If Rspamd is unreachable the email stays delivered — the system fails open rather than drop a real message because the scanner hiccupped.

rspamd.jsonjson
{
  "is_skipped": false,
  "score": 24.4,
  "required_score": 15.0,
  "action": "reject",
  "thresholds": { "reject": 15, "add header": 6, "greylist": 4 },
  "symbols": {
    "RBL_SPAMHAUS":   { "score": 8.5 },
    "URIBL_BLACK":    { "score": 6.0 },
    "MISSING_TO":     { "score": 2.0 },
    "MIME_HTML_ONLY": { "score": 1.0 }
  }
}

FAQ

The questions buyers ask before they sign a Cloudflare token.

From the journal

Operator notes on Cloudflare-native email.

Flowmails runtime diagram: inbound mail, worker, D1, R2, outbound mail.Inbound mail arrives at Cloudflare Email Routing, forwards to a Worker in your account, which writes to D1 (your database) and R2 (attachments). Outbound mail flows from the Worker through Cloudflare Email Services back to the sender.SenderSMTP / HTTPEmail RoutingCloudflareEmail ServicesOutboundWorkeryour accountD1messagesR2attachmentsInboxsupport@

Ship it on your Cloudflare

Bring your domain. Keep your data.

Self-hosted email in your Cloudflare account, live in about a minute. The Worker, the D1, the R2 — all yours.