Skip to content

Section

Tutorials

Step-by-step, hands-on guides for standing up and operating your own email stack on Cloudflare. 37 articles

Generate and rotate DKIM keys for sending on Cloudflare
tutorialsSep 2, 2026

Generate and rotate DKIM keys for sending on Cloudflare

DKIM (DomainKeys Identified Mail) lets a receiver confirm that mail claiming to be from your domain was signed by someone holding your private key, and that the signed parts were not altered in transit. It is half of what DMARC needs to pass (SPF being the other half), and on a new sending domain it is non-negotiable: Gmail and Yahoo bulk sender rules treat missing DKIM as a reason to throttle or reject. It is one box on the Gmail and Yahoo bulk sender checklist you have to clear before a first campaign.

Email to task automation: turn inbound mail into actions
tutorialsAug 31, 2026

Email to task automation: turn inbound mail into actions

Email to task automation is the practice of reading each inbound message, deciding whether it implies an action, extracting the fields that action needs, and creating the task (or firing the webhook) without a human retyping anything. The mail is structured data wearing a text costume. The job is to undress it once, reliably, and route it.

Email for AI agents: give your agent its own address and inbox
tutorialsAug 28, 2026

Email for AI agents: give your agent its own address and inbox

To give an AI agent its own email, you provision a real address ( agent@yourdomain.com ), route inbound mail to a handler that stores it, and expose both reading and sending as scoped tools the agent can call. The agent becomes the principal: it owns the mailbox, reads through typed tools instead of a screen, and sends from its own address over an HTTPS API. This guide builds the whole thing the hard way first (MX routing, MIME parsing, a message store, an HTTPS send path, and a scoped tool layer), then shows the one-command version at the end.

Self-hosted email tracking: open and click tracking that respects privacy
tutorialsAug 26, 2026

Self-hosted email tracking: open and click tracking that respects privacy

Email analytics is one of the few places where the "just use the vendor" answer quietly costs you something real: every open pixel and every wrapped link in a typical campaign points at the vendor's tracking domain, not yours. That means your subscriber list, their open behavior, and their click behavior all pass through someone else's infrastructure. For a transactional receipt that might be fine. For a newsletter you are trying to keep private, or a product where subscriber behavior is sensitive, it is a leak you signed up for without noticing.

Build a SaaS onboarding email sequence triggered by product events
tutorialsAug 24, 2026

Build a SaaS onboarding email sequence triggered by product events

"Send a welcome email" is trivial. "Send a five-step onboarding sequence that branches on behavior and shuts up when the user converts" is a small state machine running once per user, and that is where the real work lives. The naive version, a cron that fires "day 3" email to everyone who signed up three days ago, is worse than nothing: it emails people who already activated, it double-sends when invocations overlap, and it keeps drip-ing users who long since converted.

Process bounce and complaint webhooks into a suppression list
tutorialsAug 21, 2026

Process bounce and complaint webhooks into a suppression list

Bounce and complaint webhooks are not the hard part. Providers (Resend, Postmark, SendGrid, SES) all emit them, and receiving an HTTP POST is trivial. The work is the loop after the POST: verify the payload is real, classify what kind of failure it is, decide whether the address gets one strike or several, write it to a suppression list, and (the step everyone forgets) check that list before the next send. This tutorial builds that whole loop by hand on Cloudflare Workers and D1, including the failure modes that quietly let suppressed addresses slip back into your sends. At the end, the shortcut if you would rather register the flow than maintain it.

How to check SPF, DKIM, and DMARC are actually passing
tutorialsAug 19, 2026

How to check SPF, DKIM, and DMARC are actually passing

The only way to know SPF, DKIM, and DMARC are actually passing is to read the Authentication-Results header on a message that a real receiver accepted. Send a test email to an account you control at Gmail or Outlook, open the raw source, and read the spf= , dkim= , and dmarc= verdicts the receiver wrote. A green checkmark in a vendor dashboard tells you a DNS record exists. The Authentication-Results header tells you the record evaluated to pass against the IP you actually sent from, with the keys you actually signed with. Those are different facts, and the gap between them is where mail quietly goes to spam.

