Skip to content

SYSTEM Cited by 1 source

Cloudflare Email Service

Cloudflare Email Service is Cloudflare's bidirectional email primitive on the developer platform — two products under one name:

  • Email Routing (free, inbound, long-available) — receive mail at addresses on your domain, route it to a Worker or a destination address.
  • Email Sending (public beta from 2026-04-16, outbound) — send transactional mail from a Worker via an EMAIL binding, from any runtime via REST API + TS/Python/Go SDKs, or from the command line via wrangler email send.

Together they constitute "complete bidirectional email within a single platform. Receive an email, process it in a Worker, and reply, all without leaving Cloudflare" (Source: sources/2026-04-16-cloudflare-email-service-public-beta-ready-for-agents).

Surfaces

Surface Purpose Who uses it
env.EMAIL.send({ to, from, subject, text }) Native Workers binding Workers / Agents SDK
REST API /client/v4/accounts/{id}/email-service/send Platform-independent Any runtime in any language
TypeScript / Python / Go SDKs Language-native External services
wrangler email send --to … --from … … CLI send Coding agents with bash access
Email MCP server on the Cloudflare MCP surface Prompt-driven send + config MCP-aware agents (Claude Code / Cursor / Copilot)
cloudflare/skills Email Service skill Guidance for coding agents Any coding agent importing the skill

Auto-configured deliverability

On domain attach, Email Service automatically configures SPF, DKIM and DMARC records. "Sending email that actually reaches inboxes usually means wrestling with SPF, DKIM, and DMARC records. When you add your domain to Email Service, we configure all of it automatically. Your emails are authenticated and delivered, not flagged as spam" (Source: sources/2026-04-16-cloudflare-email-service-public-beta-ready-for-agents). Sibling shape to Universal SSL — hard crypto / auth configuration absorbed into the platform, default-on (see patterns/default-on-security-upgrade).

Role in agent stacks

This is the email-tier surface of the Agents SDK. Pairs with:

Canonical agent shape — receive → persist → reply

import { Agent, routeAgentEmail } from "agents";
import { createAddressBasedEmailResolver, type AgentEmail } from "agents/email";
import PostalMime from "postal-mime";

export class SupportAgent extends Agent {
  async onEmail(email: AgentEmail) {
    const raw = await email.getRaw();
    const parsed = await PostalMime.parse(raw);

    // Persist in agent state — DO-backed
    this.setState({
      ...this.state,
      ticket: {
        from: email.from,
        subject: parsed.subject,
        body: parsed.text,
        messageId: parsed.messageId,
      },
    });

    // Optionally kick off a long-running background task, or
    // enqueue on a Queue to be handled by another Worker.

    await this.sendEmail({
      binding: this.env.EMAIL,
      fromName: "Support Agent",
      from: "support@your-agents.example",
      to: this.state.ticket.from,
      inReplyTo: this.state.ticket.messageId,  // ← HMAC-signed
      subject: `Re: ${this.state.ticket.subject}`,
      text: `Thanks for reaching out...`,
    });
  }
}

export default {
  async email(message, env) {
    await routeAgentEmail(message, env, {
      resolver: createAddressBasedEmailResolver("SupportAgent"),
    });
  },
} satisfies ExportedHandler<Env>;

Canonical wiki instance of patterns/inbound-classify-persist-reply-pipeline.

Address-based routing + sub-addressing

"Each agent gets its own identity from a single domain. The address-based resolver routes support@… to a 'support' agent instance, sales@… to a 'sales' instance, and so on. You don't need to provision separate inboxes — the routing is built into the address. You can even use sub-addressing (support+ticket-123@…) to route to different agent namespaces and instances" (Source: sources/2026-04-16-cloudflare-email-service-public-beta-ready-for-agents).

Address Selects
support@domain SupportAgent class, default instance "support"
support+ticket-123@domain SupportAgent class, instance "ticket-123"
sales@domain SalesAgent class, default instance "sales"
billing+invoice-456@domain BillingAgent class, instance "invoice-456"

Local-part selects agent class + default instance; RFC-5233 plus-sub selects a specific instance inside that class. Email-tier realisation of concepts/one-to-one-agent-instance — the address is the DO-ID selector. See concepts/address-based-agent-routing, patterns/sub-addressed-agent-instance.

Signed reply routing

"When your agent sends an email and expects a reply, you can sign the routing headers with HMAC-SHA256 so that replies route back to the exact agent instance that sent the original message. This prevents attackers from forging headers to route emails to arbitrary agent instances — a security concern that most 'email for agents' solutions haven't addressed" (Source: sources/2026-04-16-cloudflare-email-service-public-beta-ready-for-agents).

The inReplyTo value carries the HMAC signature across the email round-trip; inbound verification re-derives and checks before dispatching to the destination DO instance. See patterns/signed-reply-routing-header.

Agent is not a chatbot — the async-reply differentiator

"A chatbot responds in the moment or not at all. An agent thinks, acts, and communicates on its own timeline. With Email Sending, your agent can receive a message, spend an hour processing data, check three other systems, and then reply with a complete answer. It can schedule follow-ups. It can escalate when it detects an edge case. It can operate independently" (Source: sources/2026-04-16-cloudflare-email-service-public-beta-ready-for-agents).

The inbox tolerates arbitrary agent latency — unlike a WebSocket chat session, an hour-gap reply is normal email hygiene. See concepts/asynchronous-reply-email.

Reference app

  • systems/agentic-inbox — Cloudflare's open-source email-client
  • agent reference app that wires Email Routing inbound, Email Sending outbound, Workers AI classification, R2 attachments, and Agents SDK stateful logic. Deploy-to-Cloudflare button; built-in MCP server for external agents to draft for human review.

Seen in

Last updated · 200 distilled / 1,178 read