Headers & custom headers
The headers field carries application-specific headers on a message, such as
a reference ID your own systems read back. Headers that carry transport,
authentication, or routing meaning are managed by Anypost and cannot be set
this way.
Set a header
headers is a name-to-value object on POST /v1/email:
curl https://api.anypost.com/v1/email \
-H "Authorization: Bearer $ANYPOST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <[email protected]>",
"to": ["[email protected]"],
"subject": "Order confirmed",
"html": "<p>Your order is on its way.</p>",
"headers": {
"X-Order-Id": "1190",
"X-Entity-Ref": "customer-4471"
}
}'Each pair becomes one header on the delivered message.
Names and values
A header name must be alphanumeric and hyphens only, start with a letter or digit, and be at most 78 characters. A name that breaks those rules is dropped from the map.
A message may carry at most 25 custom headers.
Headers Anypost manages
Some headers are set by Anypost itself, or carry trust signals that a sender
cannot legitimately originate. If you include one in headers, it is dropped
rather than applied. Use the headers map for your own application headers,
not to override transport, identity, authentication, or trace headers.
| Category | Examples | Why it is managed |
|---|---|---|
| Addressing and identity | From, To, Cc, Bcc, Subject, Reply-To, Sender | Set from the request's own fields. |
| Message metadata | Date, Message-ID, MIME-Version, Content-Type, Content-Transfer-Encoding, Content-Disposition | Set by Anypost or generated when the message is encoded. |
| Authentication | DKIM-Signature, Authentication-Results, Received-SPF | Owned by the platform; forging them would misrepresent the message. |
| Trace | Received, Return-Path, Delivered-To, X-Original-To, and the Resent-* and ARC-* families | Added by receiving servers. A sender cannot legitimately originate them. |
| Loop control | Auto-Submitted, Precedence | Affect vacation responders and bounce handling. |
| Anypost-managed | X-Campaign and the X-Anypost-* namespace | Set from dedicated request fields that apply their own validation. |
For a campaign label, use the top-level campaign field rather than a
header: the field is validated, and a header of the same name is dropped.
The one carve-out in the X-Anypost-*
namespace is X-Anypost-Track-Opens / X-Anypost-Track-Clicks; tracking is
covered in Open & click tracking.
What errors, and what is dropped
Header handling is forgiving by design. A malformed name, an over-long or empty value, and a managed header are all dropped silently, so a small mistake never blocks a send.
Exceeding the 25-header cap is the one condition that fails the request: it
returns 400 with a validation_error. See
API conventions for the error shape.
The trade-off is that a dropped header is not reported back. If a custom header does not arrive, check it against the name and value rules above.
Headers in a batch
In a batch send, a headers map in defaults is
shallow-merged with each entry's own map. On a name collision the entry's value
wins. The 25-header cap applies to the merged result.
Where to go next
- Send a single email: the full
POST /v1/emailrequest. - Batch sending: shared and per-entry headers in one request.