Email archival to R2 cold storage while keeping search working
tutorialsAug 17, 2026

Email archival to R2 cold storage while keeping search working

Email is append-only and mostly cold. You read a message once, maybe reply, and then it sits there forever. The bodies, especially the HTML ones, are by far the largest part of a message and the part you almost never look at again. Keeping all of that hot in your primary database is the email equivalent of renting climate-controlled storage for boxes you will never open.

Rate limiting your email API on Cloudflare Workers
tutorialsAug 14, 2026

Rate limiting your email API on Cloudflare Workers

An open send endpoint is the most dangerous route in your whole app. Not because of the bill (Workers and edge sending are cheap), but because volume is reputation. Senders earn deliverability slowly and lose it fast, and a runaway loop or a stolen token can burn through years of good behavior in an afternoon. A rate limit is one of several defenses that protect that standing; the rest are in the ways to build and protect your sender reputation, and a sudden unthrottled burst is itself one of the reasons transactional email lands in spam. The fix here is a per-caller rate limit that caps how much any one client can send in a window.

DMARC report analysis: reading aggregate reports without a paid tool
tutorialsAug 12, 2026

DMARC report analysis: reading aggregate reports without a paid tool

DMARC monitoring services exist because the raw reports are unfriendly: gzipped XML, one per provider per day, in a schema most people never learn. Those tools charge monthly to draw you a dashboard on top of data the providers already mail you for free. The dashboards are nice. They are also not necessary to answer the only questions that matter: who is sending as my domain, and is it authenticating?

Catch spam complaints with email feedback loops
tutorialsAug 10, 2026

Catch spam complaints with email feedback loops

A spam complaint is the strongest negative signal a recipient can send: they actively told their mailbox provider your mail is unwanted. Bounces you can infer from delivery failures, but complaints are invisible by default. The provider knows, and your reputation score reflects it, but you are never told which message or which recipient unless you enroll in that provider's feedback loop (FBL) . This tutorial sets up FBLs for the major providers, parses the resulting ARF (Abuse Reporting Format) reports by hand, and wires the complaining addresses into a suppression list. At the end I show how a Cloudflare-native stack turns the same ARF parsing into an inbound interpreter so you never touch the MIME by hand, but the mechanics below apply no matter what you send through.

Detect OTP and verification emails automatically
tutorialsAug 7, 2026

Detect OTP and verification emails automatically

OTP, 2FA, and verification emails are one of the few email categories with a clean, useful payload: a short code you want extracted and surfaced fast. The temptation is to write a five-line regex and move on. That regex works in the demo and then quietly matches Order #483920 in production. This post builds the detector properly: the two signals you actually need, the extraction logic, the eval suite that keeps it honest, and an LLM fallback for the cases regex cannot read. Then it shows the version Tinbox ships so you do not maintain any of it. OTP extraction is the friendliest of the email interpreter recipes for smarter inbound handling, so it is a good first one to wire up before the harder, tone-based interpreters.

Detect important email automatically with an interpreter
tutorialsAug 5, 2026

Detect important email automatically with an interpreter

Most "priority inbox" features fail the same way: they match urgency words in the subject line, so a marketing blast that screams "Act now, deadline tonight" scores exactly as high as a real escalation. The signal that actually predicts importance is not a word, it is a relationship plus an ask. This post builds an importance classifier the right way: the three independent signals, the gate that combines them, the eval suite that keeps it from flagging everything, and an LLM escalation for the ambiguous middle. Then it shows the version Tinbox ships as an interpreter, so the verdict drives a real priority view in your inbox.

Designing a D1 email database schema for an inbox
tutorialsJul 31, 2026

Designing a D1 email database schema for an inbox

