[ PROMPT_NODE_24107 ]
Email Workers – API
[ SKILL_DOCUMENTATION ]
# Email Workers API Reference
Complete API reference for Cloudflare Email Workers runtime.
## ForwardableEmailMessage Interface
The main interface passed to email handlers.
```typescript
interface ForwardableEmailMessage {
readonly from: string; // Envelope MAIL FROM (SMTP sender)
readonly to: string; // Envelope RCPT TO (SMTP recipient)
readonly headers: Headers; // Web-standard Headers object
readonly raw: ReadableStream; // Raw MIME message (single-use stream)
readonly rawSize: number; // Total message size in bytes
setReject(reason: string): void;
forward(rcptTo: string, headers?: Headers): Promise;
reply(message: EmailMessage): Promise;
}
```
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `from` | string | Envelope sender (SMTP MAIL FROM) - use for security |
| `to` | string | Envelope recipient (SMTP RCPT TO) |
| `headers` | Headers | Message headers (Subject, Message-ID, etc.) |
| `raw` | ReadableStream | Raw MIME message (**single-use**, buffer first) |
| `rawSize` | number | Message size in bytes |
### Methods
#### setReject(reason: string): void
Reject with permanent SMTP 5xx error. Email not delivered, sender may receive bounce.
```typescript
if (blockList.includes(message.from)) {
message.setReject('Sender blocked');
}
```
#### forward(rcptTo: string, headers?: Headers): Promise
Forward to verified destination. Only `X-*` custom headers allowed.
```typescript
await message.forward('[email protected]');
// With custom headers
const h = new Headers();
h.set('X-Processed-By', 'worker');
await message.forward('[email protected]', h);
```
#### reply(message: EmailMessage): Promise
Send a reply to the original sender (March 2025 feature).
```typescript
import { EmailMessage } from 'cloudflare:email';
import { createMimeMessage } from 'mimetext';
const msg = createMimeMessage();
msg.setSender({ name: 'Support', addr: '[email protected]' });
msg.setRecipient(message.from);
msg.setSubject(`Re: ${message.headers.get('Subject')}`);
msg.setHeader('In-Reply-To', message.headers.get('Message-ID'));
msg.setHeader('References', message.headers.get('References') || '');
msg.addMessage({
contentType: 'text/plain',
data: 'Thank you for your message.'
});
await message.reply(new EmailMessage(
'[email protected]',
message.from,
msg.asRaw()
));
```
**Requirements**:
- Incoming email needs valid DMARC
- Reply once per event, recipient = `message.from`
- Sender domain = receiving domain, with DMARC/SPF/DKIM
- Max 100 `References` entries
- Threading: `In-Reply-To` (original Message-ID), `References`, new `Message-ID`
## EmailMessage Constructor
```typescript
import { EmailMessage } from 'cloudflare:email';
new EmailMessage(from: string, to: string, raw: ReadableStream | string)
```
Used for sending emails (replies or via SendEmail binding). Domain must be verified.
## SendEmail Interface
```typescript
interface SendEmail {
send(message: EmailMessage): Promise;
}
// Usage
await env.EMAIL.send(new EmailMessage(from, to, mimeContent));
```
## SendEmail Binding Types
```jsonc
{
"send_email": [
{ "name": "EMAIL" }, // Type 1: Any verified address
{ "name": "LOGS", "destination_address": "[email protected]" }, // Type 2: Single dest
{ "name": "TEAM", "allowed_destination_addresses": ["[email protected]", "[email protected]"] }, // Type 3: Dest allowlist
{ "name": "NOREPLY", "allowed_sender_addresses": ["[email protected]"] } // Type 4: Sender allowlist
]
}
```
## postal-mime Parsed Output
postal-mime v2.7.3 parses incoming emails into structured data.
```typescript
interface ParsedEmail {
headers: Array;
from: { name: string; address: string } | null;
to: Array | { name: string; address: string } | null;
cc: Array | null;
bcc: Array | null;
subject: string;
messageId: string | null;
inReplyTo: string | null;
references: string | null;
date: string | null;
html: string | null;
text: string | null;
attachments: Array;
}
```
### Usage
```typescript
import PostalMime from 'postal-mime';
const buffer = await new Response(message.raw).arrayBuffer();
const email = await PostalMime.parse(buffer);
console.log(email.subject);
console.log(email.from?.address);
console.log(email.text);
console.log(email.attachments.length);
```
## mimetext API Quick Reference
mimetext v3.0.27 composes outgoing emails.
```typescript
import { createMimeMessage } from 'mimetext';
const msg = createMimeMessage();
// Sender
msg.setSender({ name: 'John Doe', addr: '[email protected]' });
// Recipients
msg.setRecipient('[email protected]');
msg.setRecipients(['[email protected]', '[email protected]']);
msg.setCc('[email protected]');
msg.setBcc(['[email protected]']);
// Headers
msg.setSubject('Meeting Notes');
msg.setHeader('In-Reply-To', '');
msg.setHeader('References', ' ');
msg.setHeader('Message-ID', ``);
// Content
msg.addMessage({
contentType: 'text/plain',
data: 'Plain text content'
});
msg.addMessage({
contentType: 'text/html',
data: '
HTML content
' }); // Attachments msg.addAttachment({ filename: 'report.pdf', contentType: 'application/pdf', data: pdfBuffer // Uint8Array or base64 string }); // Generate raw MIME const raw = msg.asRaw(); // Returns string ``` ## TypeScript Types ```typescript import { ForwardableEmailMessage, EmailMessage } from 'cloudflare:email'; interface Env { EMAIL: SendEmail; EMAIL_ARCHIVE: KVNamespace; ALLOWED_SENDERS: KVNamespace; } export default { async email( message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext ): Promise { // Fully typed } }; ```
Source: claude-code-templates (MIT). See About Us for full credits.