All skills
Skillintermediate

Email Routing API Reference

```typescript interface ExportedHandler { email?(message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext): void | Promise<void>; } ```

Claude Code Knowledge Pack7/10/2026

Overview

Email Routing API Reference

Worker Runtime API

Email Handler Interface

interface ExportedHandler {
  email?(message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext): void | Promise<void>;
}

ForwardableEmailMessage

Main interface for incoming emails:

interface ForwardableEmailMessage {
  readonly from: string;          // Envelope sender (e.g., "sender@example.com")
  readonly to: string;             // Envelope recipient (e.g., "you@yourdomain.com")
  readonly headers: Headers;       // Web API Headers object
  readonly raw: ReadableStream;    // Raw MIME message stream
  
  setReject(reason: string): void;
  forward(rcptTo: string, headers?: Headers): Promise<void>;
}

Key Properties:

PropertyTypeDescription
fromstringEnvelope sender (MAIL FROM), not header From
tostringEnvelope recipient (RCPT TO), not header To
headersHeadersEmail headers (Subject, From, To, etc.)
rawReadableStreamRaw MIME message (consume once only)

Methods:

  • setReject(reason): Reject email with bounce message
  • forward(rcptTo, headers?): Forward to verified destination, optionally add headers

Headers Object

Standard Web API Headers interface:

// Access headers
const subject = message.headers.get("subject");
const from = message.headers.get("from");
const messageId = message.headers.get("message-id");

// Check spam score
const spamScore = parseFloat(message.headers.get("x-cf-spamh-score") || "0");
if (spamScore > 5) {
  message.setReject("Spam detected");
}

Common Headers

subject, from, to, x-cf-spamh-score (spam score), message-id (deduplication), dkim-signature (auth)

Envelope vs Header Addresses

Critical distinction:

// Envelope addresses (routing, auth checks)
message.from // "bounce@sender.com" (actual sender)
message.to   // "you@yourdomain.com" (your address)

// Header addresses (display, user-facing)
message.headers.get("from") // "Alice <alice@sender.com>"
message.headers.get("to")   // "Bob <you@yourdomain.com>"

Use envelope addresses for:

  • Authentication/SPF checks
  • Routing decisions
  • Bounce handling

Use header addresses for:

  • Display to users
  • Reply-To logic
  • User-facing filtering

SendEmail Binding

Outbound email API for transactional messages.

Configuration

// wrangler.jsonc
{
  "send_email": [
    { "name": "EMAIL" }
  ]
}

TypeScript Types

interface Env {
  EMAIL: SendEmail;
}

interface SendEmail {
  send(message: EmailMessage): Promise<void>;
}

interface EmailMessage {
  from: string | { name?: string; email: string };
  to: string | { name?: string; email: string } | Array<string | { name?: string; email: string }>;
  subject: string;
  text?: string;
  html?: string;
  headers?: Headers;
  reply_to?: string | { name?: string; email: string };
}

Send Email Example

interface Env {
  EMAIL: SendEmail;
}

  async fetch(request, env, ctx): Promise {
    await env.EMAIL.send({
      from: { name: "Acme Corp", email: "noreply@yourdomain.com" },
      to: [
        { name: "Alice", email: "alice@example.com" },
        "bob@example.com"
      ],
      subject: "Your order #12345 has shipped",
      text: "Track your package at: https://track.example.com/12345",
      html: "<p>Track your package at: <a href='https://track.example.com/12345'>View tracking</a></p>",
      reply_to: { name: "Support", email: "support@yourdomain.com" }
    });
    
    return new Response("Email sent");
  }
} satisfies ExportedHandler;

SendEmail Constraints

  • From address: Must be on verified domain (your domain with Email Routing enabled)
  • Volume limits: Transactional only, no bulk/marketing email
  • Rate limits: 100 emails/minute on Free plan, higher on Paid
  • No attachments: Use links to hosted files instead
  • No DKIM control: Cloudflare signs automatically

REST API Operations

Base URL: https://api.cloudflare.com/client/v4

Authentication

curl -H "Authorization: Bearer $API_TOKEN" https://api.cloudflare.com/client/v4/...

Key Endpoints

OperationMethodEndpoint
Enable routingPOST/zones/{zone_id}/email/routing/enable
Disable routingPOST/zones/{zone_id}/email/routing/disable
List rulesGET/zones/{zone_id}/email/routing/rules
Create rulePOST/zones/{zone_id}/email/routing/rules
Verify destinationPOST/zones/{zone_id}/email/routing/addresses
List destinationsGET/zones/{zone_id}/email/routing/addresses

Create Routing Rule Example

curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/email/routing/rules" \\
  -H "Authorization: Bearer $API_TOKEN" \\
  -H "Content-Type: application/json" \\
  -d '{
    "enabled": true,
    "name": "Forward sales",
    "matchers": [{"type": "literal", "field": "to", "value": "sales@yourdomain.com"}],
    "actions": [{"type": "forward", "value": ["alice@company.com"]}],
    "priority": 0
  }'

Matcher types: literal (exact match), all (catch-all).