D1 is SQLite at the edge, which is a genuinely good fit for an email inbox: mail is mostly read-heavy, append-mostly, and you want it co-located with the Worker that serves it. The hard part is not the database, it is the data model. Email has been accreting headers since 1982, threading is a graph not a tree, and bodies range from a one-line reply to a 25 MB newsletter with inline images. Get the model wrong and every list query gets slow or every thread renders out of order.

Wire a custom domain per tenant for client inboxes
tutorialsJul 29, 2026

Wire a custom domain per tenant for client inboxes

A custom domain per tenant means three separate jobs, and people usually only think about the first. You need inbound delivery (mail addressed to the client's domain reaches your handler), outbound authentication (mail you send from the client's domain passes SPF, DKIM, and DMARC), and tenant resolution (a given address maps to the right client's data and nobody else's). The first two are DNS. The third is application architecture, and it is the one that decides whether you have a multi-tenant product or a security incident waiting to happen.

Connect Claude to your email inbox in five minutes
tutorialsJul 27, 2026

Connect Claude to your email inbox in five minutes

To connect Claude to your email, you expose your inbox as an MCP server and add that server as a connector in Claude. The Claude app authenticates with one-click OAuth; Claude Code uses a static bearer token. From there Claude calls typed tools (search, read, triage, send) against your inbox instead of guessing from screenshots. This walkthrough does it end to end, including the failure modes you will actually hit, and it shows the hard way (building the MCP server yourself) before the shortcut.

MailChannels for Cloudflare Workers is gone: the alternative
tutorialsJul 24, 2026

MailChannels for Cloudflare Workers is gone: the alternative

For about three years, the answer to "how do I send email from a Cloudflare Worker" was a single, almost magical snippet. No account, no API key, no credit card: you POSTed JSON to api.mailchannels.net/tx/v1/send and a transactional email went out. That worked because of a partnership between Cloudflare and MailChannels that gave Workers a free relay.

Turn inbound email into a webhook with Cloudflare Workers
tutorialsJul 22, 2026

Turn inbound email into a webhook with Cloudflare Workers

Inbound email as an event source is genuinely useful: ticket creation from support@ , magic-link replies, +tag routing, parsing supplier order confirmations, an ai@ address that hands a message to an agent. The classic answer is to point an MX record at a provider that parses the mail and POSTs you JSON. That works, but now a third party reads every message before you do, and you pay per inbound.

Storing email attachments in Cloudflare R2
tutorialsJul 20, 2026

Storing email attachments in Cloudflare R2

If you are running email on Cloudflare, the bodies are easy: text and HTML are small, they live happily as columns in D1. Attachments are the part that bites you. A single thread can carry tens of megabytes of PDFs, images, and the occasional zip, and none of that belongs in a SQLite row. This is a walkthrough of doing attachment storage properly on Cloudflare: where the bytes go, how to key them, and how to serve them back without leaking your bucket to the world. We will build it by hand first so you understand every moving part, then show the version where you do not have to.

Using Cloudflare Queues to send email reliably at volume
tutorialsJul 17, 2026

Using Cloudflare Queues to send email reliably at volume

You wrote a clean little route. A user does something, you send a confirmation email inline, you return 200. It works. Then a launch happens, a thousand signups land in a minute, and your logs fill with timeouts and dropped mail. Nothing about the email got harder; you just stopped being able to do it synchronously.

Cloudflare Email Routing tutorial: receive inbound mail in a Worker
tutorialsJul 15, 2026

Cloudflare Email Routing tutorial: receive inbound mail in a Worker

The outbound half: why Email Routing can't send covered sending from the edge. This is the other half: receiving. Cloudflare Email Routing accepts mail at your domain and, instead of just forwarding it to Gmail, can hand each message to a Worker you control. That Worker is where inbound mail stops being a forwarded copy and becomes structured data you can query, search, and feed to an agent.

Set up a catch-all address with Cloudflare Email Routing
tutorialsJul 13, 2026

Set up a catch-all address with Cloudflare Email Routing

