Pular para o conteúdo

Email headers

Which email headers you can set, which are auto-generated, and how they are validated

Atualizado em Ver como Markdown

When sending emails with Cloudflare Email Service, you can set custom headers using the headers field in the Workers API or REST API. The Email Service uses a allowlist-based approach — only explicitly approved headers are accepted. Any header not on the allowlist (and not an X- prefixed custom header) is rejected at API time with a clear error.

When sending over SMTP, set headers directly in the MIME message rather than through a headers field. The same allowlist applies.

Platform-controlled headers

These headers are auto-generated by the Cloudflare Email Service infrastructure. You cannot set or override them. If you include any of these in the headers object, the API returns E_HEADER_NOT_ALLOWED.

Header Behavior
Date UTC timestamp set at acceptance time
Message-ID Generated with Cloudflare domain for unique tracking
MIME-Version Always 1.0
Content-Type Generated from body parts provided
Content-Transfer-Encoding Generated from content analysis
DKIM-Signature Signed by Cloudflare infrastructure
Return-Path Set to Cloudflare bounce processor
Received Added per RFC 5321 at each hop
Feedback-ID Generated for Google Postmaster Tools reputation feedback
ARC-* Authentication chain for forwarding
TLS-Required Platform-controlled delivery infrastructure setting
TLS-Report-Domain TLS failure reports route to Cloudflare infrastructure
TLS-Report-Submitter References Cloudflare sending domain
CFBL-Address Complaint feedback loop address (RFC 9477)
CFBL-Feedback-ID Complaint feedback loop ID (RFC 9477)

Headers that correspond to first-class API fields — From, To, Cc, Bcc, Subject, Reply-To — are also rejected in the headers object with E_HEADER_USE_API_FIELD. Set these using the dedicated API fields (from, to, cc, bcc, subject, replyTo for Workers / reply_to for REST) instead.

Allowlisted custom headers

These headers can be set via the headers field. Any header not listed here and not starting with X- is rejected with E_HEADER_NOT_ALLOWED.

Threading and reply headers

Header RFC Notes
In-Reply-To RFC 5322 Critical for email threading in all clients
References RFC 5322 Critical for email threading in all clients

List management headers

Header RFC Notes
List-Unsubscribe RFC 2369 Must contain <https://...> and/or <mailto:...> URI(s). HTTP (non-TLS) URIs are rejected. Gmail and Yahoo require this for bulk senders. Always DKIM-signed per RFC 8058.
List-Unsubscribe-Post RFC 8058 Must be exactly List-Unsubscribe=One-Click (case-sensitive). Requires List-Unsubscribe with an HTTPS URI.
List-Id RFC 2919 List identification
List-Archive RFC 2369 URL to list archive
List-Help RFC 2369 URL for help
List-Owner RFC 2369 List owner contact
List-Post RFC 2369 Address for posting
List-Subscribe RFC 2369 Subscribe URL or address
Precedence De facto standard Accepted values: bulk, list, junk

Automated message identification

Header RFC Notes
Auto-Submitted RFC 3834 Values: auto-generated, auto-replied, auto-notified

Content and display

Header RFC Notes
Content-Language RFC 3282 Language of content (for example, en, fr)
Keywords RFC 5322 Message keywords (comma-separated for multiple values)
Comments RFC 5322 Additional comments (comma-separated for multiple values)
Importance RFC 2156 Values: high, normal, low
Sensitivity RFC 2156 Values: personal, private, company-confidential
Organization RFC 4021 Sender's organization name

Delivery and notification

Header RFC Notes
Require-Recipient-Valid-Since RFC 7293 Address reuse protection

Modern standards

Header RFC Notes
Archived-At RFC 5064 URL where message is archived

Custom X-headers

Any header starting with X- is allowed. This covers common headers like X-Mailer, X-Priority, X-Campaign-ID, and any custom tracking headers your application needs.

  • Name format: X-[A-Za-z0-9\-_]+, maximum 100 characters
  • Value: UTF-8, maximum 2,048 bytes
  • No count limit on X-headers (subject to the 16 KB total payload limit)

Usage examples

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "to": "user@example.com",
    "from": "notifications@yourdomain.com",
    "subject": "Your weekly digest",
    "html": "<h1>Weekly Digest</h1>",
    "headers": {
      "In-Reply-To": "<original-message-id@yourdomain.com>",
      "References": "<original-message-id@yourdomain.com>",
      "List-Unsubscribe": "<https://yourdomain.com/unsubscribe?id=abc123>",
      "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
      "X-Campaign-ID": "weekly-digest-2026-03",
      "X-User-Segment": "premium"
    }
  }'
const response = await env.EMAIL.send({
	to: "user@example.com",
	from: "notifications@yourdomain.com",
	subject: "Your weekly digest",
	html: "<h1>Weekly Digest</h1>",
	headers: {
		// Threading
		"In-Reply-To": "<original-message-id@yourdomain.com>",
		References: "<original-message-id@yourdomain.com>",

		// List management (required by Gmail/Yahoo for bulk senders)
		"List-Unsubscribe": "<https://yourdomain.com/unsubscribe?id=abc123>",
		"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",

		// Custom tracking
		"X-Campaign-ID": "weekly-digest-2026-03",
		"X-User-Segment": "premium",
	},
});

Header limits

Limit Value
Max allowlisted (non-X) custom headers 20
Max header name length 100 bytes
Max header value length 2,048 bytes
Total custom headers payload 16 KB

The total payload is calculated as sum(len(name) + 2 + len(value) + 2) for all custom headers (name + : + value + CRLF). Allowlisted and X-headers are counted together toward this limit.

Validation rules

  1. Header names — ASCII only, no spaces, no colons, 1–100 characters. Allowlisted headers must match [A-Za-z0-9\-]+. X-headers must match X-[A-Za-z0-9\-_]+ (underscores allowed only in X-headers).
  2. Header values — UTF-8 allowed, maximum 2,048 bytes, no bare CR/LF. Empty values are rejected.
  3. Case-insensitive matching — Header names are matched case-insensitively per RFC 5322 §2.2. The canonical casing from the allowlist is used in the generated message.
  4. Proper line folding — Long headers are folded at 78 characters per RFC 5322 using CRLF+WSP, not MIME encoding.
  5. Single occurrence — The headers type is { [key]: string }, so each header name can appear at most once. For headers that support multiple values (such as Keywords or Comments), use comma-separated values in a single string.

Error codes

Error Code When Example message
E_HEADER_NOT_ALLOWED Header is platform-controlled or not on the allowlist Header 'Date' is not allowed. It is auto-generated by the platform.
E_HEADER_USE_API_FIELD Header corresponds to a first-class API field Header 'From' must be set via the 'from' API field, not the 'headers' object.
E_HEADER_VALUE_INVALID Header value is malformed or empty Header 'List-Unsubscribe' must contain angle-bracket HTTPS or mailto URI(s).
E_HEADER_VALUE_TOO_LONG Header value exceeds 2,048 byte limit Header 'X-Campaign-ID' value exceeds 2048 byte limit.
E_HEADER_NAME_INVALID Header name contains invalid characters or exceeds 100 bytes Header name 'Bad Header!' contains invalid characters.
E_HEADERS_TOO_LARGE Total custom headers payload exceeds 16 KB Total custom headers payload (17.2KB) exceeds 16KB limit.
E_HEADERS_TOO_MANY Too many allowlisted (non-X) custom headers 21 allowlisted headers provided, maximum is 20.