Zuletzt aktualisiert: 2026-05-127 Min. Lesezeit

Custom Email Headers — When and Why

Truncus lets you inject a small set of standard RFC headers into the outbound MIME of every send. The feature is off by default and must be enabled explicitly in Dashboard → Settings → Email Features. It is available on the Pro and Scale plans.

When to enable

Turn it on if you are sending:

  • Newsletters or digests — Gmail and Yahoo require a working List-Unsubscribe header on bulk mail. Without it your sender reputation will degrade and inbox placement will follow.
  • Cold outreach sequences — same Gmail/Yahoo requirement, and Feedback-ID lets you slice Postmaster Tools by cohort or campaign.
  • Auto-reply / digest mail — set Auto-Submitted: auto-generated so vacation responders and other auto-mailers skip your message.
  • Threaded transactional mail — use References + In-Reply-To to keep replies in the right thread (e.g. an order-status mail in the original order thread).

When NOT to enable

Leave it off if you are sending only transactional mail (password resets, receipts, magic links). Several inbox providers treat the presence of List-Unsubscribe as a "this is bulk" signal — exactly what you don't want for a one-to-one receipt.

Allowed headers

HeaderUse case
List-UnsubscribeOne-click unsubscribe URL and/or mailto.
List-Unsubscribe-PostCompanion to List-Unsubscribe enabling RFC 8058 one-click.
Auto-SubmittedSuppresses vacation responders for automated mail.
Feedback-IDGmail Postmaster Tools cohort/campaign identifier.
X-Entity-Ref-IDGmail thread-collapse hint.
X-MailerFree-form mailer identifier.
ReferencesRFC 5322 threading — list of parent Message-IDs.
In-Reply-ToRFC 5322 threading — direct parent Message-ID.

Everything else is rejected. In particular, you cannot set From, To, Bcc, Subject, Reply-To, Message-ID, DKIM-Signature, Content-Type, or any ARC-* header. These are managed by Truncus and SES so the message stays authentic, signed, and routable.

Example

POST https://truncus.co/api/v1/emails/send
Authorization: Bearer tr_live_...
Idempotency-Key: 9b8b...

{
  "to": "subscriber@example.com",
  "from": "newsletter@mail.yourdomain.com",
  "subject": "Weekly digest",
  "html": "<h1>Hi!</h1>",
  "headers": {
    "List-Unsubscribe": "<https://app.example.com/u/abc123>, <mailto:unsubscribe@example.com>",
    "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
    "Feedback-ID": "weekly:saas:cohort-42"
  }
}

Errors

HTTPCodeMeaning
403custom_headers_not_enabledThe feature is off for this account. Enable in Dashboard → Settings → Email Features.
400header_not_allowedA denylisted header (e.g. From) or non-allowlisted header was sent. The response includes a denied array.
400invalid_headerBad shape, CR/LF in a value, too many keys, or payload over 2 KB.

Limits

  • Maximum 10 headers per send
  • Header name max 80 chars, ASCII letters/digits/- only
  • Header value max 998 chars (RFC 5322 line limit)
  • Total serialized payload ≤2 KB
  • CR and LF in values are rejected (CRLF injection defense)

Edge cases

Caller vs. tracking-layer precedence

Truncus' click-tracking layer automatically adds a List-Unsubscribe + List-Unsubscribe-Post pair when tracking is enabled on the send. If you also pass either header via headers, your value wins. The tracking-layer default is suppressed on a per-header basis (so passing only List-Unsubscribe still gets the auto-generated List-Unsubscribe-Post, and vice versa). Dedupe is keyed on the lowercased header name and runs before MIME emit — Gmail and Yahoo reject mail with duplicate List-Unsubscribe lines under the 2024 Bulk Sender requirements, so this is intentional and not configurable.

Why these headers are on the denylist

Header(s)Why denied
From, Sender, Return-Path, Resent-FromIdentity. Allowing override would let any caller spoof the sending address inside an otherwise-verified domain, defeating SPF/DKIM/DMARC alignment.
To, Cc, Bcc (and Resent-* variants)Envelope. These are derived from the JSON body so suppression-list checks, dedupe, recipient cooldowns, and warmup caps all see the real recipient set. Allowing header overrides would let Bcc recipients silently bypass suppression.
Subject, Reply-ToOverlap with body params. The existing subject and reply_to fields are how you set these — exposing them twice would create ambiguity for which value wins.
Date, Message-ID, Resent-Date, Resent-Message-IDTruncus-owned. Message-ID is the cross-provider correlation anchor (paired with X-Truncus-Global-Message-Id) — overriding it would break webhooks and replay.
DKIM-Signature, ARC-*, Authentication-Results, Received, Received-SPFAuthentication. SES signs DKIM at send time and receiving MTAs add the rest. A caller-provided value would either be stripped by SES or, worse, accepted and immediately invalidated.
Content-Type, Content-Transfer-Encoding, MIME-VersionContent negotiation. Truncus builds the multipart structure (text + html + optional attachments). Overriding these breaks MIME parsing in major clients.

Non-ASCII header values

Header values are passed through to the MIME unchanged. Non-ASCII bytes are valid UTF-8 in the value but will not be auto-encoded — several receivers will mangle non-ASCII characters in headers they don't recognize as encoded-word (RFC 2047). If you need an accented character in a header value (rare — typically only useful in custom X-Mailer strings), pre-encode it yourself as =?UTF-8?B?…?=. The validator rejects only CR, LF, NUL, and most C0/C1 control bytes — UTF-8 letter bytes pass.

Rate limiting scope

Custom headers do not add a separate rate-limit scope. The same per-API-key burst limiter (10/sec, 60/min) and the same monthly plan cap (3K / 50K / 300K) apply. There is no per-header throttle. The 2 KB serialized-size cap is the only quantitative limit attached to the feature itself.

Syntax error in header value

Validation runs before persistence and before suppression / cap checks. A request with a bad header value returns 400 invalid_header with a message naming the offending header and the rule it broke. The email is never written to the database, never counted against your monthly cap, and never sent — there is no partial state to clean up.

Documentation translations

This article is currently English-only. The Dutch and German manual show the same English content as a fallback until translation passes happen — the article metadata (titles in the sidebar) is localized, but the body text is shared. Track the translation pass in the content/manual/{nl,de}/ directories.

Eigene E-Mail-Header — Wann und Warum