A catch-all address is one rule that matches every local part at a domain that doesn't already have an explicit rule. Instead of creating support@ , hello@ , billing@ , careers@ , and the dozen aliases you'll think of later, you set one wildcard and everything lands in the same place. Cloudflare Email Routing ships this as a first-class feature, and the basic version takes about five minutes. The interesting version, where the catch-all feeds a Worker and you keep the mail, takes a little longer. Here's both.

Send scheduled email digests with Cloudflare Cron Triggers
tutorialsJul 10, 2026

Send scheduled email digests with Cloudflare Cron Triggers

A digest email is deceptively simple to describe and annoying to run. The logic ("gather the last day's activity, format it, mail it") is trivial. The hard part is the recurring, reliable, time-zone-correct trigger , and a Worker has no built-in scheduler the way a Linux box has crontab. Cloudflare's answer is Cron Triggers, and they are good, but they behave differently from a unix cron in ways that will bite you if you assume otherwise.

Connect ChatGPT and other assistants to your inbox over MCP
tutorialsJul 8, 2026

Connect ChatGPT and other assistants to your inbox over MCP

To connect ChatGPT and other assistants to your email over MCP, expose your inbox as one MCP server and point every client at the same /mcp URL. ChatGPT, Cursor, and headless scripts authenticate with a scoped bearer token; the Claude app additionally supports one-click OAuth. The same typed tools (search, read, triage, send) work across every client because MCP is a shared protocol, not a per-vendor SDK. This walkthrough connects multiple assistants to one inbox, is honest about where the OAuth path stops and the bearer path takes over, and shows the hard way (building a multi-client MCP server) before the shortcut.

Build a newsletter signup with double opt-in on Cloudflare
tutorialsJul 6, 2026

Build a newsletter signup with double opt-in on Cloudflare

Single opt-in is one INSERT: someone types an address, you store it, done. It is also how you end up mailing spam traps, typo'd addresses, and people who never asked, all of which quietly poison your sender reputation. Double opt-in adds one step: the address is only real once its owner clicks a confirmation link. That single extra hop is what keeps your list clean and your consent provable.

Your inbox is now an MCP server: connect Claude to your email
tutorialsJul 2, 2026

Your inbox is now an MCP server: connect Claude to your email

The reason AI assistants are bad at email isn't the models; it's access. Your mail lives behind a vendor's UI, and the assistant can't get to it without screen-scraping or a brittle integration. Tinbox flips this: because your inbox is a database you own , Tinbox can expose it as a proper MCP server , and any MCP-capable assistant can connect to it directly.

Why Node SMTP fails in Cloudflare Workers — and what works
tutorialsJun 24, 2026

Why Node SMTP fails in Cloudflare Workers — and what works

You're building on Cloudflare Workers. Everything is fast and cheap and lives at the edge. Then you need to send one email (a password reset, an order receipt) and you reach for the thing you've used a hundred times:

How to build an MCP server on Cloudflare Workers
tutorialsJun 15, 2026

How to build an MCP server on Cloudflare Workers

An MCP server on Cloudflare Workers is a stateless JSON-RPC 2.0 HTTP endpoint that answers three methods: initialize , tools/list , and tools/call . You do not need the official SDK or a persistent session. You parse each POST, switch on the method, and return a JSON-RPC envelope. That is the whole shape, and it maps cleanly onto the Fetch Request / Response a Worker already speaks.

BIMI setup: show your brand logo in the inbox
tutorialsJun 13, 2026

BIMI setup: show your brand logo in the inbox

BIMI (Brand Indicators for Message Identification) is the standard that puts your logo in the inbox. When it works, a supporting mail client shows your brand mark next to your messages instead of a generic letter or a colored initial. It looks like a small thing. It is a real trust signal, and it is one of the few inbox affordances you can actually control as a sender.

AI inbox triage: automatically sort and prioritize your email
tutorialsJun 11, 2026

AI inbox triage: automatically sort and prioritize your email

AI inbox triage is the practice of running a classifier over every inbound message and writing back structured conclusions: a category like promotions or support , a priority flag, and any extracted fields like an order number or a one-time code. The hard part is not the model call. It is doing it cheaply, deterministically where you can, and without your classifier silently regressing every time you tweak a prompt.

