Simple Inbox
A private, self-hosted inbox on one Cloudflare Worker.
Simple Inbox is a clean-room mail workspace that runs as one Cloudflare Worker named
simple-inbox-cf. One deployment serves the web app and API, receives Email Routing events, and
runs scheduled retention.
browser ---- fetch() ----> simple-inbox-cf ----> D1
Email Routing -- email() ------| private R2
Cloudflare Cron -- scheduled() ----------------> Email SendingD1 holds queryable mailbox state. A private R2 bucket holds canonical raw .eml objects. The
browser reaches both only through authenticated API routes.
What is included
- Passwordless owner sign-in with one-time magic links.
- Thread, search, archive, unread, workflow, compose, and reply flows.
- Canonical raw-message and attachment download after mailbox authorization.
- Inbound capture, owner forwarding, opaque reply aliases, and outbound Email Sending.
- Durable send idempotency and explicit
unknowndelivery state. - Bounded daily retention across private R2 and D1.
- A first-run
/setupwizard for owner, mailbox, origin, mail domain, and retention settings. - Embedded OpenAPI and operator/security documentation.
First deployment
The root Wrangler config declares one Worker plus D1, R2, Email Sending, rate limiting, and a daily cron. Wrangler provisions D1/R2, and the root deploy task builds, migrates, and deploys:
vp run deployThis is a remote, state-changing command. Before using it, follow the local verification and account checks in Deployment. Cloudflare also requires Email Routing to be enabled and one owner-controlled destination verified before it can attach the Worker's email binding.
Create two independent secret values of at least 32 random bytes:
AUTH_TOKEN_PEPPERprotects authentication-token digests;SETUP_TOKENauthorizes the first-run wizard.
After deployment, open the chosen HTTPS origin at /setup. For a synthetic local test, use values
such as owner@example.test, mail.example.test, and inbox@mail.example.test. Setup writes all
installation records atomically; until it succeeds, protected APIs fail closed, inbound mail is
rejected, and retention stays idle.
Email Sending domain verification, a private R2 lifecycle rule, and Email Routing activation remain explicit Cloudflare Dashboard owner steps.
Future one-click deployment
After the source repository becomes public, this link can launch Cloudflare's deployment flow:
Deploy Simple Inbox to Cloudflare
Deploy to Cloudflare does not work for other users while the source repository is private.
Routes
/setup— required only before the first installation completes./sign-inand/auth/verify— passwordless authentication./inbox— authenticated mail workspace./docs— this public guide./api/v1/health,/api/v1/capabilities,/api/v1/openapi.json— public service metadata.- Other
/api/v1/*inbox routes — authenticated and mailbox scoped.
The mail package's /internal/* Hono routes are in-process infrastructure and are never exposed by
the public Worker router.
Continue reading
- Deployment — deploy, complete setup, configure Cloudflare, test, and recover.
- Architecture — the single-Worker runtime and logical module boundaries.
- Security — secrets, authorization, privacy, retention, and incident safeguards.
- API — versioned contracts and error behavior.