Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
0165280
[Email Service] Document account-wide suppressions
rpots Aug 24, 2026
1aa8b47
[Email Service] Align suppression docs with style guide
rpots Aug 24, 2026
c7f4717
[Email Service] Address suppression review findings
rpots Aug 24, 2026
9e35426
[Email Service] Clarify suppression behavior
rpots Aug 26, 2026
e9ab174
[API Shield] Remove documentation for applying learned schemas (#32635)
djhworld Aug 24, 2026
38379a8
docs(realtimekit): added faq for pre call check and added a button (#…
ravindra-cloudflare Aug 24, 2026
95c0232
docs(realtimekit): added release notes for 24 aug 2026 release of rea…
ravindra-cloudflare Aug 24, 2026
631ab41
docs(logs): add Transformers page (closed beta) (#32850)
Sahidya Aug 24, 2026
efc392f
[Cloudflare One] Document self-serve Cloudflare One Virtual Appliance…
nikitacano Aug 24, 2026
2e2563d
[Chore] Untangle magic products MDX (#32950)
kodster28 Aug 24, 2026
2fe1bb8
feat: incremental builds support (#32676)
mvvmm Aug 24, 2026
a903e38
[DLP] Add Test scan documentation and changelog (#32855)
Jose-Maria-Martins Aug 24, 2026
1662c3d
Docs/remove swg audit ssh (#32842)
Michael9127 Aug 24, 2026
e84e48b
fix: return markdown 404 for agent clients (#32929)
mvvmm Aug 24, 2026
dc4ec67
[Workers] Add release note for DO Dynamic Worker concurrency limit (#…
harrishancock Aug 24, 2026
a7f1bc7
[Fundamentals] Add SCIM PUT changelog (#32925)
AdamBouhmad Aug 24, 2026
ef59524
docs: add contributors page (#32934)
mvvmm Aug 24, 2026
cc14cc0
chore: remove elithrar from CODEOWNERS (#32965)
elithrar Aug 24, 2026
1bfcdb6
fix: clarify contributor count (#32968)
mvvmm Aug 24, 2026
c58fea0
[Web Analytics/RUM] Revise Core Web Vitals browser support (#32969)
ryantownsend Aug 24, 2026
401d495
fix: stop advertising api markdown docs in api-catalog (#32930)
mvvmm Aug 24, 2026
08dee0d
fix: improve JSON-LD org structured data (#32932)
mvvmm Aug 24, 2026
4041d73
fix: improve homepage heading semantics (#32933)
mvvmm Aug 24, 2026
6501906
feat: publish /.well-known/ai-catalog.json (#32931)
mvvmm Aug 24, 2026
8cef774
[Docs Site] Bump the non-major group across 1 directory with 26 updat…
dependabot[bot] Aug 24, 2026
d5b4102
[Workers] Recommend vinext for Next.js (#31887)
irvinebroque Aug 25, 2026
0b6b0ef
Workers Cache purge uses free tier limits (#32942)
vicb Aug 25, 2026
ceee454
chore: add flagship code owners (#32988)
roerohan Aug 25, 2026
a38a816
[Access] Document MCP 2026-07-28 portal support (#32958)
kennyj42 Aug 25, 2026
8acb7d0
Tunnel: Address terms and routing review feedback (#32886)
hugo-vicente11 Aug 25, 2026
0054baa
[Email Service] Document RFC 2156 priority and expiry headers (#32956)
ttoino Aug 25, 2026
8d26b67
[Email Service] Document Outlook threading headers (#32955)
ttoino Aug 25, 2026
0b4469c
[Fundamentals] Document audit log actor context values (#32967)
cf-ypark Aug 25, 2026
57ac13a
fix(llms.txt): normalize paths and preserve fragments when appending …
wallidsaydi-creator Aug 25, 2026
f929db6
[WAN] Correct DHCP network boot options (#33005)
JackAlexRose Aug 25, 2026
1beb84b
[RealtimeKit] Update feature availability labels (#32924)
korinne Aug 25, 2026
969e7dc
[Analytics] Fix broken GraphiQL images, add reference-style image rul…
mvvmm Aug 25, 2026
5c9c4b5
DS-16910: [Analytics] Document account-based GraphQL API rate limitin…
hc2116 Aug 25, 2026
52b543a
[Chore] Remove conditional partial logic (#32998)
kodster28 Aug 25, 2026
f57eb43
[Radar] Add RPKI ASPA path validation changelog (#32974)
digizeph Aug 25, 2026
8be70d0
[RealtimeKit] Add release notes navigation page (#32997)
swapnilmadavi Aug 25, 2026
31440f2
chore: disable workers.dev URL in wrangler.jsonc (#33008)
mvvmm Aug 25, 2026
39a559c
Mark field cf.api_gateway.request_violates_schema as deprecated (#32960)
djhworld Aug 25, 2026
a4672aa
[Turnstile] Update troubleshooter link (#32993)
anafoppa Aug 25, 2026
c9b7ef2
[Bot Mgmt / Precursor / Turnstile] I missed a bunch of spots where I …
marinaelmore Aug 25, 2026
b6bf546
[AI Gateway] Add Datadog as a supported OTEL backend (#32049)
Kyle-Verhoog Aug 25, 2026
4137ca9
[Chore] Add contextual metadata to upload r2 action (#33014)
kodster28 Aug 25, 2026
9e0dcd7
fix: use shallow checkout in production publish workflow (#33015)
mvvmm Aug 25, 2026
2ddcc01
Revert "fix: use shallow checkout in production publish workflow" (#3…
mvvmm Aug 25, 2026
f71d912
[Access] Document service token controls (#32954)
kennyj42 Aug 25, 2026
372c5ab
update models (#33011)
ethulia Aug 25, 2026
f40e7b7
[Hyperdrive] Document creating PlanetScale databases with Wrangler (#…
mtlemilio Aug 25, 2026
d27b26b
[Flagship] Document app-scoped API tokens (#32851)
roerohan Aug 26, 2026
b95b65d
[RealtimeKit] Add network allowlist page (#33007)
swapnilmadavi Aug 26, 2026
05ae9ae
WAF Release 25th August (#33009)
fb1337 Aug 26, 2026
5c2c29f
docs(waf): note that beta tag may persist beyond the 7-day review per…
zeinjaber Aug 26, 2026
d604895
docs(bots): note that JSD API invocations show as Unknown in Bot Anal…
zeinjaber Aug 26, 2026
aca6b74
Clarify AI-based PII detection terminology (#33013)
mrusso19 Aug 26, 2026
9e272a7
WAF Release 26th August - Emergency (#33038)
fb1337 Aug 26, 2026
1acee39
[Radar] Add Researcher improvements changelog (#33030)
andre-j3sus Aug 26, 2026
f6fa79b
AI Search: document larger metadata values (#32916)
G4brym Aug 26, 2026
379581e
AI Search: add six Workers AI text generation models (#32986)
G4brym Aug 26, 2026
40b6685
Add @cjolowicz as CODEOWNER for log-explorer docs and changelog (#33036)
cjolowicz Aug 26, 2026
cede178
[DO] Document disabling alarm retries after abort (#32884)
apeacock1991 Aug 26, 2026
7d8c738
docs(bots): clarify JA4 Signals Intelligence fields cannot be used in…
zeinjaber Aug 26, 2026
a0b7a35
docs(bots): document bot score 1 assigned when User-Agent header is m…
zeinjaber Aug 26, 2026
8223c67
docs(bots): add ephemeral_id availability and entitlement to Bot Mana…
zeinjaber Aug 26, 2026
4e1ec29
[Logs] Add Microsoft Sentinel connector deprecation notice (#33031)
Sahidya Aug 26, 2026
7d779b5
[RealtimeKit] Add Recording SDK release notes (#33000)
swapnilmadavi Aug 26, 2026
941787b
[Workers AI] Update DeepSeek V4 models and unpin catalog models (#32973)
mchenco Aug 26, 2026
1b843fa
Fixes python examples links and shortens ASGI code. (#32947)
dom96 Aug 26, 2026
f9b434e
CODEOWNERS: add WIT PM/EM reviewers to bots-related paths (#32971)
cf-jian Aug 26, 2026
45860ea
[Security Insights] Document free account scan pauses (#32755)
davejbax Aug 26, 2026
7eac54d
docs(api-shield): surface discovery requirements inline including Wor…
zeinjaber Aug 26, 2026
24a4a94
[Workers AI] Add GLM 5.3 Flash model (#33041)
mchenco Aug 26, 2026
59cae93
[Cloudflare One] Clarify SCIM policy evaluation (#33049)
kennyj42 Aug 26, 2026
e49e3bc
[Workers AI] Use Gemma 4 in starter guide (#33053)
superhighfives Aug 27, 2026
0405be1
[Workers AI] Document GLM-5.2 reasoning effort (#33022)
KastanDay Aug 27, 2026
7a3da25
[Log Explorer] Add dataset deletion changelog (#33033)
Sahidya Aug 27, 2026
0b6ba40
[Log Explorer] Document dataset deletion (#33034)
Sahidya Aug 27, 2026
8e2e07e
chore: consume API schema from middlecache (#33065)
mvvmm Aug 27, 2026
c71692b
[AI Gateway] Clarify caching opt-in behavior (#33027)
superhighfives Aug 27, 2026
248cc1a
docs: update Debian support timeline (#33018)
cf-joshnabbott Aug 27, 2026
d417035
[AI Gateway] Clarify Guardrails streaming evaluation behavior (#32964)
superhighfives Aug 27, 2026
d18c6d0
docs: clarify Organization API authentication (#33054)
nickzylstra Aug 27, 2026
718b471
[Audit Logs] Document CMB support (#33060)
Sahidya Aug 27, 2026
a01c402
[Logs] Update Logpush dataset field definitions (2026-08-20) (#32882)
soheiokamoto Aug 27, 2026
aa26405
chore: add Scott Buscemi as product codeowner (#33023)
scottbuscemi Aug 27, 2026
dac2761
[Access] Document service token secret format (#33045)
kennyj42 Aug 27, 2026
d9895b1
[Cloudflare One] Update service token secret example (#33070)
georgemblack Aug 27, 2026
ee2e6e8
Reframe Realtime SFU around application outcomes (#33071)
rcccf Aug 27, 2026
4bc0740
Document Dynamic Workers concurrency limits (#32951)
ketanhwr Aug 27, 2026
a86c261
CODEOWNERS: add mbullock1986 for IP geolocation docs (#33069)
stechedo Aug 27, 2026
229f7a4
[Network] Document IP geolocation accuracy limits and correct correct…
stechedo Aug 27, 2026
844e126
[D1] Add changelog entry for free tier daily query limit enforcement …
ivoryibu Aug 27, 2026
4e56c6e
[DNS] Clarify that assigned nameservers cannot be changed (#33037)
ngayerie Aug 28, 2026
27e0818
[API Shield] Document symmetric JWT validation (#33010)
janrueth Aug 28, 2026
2f5c84e
ai-search: add GLM-5.3-Flash support (#33079)
G4brym Aug 28, 2026
e0041a4
[SSL] Add Cloudflare Email Security to PQC products page (#33048)
spark516 Aug 28, 2026
8098ad1
[Audit Logs] Document account analytics (#33082)
Sahidya Aug 28, 2026
af290ca
[Workers] Add release note for v8 version 15.3 update (#33078)
mar-cf Aug 28, 2026
2136176
fix: serve original images in local dev (#33080)
mvvmm Aug 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/content/docs/email-service/api/send-emails/smtp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ Thanks for signing up.
221 mx.cloudflare.net Cloudflare Email ESMTP Service closing transmission channel
```

The `250 2.0.0 Ok` response after the message body includes the assigned Message-ID. Use it to correlate the submission with delivery logs in the dashboard.
A `250 2.0.0 Ok` response after the message body normally includes the assigned Message-ID. Use it to correlate the submission with delivery logs in the dashboard.

When **Drop suppressed recipients** is on and all recipients are suppressed, SMTP may return `250 2.0.0 Ok` without a Message-ID and deliver nothing. Refer to [Suppressed recipients](#suppressed-recipients).

## Examples

Expand Down Expand Up @@ -134,6 +136,20 @@ Cloudflare's SMTP server returns standard [RFC 5321](https://datatracker.ietf.or
| `552 5.3.4` | Message exceeds the 5 MiB `SIZE` limit. |
| `554` | Transaction failed — content rejected by policy. |

## Suppressed recipients

SMTP accepts a syntactically valid recipient with `250 2.1.5 Ok` during `RCPT TO`. Email Service checks the [suppression list](/email-service/concepts/suppressions/) for the account after receiving the message body.

Behavior depends on the per-sending-domain [**Drop suppressed recipients** setting](/email-service/configuration/domains/#drop-suppressed-recipients). The setting is off by default.

When the setting is off, any suppressed recipient causes SMTP to reject the entire message. When the setting is on, Email Service removes suppressed recipients and continues processing the remaining recipients.

If all recipients are suppressed while dropping is on, SMTP may return `250 2.0.0 Ok` without a Message-ID. It delivers nothing in this case.

Use [Email sending logs](/email-service/observability/logs/) to confirm delivery. Suppressed recipients appear with a **Rejected** result.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above


Suppression produces a `message.rejected` event in [Email Sending event subscriptions](/email-service/platform/event-subscriptions/) with `rejection.reason` set to `suppressed`.

## Troubleshooting

### `535 5.7.8 Authentication failed`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ The following error codes may be returned when sending emails:
| `E_TOO_MANY_ATTACHMENTS` | Too many attachments in `attachments` array | `attachments` array exceeds 32 entries |
| `E_SENDER_NOT_VERIFIED` | Sender domain not verified | Attempting to send from unverified domain |
| `E_RECIPIENT_NOT_ALLOWED` | Recipient not in allowed list | Recipient address not in `allowed_destination_addresses` |
| `E_RECIPIENT_SUPPRESSED` | Recipient is on suppression list | Email address has bounced or reported your emails as spam |
| `E_RECIPIENT_SUPPRESSED` | Suppressed recipient while dropping is off | At least one recipient is suppressed and **Drop suppressed recipients** is off |
| `E_SENDER_DOMAIN_NOT_AVAILABLE` | Domain not available for sending | Domain not onboarded to Email Service |
| `E_CONTENT_TOO_LARGE` | Email content exceeds size limit | Total message size exceeds the maximum |
| `E_DELIVERY_FAILED` | Could not deliver the email | SMTP delivery failure, recipient server rejection |
Expand All @@ -205,6 +205,8 @@ The following error codes may be returned when sending emails:
| `E_HEADERS_TOO_LARGE` | Headers payload too large | Total custom headers exceed 16 KB limit |
| `E_HEADERS_TOO_MANY` | Too many headers | More than 20 allowlisted (non-X) custom headers |

**Drop suppressed recipients** is off by default. When you [turn on the setting](/email-service/configuration/domains/#drop-suppressed-recipients), Email Service removes suppressed recipients and processes the remaining recipients.

## Legacy `EmailMessage` API

The `EmailMessage` API remains supported for backward compatibility. Use it when you already have a raw [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322) MIME message to send. For new code, prefer the structured [`send()` method](#send-method) above.
Expand Down
13 changes: 7 additions & 6 deletions src/content/docs/email-service/concepts/deliverability.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ Bounces occur when emails cannot be delivered to recipients. There are two types

Hard bounces are permanent delivery failures that occur when:

- Email address doesn't exist (`user@domain.com` → No such user)
- Domain does not exist (`user@nonexistentdomain.com`)
- Recipient server permanently blocks your domain
- Content rejected as spam by recipient filters
- The recipient address does not exist.
- The recipient domain does not exist.
- The receiving server permanently rejects the recipient.

**Hard bounces are never retried** because the failure is permanent. Emails that hard bounce will generate a bounce notification to the sender address and can be monitored through [analytics](/email-service/observability/metrics-analytics/).

Hard bounced addresses are automatically added to your [suppression list](/email-service/concepts/suppressions/) to protect your sender reputation.
Email Service adds eligible recipient-side hard bounces to your [suppression list](/email-service/concepts/suppressions/). Suppressions have no expiration when the mailbox or domain does not exist.

They also have no expiration when the recipient remains unavailable across repeated delivery attempts. Other eligible hard-bounce suppressions last seven days.

### Soft bounces

Expand All @@ -38,7 +39,7 @@ Soft bounces are temporary failures that may succeed if retried:
- Email server temporarily down
- Rate limiting or greylisting

Cloudflare automatically retries soft bounces with exponential backoff over an extended period.
Cloudflare automatically retries soft bounces with exponential backoff. Eligible recipient-side failures create a 24-hour suppression.

## Reputation management

Expand Down
16 changes: 5 additions & 11 deletions src/content/docs/email-service/concepts/email-lifecycle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,27 @@ flowchart LR
### Stage details

1. **Request received:** The system validates the email format, sender authorization, and message structure. Invalid requests are rejected immediately and do not proceed to the next stage.

2. **Rate limit check:** The system checks sending [limits](/email-service/platform/limits/) per account, domain, and recipient to prevent abuse. Requests that exceed these limits are temporarily rejected and must be retried later.

3. **Authentication and reputation**: The system performs email authentication checks and evaluates sender reputation:
- **SPF (Sender Policy Framework)**: Verifies that the sending IP address is authorized to send emails for the domain by checking DNS TXT records. This prevents domain spoofing and improves deliverability.
- **DKIM (DomainKeys Identified Mail)**: Validates the email's cryptographic signature to ensure message integrity and authenticate the sender domain. This builds trust with recipient servers.
- **DMARC (Domain-based Message Authentication)**: Applies domain owner policies for handling emails that fail SPF or DKIM checks, helping prevent phishing and brand impersonation while providing feedback reports.

These authentication mechanisms work together to establish sender legitimacy and protect against email fraud. Senders with low reputation scores may experience throttling or delayed processing.

4. **Suppression list check:** The system checks the recipient against your account's suppression list, which includes bounces, complaints, and unsubscribes. Recipients found on this list are blocked from receiving the email.
4. **Suppression list check:** The system checks each recipient against the Email Sending [suppression list](/email-service/concepts/suppressions/) for your account. Suppressed recipients do not reach the delivery stage or count toward your quota.

The per-sending-domain [**Drop suppressed recipients** setting](/email-service/configuration/domains/#drop-suppressed-recipients) is off by default. When off, the REST API returns `400`, the Workers binding throws `E_RECIPIENT_SUPPRESSED`, and SMTP rejects the message if any recipient is suppressed.

When on, Email Service removes suppressed recipients and processes the remaining recipients. Email Service does not process unsubscribe links, so add unsubscribed recipients manually.

5. **Delivery attempt:** The system connects to the recipient's mail server and attempts message delivery via SMTP. When delivery fails, the system applies different retry logic based on the failure type:
- **Soft bounces (4xx responses)**: The system retries delivery using exponential backoff timing
- **Hard bounces (5xx responses)**: The system marks the email as permanently failed with no retry attempts

6. **Server response handling:** The system processes SMTP response codes from the recipient server to determine the final email status:
- **2xx codes**: The email was delivered successfully
- **4xx codes**: Temporary failure occurred and the email will be retried
- **5xx codes**: Permanent failure occurred and the email cannot be delivered

7. **Final status and metrics:** Based on the server response, the system assigns emails one of these final statuses:
- **Delivered**: The email was successfully accepted by the recipient server
- **Delivery failed**: The email permanently failed delivery (hard bounce) or exceeded the maximum retry attempts (soft bounce). This status appears as `deliveryFailed` when querying the [GraphQL Analytics API](/email-service/observability/metrics-analytics/).
Expand Down Expand Up @@ -82,18 +82,12 @@ flowchart LR
### Stage details

1. **SMTP receipt:** A sending server connects to a Cloudflare MX server and submits the message over SMTP. Messages larger than the [inbound message size limit](/email-service/platform/limits/) are rejected at this stage.

2. **Authentication check:** The system performs [SPF, DKIM, DMARC, and ARC](/email-service/concepts/email-authentication/) checks on the incoming message. Mail that fails authentication according to the sender's DMARC policy is rejected. Mail from IP addresses on a Realtime Block List is also rejected at this stage. Refer to [Postmaster information](/email-service/reference/postmaster/) for details.

3. **Rule match:** The system matches the recipient address against your configured [routing rules](/email-service/configuration/email-routing-addresses/). If [subaddressing](/email-service/configuration/email-routing-addresses/#subaddressing) is enabled, sub-addressed recipients fall back to the base routing rule. If no rule matches and the [catch-all rule](/email-service/configuration/email-routing-addresses/#catch-all-rule) is enabled, the catch-all rule applies.

4. **Action:** The system applies the matched rule's action:
- **Send to an email**: The message is forwarded to the verified destination address (stage 5).
- **Send to a Worker**: The message is passed to your [Worker](/email-service/api/route-emails/email-handler/). The Worker can call `forward()`, `reply()`, or `setReject()`.
- **Drop**: The message is silently discarded. No further processing occurs.

5. **ARC sign and SRS rewrite:** For forwarded messages, the system adds an ARC seal preserving the original authentication results and rewrites the envelope sender using the [Sender Rewriting Scheme](/email-service/reference/postmaster/#sender-rewriting). This allows SPF to pass at the destination server.

6. **Outbound delivery:** The system connects to the destination mail server and delivers the message. Soft bounces are retried with exponential backoff. Hard bounces are returned to the original sender in-session as upstream SMTP errors. Refer to [Postmaster: SMTP errors](/email-service/reference/postmaster/#smtp-errors).

7. **Final status and metrics:** The final outcome is recorded and available through the [Activity log](/email-service/observability/logs/) and the [GraphQL Analytics API](/email-service/observability/metrics-analytics/).
Loading