Skip to content

Commit 3aae360

Browse files
celsokodster28elithrar
authored andcommitted
Updates Email Routing docs (#20491)
* Updates postmaster page * formatting * updates outbound hostnames * better language * New reply rules and limits * adds changelog * clarifies headers * Update src/content/changelog/email-routing/2025-03-12-reply-limits.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/changelog/email-routing/2025-03-12-reply-limits.mdx Co-authored-by: Matt Silverlock <[email protected]> --------- Co-authored-by: Celso Martinho <[email protected]> Co-authored-by: Kody Jackson <[email protected]> Co-authored-by: Matt Silverlock <[email protected]>
1 parent 0498cbd commit 3aae360

File tree

3 files changed

+102
-29
lines changed

3 files changed

+102
-29
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: Threaded replies now possible in Email Workers
3+
description: You can now use Email Workers to send multiple replies to the same email thread.
4+
date: 2025-03-12T18:00:00Z
5+
---
6+
7+
We’re removing some of the restrictions in Email Routing so that AI Agents and task automation can better handle email workflows, including how Workers can [reply](/email-routing/email-workers/reply-email-workers/) to incoming emails.
8+
9+
It's now possible to keep a threaded email conversation with an [Email Worker](/email-routing/email-workers/) script as long as:
10+
11+
* The incoming email has to have valid [DMARC](https://www.cloudflare.com/learning/dns/dns-records/dns-dmarc-record/).
12+
* The email can only be replied to once in the same `EmailMessage` event.
13+
* The recipient in the reply must match the incoming sender.
14+
* The outgoing sender domain must match the same domain that received the email.
15+
* Every time an email passes through Email Routing or another MTA, an entry is added to the `References` list. We stop accepting replies to emails with more than 100 `References` entries to prevent abuse or accidental loops.
16+
17+
Here's an example of a Worker responding to Emails using a Workers AI model:
18+
19+
```ts title="AI model responding to emails"
20+
import PostalMime from "postal-mime";
21+
import {createMimeMessage} from "mimetext"
22+
import { EmailMessage } from "cloudflare:email";
23+
24+
export default {
25+
async email(message, env, ctx) {
26+
const email = await PostalMime.parse(message.raw)
27+
const res = await env.AI.run('@cf/meta/llama-2-7b-chat-fp16', {
28+
messages: [{
29+
role: "user",
30+
content: email.text ?? ''
31+
}]
32+
})
33+
34+
// message-id is generated by mimetext
35+
const response = createMimeMessage()
36+
response.setHeader("In-Reply-To", message.headers.get("Message-ID")!);
37+
response.setSender("[email protected]");
38+
response.setRecipient(message.from);
39+
response.setSubject("Llama response");
40+
response.addMessage({
41+
contentType: 'text/plain',
42+
data: res instanceof ReadableStream ? await new Response(res).text() : res.response!
43+
})
44+
45+
const replyMessage = new EmailMessage("<email>", message.from, response.asRaw());
46+
await message.reply(replyMessage)
47+
}
48+
} satisfies ExportedHandler<Env>;
49+
```
50+
51+
See [Reply to emails from Workers](/email-routing/email-workers/reply-email-workers/) for more information.

src/content/docs/email-routing/email-workers/reply-email-workers.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ export default {
4040
}
4141
```
4242

43-
To mitigate security risks and abuse, replying to incoming emails has a few requirements:
43+
To mitigate security risks and abuse, replying to incoming emails has a few requirements and limits:
4444

4545
* The incoming email has to have valid [DMARC](https://www.cloudflare.com/learning/dns/dns-records/dns-dmarc-record/).
4646
* The email can only be replied to once in the same `EmailMessage` event.
47-
* The `In-Reply-To` header of the reply message must be set to the `Message-ID` of the incoming message.
4847
* The recipient in the reply must match the incoming sender.
4948
* The outgoing sender domain must match the same domain that received the email.
49+
* Every time an email passes through Email Routing or another MTA, an entry is added to the `References` list. We stop accepting replies to emails with more than 100 `References` entries to prevent abuse or accidental loops.
5050

51-
If these and other internal conditions are not met, then `reply()` will fail with an exception, otherwise you can freely compose your reply message and send it back to the original sender.
51+
If these and other internal conditions are not met, `reply()` will fail with an exception. Otherwise, you can freely compose your reply message, send it back to the original sender, and receive subsequent replies multiple times.

src/content/docs/email-routing/postmaster.mdx

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,22 @@ The best way to contact us is using our [community forum](https://community.clou
2828

2929
Through this standard, the sender publishes its public key to a domain's DNS once, and then signs the body of each message before it leaves the server. The recipient server reads the message, gets the domain public key from the domain's DNS, and validates the signature to ensure the message was not altered in transit.
3030

31-
Email Routing signs email on behalf of `email.cloudflare.net`. If the sender did not sign the email, the receiver will likely use Cloudflare's signature for authentication.
31+
Email Routing adds two new signatures to the emails in transit, one on behalf of the Cloudflare domain used for sender rewriting `email.cloudflare.net`, and another one on behalf of the customer's recipient domain.
3232

3333
Below is the DKIM key for `email.cloudflare.net`:
3434

3535
```sh
36-
dig TXT 2022._domainkey.email.cloudflare.net +short
36+
dig TXT cf2024-1._domainkey.email.cloudflare.net +short
3737
```
3838

3939
```sh output
40+
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiweykoi+o48IOGuP7GR3X0MOExCUDY/BCRHoWBnh3rChl7WhdyCxW3jgq1daEjPPqoi7sJvdg5hEQVsgVRQP4DcnQDVjGMbASQtrY4WmB1VebF+RPJB2ECPsEDTpeiI5ZyUAwJaVX7r6bznU67g7LvFq35yIo4sdlmtZGV+i0H4cpYH9+3JJ78k" "m4KXwaf9xUJCWF6nxeD+qG6Fyruw1Qlbds2r85U9dkNDVAS3gioCvELryh1TxKGiVTkg4wqHTyHfWsp7KD3WQHYJn0RyfJJu6YEmL77zonn7p2SRMvTMP3ZEXibnC9gz3nnhR6wcYL8Q7zXypKTMD58bTixDSJwIDAQAB"
41+
```
42+
43+
You can find the DKIM key for the customer's `example.com` domain by querying the following:
4044

41-
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnraPy1d8e6+lzeE1HIoUvYWoAOUSREkNHcwxA/ueVM8f6FKXvPu/9gVpgkn8iUyaCfk2z1MW+OVLuFeH64YRMa39mkaQalgke2tZ05SnjRUtYEHYvfrqPuMT+Ouk+GecpgvrtMq5gMXm6ZfeUhQkdWxmMQJGf4fdW5I0piUQJMhK/Qc1dNRSskk" "TiUtXKnsEdjTN2xcnHhyj985S0xOEAxm9Uj1rykPqVvKpqEdjUkujbXOwR0KmHTvPyFpBjCCfxAVqOwwo9zBYuvk/nh0qlDgLIpy0SimrYhNFCq2XBxIj4tdUzIl7qZ5Ck6zLCQ+rjzJ4sm/zA+Ov9kDkbcmyrwIDAQAB"
45+
```sh
46+
dig TXT cf2024-1._domainkey.example.com +short
4247
```
4348

4449
### DMARC enforcing
@@ -88,14 +93,34 @@ example.com. 300 IN TXT "v=spf1 include:_spf.mx.cloudflare.net ~all"
8893

8994
[The MX (mail exchange) records](https://www.cloudflare.com/learning/dns/dns-records/dns-mx-record/) tell the Internet where the inbound servers receiving email messages for the zone are. In this case, anyone who wants to send an email to `example.com` can use the `amir.mx.cloudflare.net`, `linda.mx.cloudflare.net`, or `isaac.mx.cloudflare.net` SMTP servers.
9095

96+
### Outbound prefixes
97+
98+
Email Routing sends its traffic using both IPv4 and IPv6 prefixes, when supported by the upstream SMTP server.
99+
100+
If you are a postmaster and are having trouble receiving Email Routing's emails, allow the following outbound IP addresses in your server configuration:
101+
102+
**IPv4**
103+
104+
`104.30.0.0/19`
105+
106+
**IPv6**
107+
108+
`2405:8100:c000::/38`
109+
110+
_Ranges last updated: December 13th, 2023_
111+
91112
### Outbound hostnames
92113

93-
In addition to the outbound prefixes, Email Routing will use the domain `email.cloudflare.net` for the `HELO/EHLO` command.
114+
In addition to the outbound prefixes, Email Routing will use the following outbound domains for the `HELO/EHLO` command:
115+
116+
- `cloudflare-email.net`
117+
- `cloudflare-email.org`
118+
- `cloudflare-email.com`
94119

95120
PTR records (reverse DNS) ensure that each hostname has an corresponding IP. For example:
96121

97122
```sh
98-
dig a0-7.email.cloudflare.net +short
123+
dig a-h.cloudflare-email.net +short
99124
```
100125

101126
```sh output
@@ -107,25 +132,9 @@ dig -x 104.30.0.7 +short
107132
```
108133

109134
```sh output
110-
a0-7.email.cloudflare.net.
135+
a-h.cloudflare-email.net.
111136
```
112137

113-
### Outbound prefixes
114-
115-
Email Routing sends its traffic using both IPv4 and IPv6 prefixes, when supported by the upstream SMTP server.
116-
117-
If you are a postmaster and are having trouble receiving Email Routing's emails, allow the following outbound IP addresses in your server configuration:
118-
119-
**IPv4**
120-
121-
`104.30.0.0/20`
122-
123-
**IPv6**
124-
125-
`2405:8100:c000::/38`
126-
127-
_Ranges last updated: December 13th, 2023_
128-
129138
### Sender rewriting
130139

131140
Email Routing rewrites the SMTP envelope sender (`MAIL FROM`) to the forwarding domain to avoid issues with [SPF](#spf-record). Email Routing uses the [Sender Rewriting Scheme](https://en.wikipedia.org/wiki/Sender_Rewriting_Scheme) to achieve this.
@@ -136,14 +145,27 @@ This has no effect to the end user's experience, though. The message headers wil
136145

137146
In most cases, Email Routing forwards the upstream SMTP errors back to the sender client in-session.
138147

139-
### Spam and abusive traffic
148+
### Realtime Block Lists
140149

141-
Handling spam and abusive traffic is essential to any email provider. Email Routing filters emails based on advanced anti-spam criteria, [powered by Email Security (formerly Area 1)](/email-security/). When Email Routing detects and blocks a spam email, you will receive a message with details explaining what happened. For example:
150+
Email Routing uses an internal Domain Name System Blocklists (DNSBL) service to check if the sender's IP is present in one or more Realtime Block Lists (RBL) lists. When the system detects an abusive IP, it blocks the email and returns an SMTP error:
142151

143152
```txt
144-
554 <YOUR_IP_ADDRESS> found on one or more DNSBLs (abusixip). Refer to https://developers.cloudflare.com/email-routing/postmaster/#spam-and-abusive-traffic/
153+
554 <YOUR_IP_ADDRESS> found on one or more RBLs (abusixip). Refer to https://developers.cloudflare.com/email-routing/postmaster/#spam-and-abusive-traffic/
154+
```
155+
We update our RBLs regularly. You can use combined block list lookup services like [MxToolbox](https://mxtoolbox.com/blacklists.aspx) to check if your IP matches other RBLs. IP reputation blocks are usually temporary, but if you feel your IP should be removed immediately, please contact the RBL's maintainer mentioned in the SMTP error directly.
156+
157+
### Anti-spam
158+
159+
In addition to DNSBL, Email Routing uses advanced heuristic and statistical analysis of the email's headers and text to calculate a spam score. We inject the score in the custom `X-Cf-Spamh-Score` header:
160+
161+
```
162+
X-Cf-Spamh-Score: 2
145163
```
146164

165+
This header is visible in the forwarded email. The higher the score, 5 being the maximum, the more likely the email is spam. Currently, this system is experimental and passive; we do not act on it and suggest that upstream servers and email clients don't act on it either.
166+
167+
We will update this page with more information as we fine-tune the system.
168+
147169
### SPF record
148170

149171
A SPF DNS record is an anti-spoofing mechanism that is used to specify which IP addresses and domains are allowed to send emails on behalf of your zone.
@@ -204,4 +226,4 @@ Email Routing does not support sending or replying from your Cloudflare domain.
204226

205227
### Signs such "`+`" and "`.`" are treated as normal characters for custom addresses
206228

207-
Email Routing does not have advanced routing options. Characters such as `+` or `.`, which perform special actions in email providers like Gmail and Outlook, are currently treated as normal characters on custom addresses. More flexible routing options are in our roadmap.
229+
Email Routing does not have advanced routing options. Characters such as `+` or `.`, which perform special actions in email providers like Gmail and Outlook, are currently treated as normal characters on custom addresses. More flexible routing options are in our roadmap.

0 commit comments

Comments
 (0)