Unsubscribe handling
Marketing mail needs a working unsubscribe path. Anypost can generate a one-click unsubscribe for a message, leave it off for transactional mail, or forward an unsubscribe header you supply yourself.
One-click unsubscribe is not optional for bulk mail. Gmail and Yahoo require
any sender of 5,000 or more messages a day to personal accounts to offer
one-click unsubscribe on promotional mail and to honor the request within two
days; Microsoft requires a working unsubscribe link on bulk mail. mode: "generate" satisfies these requirements. Transactional mail is exempt.
Three behaviors
The optional unsubscribe object on POST /v1/email selects one of two modes.
A third behavior, forwarding your own header, needs no mode at all.
| You want | What to send |
|---|---|
| Anypost to generate a one-click unsubscribe | unsubscribe: { "mode": "generate" } |
| No unsubscribe header at all | unsubscribe: { "mode": "none" }, or omit unsubscribe |
| To use your own list-management unsubscribe | A List-Unsubscribe header; see Forward your own header |
Let Anypost generate it
mode: "generate" mints a signed, per-recipient unsubscribe and injects the
List-Unsubscribe and List-Unsubscribe-Post headers. Mail clients that
support RFC 8058, including Gmail and Apple Mail, render a native Unsubscribe
button from them.
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": "March newsletter",
"html": "<p>This month at Acme.</p>",
"topic": "newsletter",
"unsubscribe": { "mode": "generate", "display_name": "Acme newsletter" }
}'A generated unsubscribe requires a topic. The topic is the bucket the
recipient unsubscribes from: a send with topic: "newsletter" unsubscribes
them from your newsletter, not from your receipts. A mode: "generate" send
with no topic is rejected with a validation_error. See
Tags, topics & campaigns.
display_name is optional. It is a human-readable label, up to 120 characters,
shown on the confirmation page Anypost hosts when a recipient unsubscribes.
When a recipient unsubscribes, Anypost records a suppression scoped to that
topic and emits an email.unsubscribed event. Later sends to that address on
the same topic are dropped; other topics are unaffected. See
Suppressions.
The link in the body
A native client button is not always visible, so put an unsubscribe link in the
body too. On a mode: "generate" send, write {{unsubscribe_url}} in the HTML
body and Anypost replaces it with the same per-recipient unsubscribe URL it put
in the header:
<p><a href="{{unsubscribe_url}}">Unsubscribe</a></p>The placeholder is filled whether or not the send carries other variables.
No unsubscribe header
mode: "none" injects no unsubscribe header. It is the default: a send that
omits unsubscribe behaves the same way.
Use it for transactional mail that must not carry unsubscribe semantics, such
as a password reset or a one-time code. A recipient cannot opt out of a
security email, and such a send usually carries no topic at all.
Forward your own header
If you already run list management elsewhere, set your own List-Unsubscribe
header in the headers map. Anypost forwards it rather than
generating its own. A customer-supplied header always wins: it is used even
when unsubscribe.mode is generate.
A supplied header is checked and lightly normalized before it is sent. Common,
recoverable mistakes are fixed and reported back in the warnings array of the
response:
- CR, LF, and tab characters are stripped, and runs of whitespace collapsed.
- Missing
<>angle brackets around a URI are added. - A
mailto:URI listed before anhttps:URI is reordered, because one-click receivers scan for the first HTTPS URI.
Shapes that cannot be made valid are rejected with 422 and an error.code.
The most common causes: a List-Unsubscribe-Post header without a matching
List-Unsubscribe, a one-click header whose List-Unsubscribe carries no
HTTPS URL, and a non-TLS http: URL. See API conventions.
In a batch
In a batch send, an unsubscribe object in
defaults applies to every entry that does not set its own. The
topic-required rule for mode: "generate" is checked per entry, against each
entry's merged topic.
Where to go next
- Suppressions: the addresses Anypost will not send to, and how a topic scopes them.
- Tags, topics & campaigns: the topic an unsubscribe is scoped to.
- Webhooks: receive the
email.unsubscribedevent.