Build an AI email agent with typed tools over your own inbox
tutorialsJun 10, 2026

Build an AI email agent with typed tools over your own inbox

An AI email agent is a language model wired to a set of typed tools over your mail store, so it can take actions (search, read, summarize, draft, send) instead of only answering questions about email in the abstract. The difference from a chatbot is the tool loop: when you ask "what needs my attention?", a chatbot guesses from training data, while an agent calls a search_emails tool, gets real rows back from your inbox, and reasons over them.

AI draft email replies: have an agent prepare them, not send them
tutorialsJun 8, 2026

AI draft email replies: have an agent prepare them, not send them

To get AI draft email replies without auto-sending, give the agent read tools and a create_draft tool, but no send tool. The model reads the thread, writes a reply, and saves it as a draft tied to that conversation. A human opens the draft, edits, and presses send. The safety property is structural, not a prompt instruction: an agent can only call tools it was given, so an agent with no send verb cannot deliver mail no matter what it decides or what an attacker writes into an incoming email.

AI schedule and snooze email: build send-later and snooze as agent tools
tutorialsJun 6, 2026

AI schedule and snooze email: build send-later and snooze as agent tools

AI schedule and snooze email means an agent turns a natural-language request into durable state that a clock later acts on: a row that says "send this draft at timestamp T" or "hide this thread until timestamp W." The agent does not stay awake until then. It parses the time, writes the row, and returns. A scheduled job does the timed part. Get that division right and send-later and snooze are about 150 lines of infrastructure plus two small tool definitions.

Let an AI agent label and tag incoming email by intent
tutorialsJun 5, 2026

Let an AI agent label and tag incoming email by intent

Labeling email by intent means assigning each inbound message one tag from a small fixed set, so your inbox can filter, route, and badge on it. The classification itself is the easy part. The work is doing it cheaply where the answer is obvious, reaching for a model only where intent is genuinely ambiguous, and writing the label back to your own store without standing up a separate tagging service.

Add transactional and lifecycle email to your SaaS in a day
tutorialsJun 3, 2026

Add transactional and lifecycle email to your SaaS in a day

"Add email to your SaaS" sounds like a one-liner: install an SDK, call send . The market is full of drop-ins that promise exactly that, and if you just want to survey them quickly, the tools to add email to your app in an afternoon is the shortlist. But the SDK is the easy part. Email in a real product is four jobs wearing a trench coat. There is the trigger (the user did a thing). There is the template (turn data into HTML). There is the suppression check (don't mail people who left or bounced). And there is delivery (sign it, relay it, track whether it landed). Transactional and lifecycle email are the same four jobs; only the trigger differs.

How to A/B test email subject lines on your own stack
tutorialsJun 1, 2026

How to A/B test email subject lines on your own stack

Subject-line testing is the highest-leverage A/B test in email because the subject is the one thing every recipient sees before deciding whether to open. A two-point swing in open rate compounds across every campaign you send for the rest of the year. So it is worth doing properly. Once the plumbing here is in place it powers more than subject lines, so it is worth keeping a running list of email A/B tests worth running on your own stack to feed the same harness. The catch is that "properly" means two separate problems: the engineering of splitting a list and attributing events, which is easy, and the statistics of knowing when a difference is real, which is where most people, and most tools, quietly cut corners.

Deploy your Tinbox email stack from GitHub Actions
tutorialsAug 3, 2026

Deploy your Tinbox email stack from GitHub Actions

A Tinbox email stack is a single Cloudflare Worker plus its D1 database, R2 bucket, KV namespace, and queues. Deploying it is just wrangler deploy with the schema migrated first. That is easy to do once interactively. The problem is doing it repeatably: across a team, across environments, and (for an agency) across a dozen client tenants that each live on their own domain. GitHub Actions is the obvious place to put that, and the whole thing is more boring than it looks. Here is the complete setup, including the failure modes that trip people up.