GLOSSARY

What is List-Unsubscribe?

List-Unsubscribe is an email header defined in RFC 2369 that carries an https or mailto URI so the mail client can show a native unsubscribe button, and RFC 8058 extends it with List-Unsubscribe-Post so a single POST removes the recipient with no confirmation page and no login.

Free forever plan · No credit card required · Cancel anytime

Quick definition

List-Unsubscribe is an email header defined in RFC 2369 that carries an https or mailto URI so the mail client can show a native unsubscribe button, and RFC 8058 extends it with List-Unsubscribe-Post so a single POST removes the recipient with no confirmation page and no login.

In one line: two headers that turn the exit from a scavenger hunt into a single tap.

What it means

The unsubscribe link at the bottom of a marketing email is a convention, not a standard. It is six-point grey text after four paragraphs of footer, and a large share of recipients never find it, so they press the button they can find instead: report spam. That single click is recorded by the mailbox provider against your sending domain and hurts delivery for every other person on your list.

List-Unsubscribe is the standards-based fix. RFC 2369 defined a family of headers for mailing list software, and this is the one that survived. Put a URI in the header, and the mail client can render its own unsubscribe control right next to the sender name, above the message, before the recipient has read a word. RFC 8058 then closed the last gap: with a companion List-Unsubscribe-Post header, the provider can perform the unsubscribe itself with one HTTP POST, so the recipient never leaves the mail client and never sees a landing page.

Since February 2024 this stopped being optional. Gmail and Yahoo both require one-click unsubscribe on bulk marketing mail, along with authentication and a spam complaint rate under 0.3 percent. Sending high volume without it now costs you delivery directly.

The two headers, exactly

Both are single headers on the outgoing message. The URIs go in angle brackets, comma separated, and the https URI goes first:

  • List-Unsubscribe: one or more URIs. An https: URI is what one-click uses. A mailto: URI is the fallback for older clients, and may carry a ?subject= so your inbound parser can match it without reading the body.
  • List-Unsubscribe-Post: the literal value List-Unsubscribe=One-Click. Nothing else is valid. Its presence is what tells the provider it may POST rather than hand the URL to a browser.

The related RFC 2369 headers, List-Id, List-Help, List-Post, List-Owner and List-Archive, are for discussion lists rather than marketing mail. Adding List-Id to a newsletter is harmless and lets recipients filter on it. Adding List-Post to something nobody can post to is just wrong.

The GET trap, and why it costs you your list

This is the failure that actually happens, and it is worth stating plainly. Corporate mail security products rewrite and then visit every URL in every message to check for malware. Mail clients prefetch links to build previews. Archiving systems crawl. All of them issue GET.

If your unsubscribe endpoint performs the removal on GET, every one of those automated visits unsubscribes a real subscriber who never asked. The symptom is a campaign to a corporate-heavy segment where a large slice of one company domain unsubscribes within minutes of the send, all with no opens. RFC 8058 is explicit that the one-click request is a POST for exactly this reason.

The correct shape is two behaviours on one URL:

  • GET renders a page with the recipient address shown and a single confirm button. Idempotent, safe, crawlable without consequence.
  • POST performs the unsubscribe and returns 200. This is what the provider calls, and what the confirm button submits.

Signing the URI

The token in the URL is a capability: whoever holds it can unsubscribe that address. Do not use a database id, and do not use the email address in plain text, which leaks the address to every proxy and log along the way. Use an opaque identifier plus an HMAC over the identifier, the stream and an expiry, keyed with a secret only your application holds. Verify the HMAC before you do anything, and treat a bad signature as a 404 rather than an error, so the endpoint cannot be used as an oracle to test whether an address is on your list.

What happens after the POST

An unsubscribe is not a row you delete. It is a durable statement of consent withdrawal, and it belongs in a suppression list that is checked at send time by the worker that talks to SMTP, not just at the moment a campaign audience is built. A campaign compiled on Monday and sent on Thursday will otherwise mail people who left on Tuesday.

Scope matters as much as speed. Unsubscribing from a weekly newsletter should not silence a password reset, and a recipient who unsubscribes from one brand in a multi-brand account has not unsubscribed from the others. Record which stream the request came from, which is why the signed token should carry it.

Related concepts

  • Suppression list: where every unsubscribe has to land to mean anything.
  • DMARC: the other half of the 2024 bulk sender requirements.
  • DKIM: sign the unsubscribe headers so they cannot be rewritten in transit.
  • Bounce rate: complaints and bounces are the two numbers a mailbox provider watches.
  • Drip campaign: every step of a sequence needs the header, not just the first one.
  • Lead magnet: where most of these subscriptions start, and where consent is recorded.

How Pinlyx handles it

Marketing and lifecycle mail sent from Pinlyx carries both headers automatically, with a signed per-recipient token scoped to the stream it came from. The endpoint answers POST for one-click and renders a confirmation page on GET, so a security appliance crawling the link cannot remove a subscriber. Transactional mail deliberately carries no unsubscribe header. Every removal is written to the workspace suppression list with its reason and timestamp, kept as evidence rather than deleted, and re-checked in the sending worker immediately before the message goes out.

Wire format

The headers, the request, and the test.

If the third block does not return 200 from a machine outside your network, the first two are decoration.

Headers on the outgoing message

From: Pinlyx <hello@pinlyx.com>
To: maya@example.com
Subject: Your weekly pipeline digest
List-Id: Weekly digest <digest.pinlyx.com>
List-Unsubscribe: <https://pinlyx.com/u/8f2c1d4b?s=marketing&t=a91c7e2f>,
 <mailto:unsubscribe@pinlyx.com?subject=unsub-8f2c1d4b>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pinlyx.com; s=resend;
  h=from:to:subject:date:list-unsubscribe:list-unsubscribe-post; ...

Note both list headers inside the DKIM h= list. An unsigned unsubscribe header can be replaced in transit.

What the mailbox provider sends

POST /u/8f2c1d4b?s=marketing&t=a91c7e2f HTTP/1.1
Host: pinlyx.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 26

List-Unsubscribe=One-Click

HTTP/1.1 200 OK
Content-Type: text/plain

unsubscribed

No cookies, no session, no Referer, no user agent you can rely on. Anything that requires one of those turns this into a 403 and the button disappears from the client.

The one-line test

curl -i -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "List-Unsubscribe=One-Click" \
  "https://pinlyx.com/u/8f2c1d4b?s=marketing&t=a91c7e2f"

# expected: HTTP/1.1 200, no redirect, no challenge page
# a 301 to https is fine only if the POST body survives it, which it often does not
Conformance checklist

Six requirements, all of which are load bearing.

RequirementWhy it matters in production
The endpoint must accept POSTRFC 8058 one-click sends an HTTP POST with Content-Type application/x-www-form-urlencoded and the body List-Unsubscribe=One-Click. A route that only answers GET is not one-click, whatever the header claims.
GET must never unsubscribeSecurity gateways, link scanners and mail-client prefetchers issue GET requests on every URL they find. If GET performs the removal, an appliance will unsubscribe your recipients for them, silently, in bulk.
No authentication, no interstitialThe provider POSTs from its own infrastructure with no cookies. A login wall, a consent banner, a bot challenge or a Are you sure page all count as a failure.
Return 2xx quicklyAnswer 200 or 202 within a couple of seconds and do the real work asynchronously. A 403 from a bot-protection rule is the most common reason a provider stops showing the button.
The URI must be per-recipient and unguessableSign it. An incrementing id lets anyone enumerate your list and unsubscribe strangers, and it leaks the size of your list while they do it.
Honour it within two daysThe Gmail and Yahoo bulk sender rules require processing within two days. CAN-SPAM allows ten business days, GDPR expects it without undue delay. Two days is the number to build to.
Watch out for

A whole company unsubscribing in ninety seconds.

If a campaign shows a burst of unsubscribes from one corporate domain, all within a couple of minutes of the send, all with zero opens and zero clicks recorded, nobody unsubscribed. Their mail security gateway crawled the links, your endpoint acted on GET, and it removed everyone it could reach.

Fix the endpoint first, then restore the affected addresses only with a re-consent message sent to a small sample. Bulk re-subscribing people whose removal you cannot explain is worse than losing the addresses.

List-Unsubscribe: FAQ

The questions that come up when the native unsubscribe button stops appearing.

You need both. The header drives the native button that Gmail, Apple Mail and Outlook render next to the sender name, and the footer link is what a recipient looks for when the client does not render one. They must point at the same identity and the same suppression, otherwise someone unsubscribes twice and still receives mail, which is how a complaint becomes a spam report.
No. Password resets, receipts, security alerts and delivery notifications are messages the recipient asked for by taking an action. Put an unsubscribe header on them and someone will use it, then open a support ticket because their invoices stopped arriving. Keep marketing, lifecycle and transactional as separate streams with separate suppression, and only put the header on the first two.
Almost always because the POST is being blocked before it reaches your application. Cloudflare bot protection, a WAF rule that rejects requests with no Referer, a redirect from http to https that turns the POST into a GET, or a CSRF filter that requires a token the provider cannot have. Test with curl -X POST -d "List-Unsubscribe=One-Click" against the exact URL you embedded, from outside your network.
List the https URI first. Both are legal and some clients pick the mailto, but one-click as defined in RFC 8058 only applies to the https URI, and a mailto unsubscribe means you have to parse an inbound message and match it to a subscriber, which is slower and easier to get wrong. Keep the mailto as a fallback for clients that only support RFC 2369.
No, and that is the whole point of making it easy. An unsubscribe is a clean exit that costs you one address. A spam complaint, which is what people click when they cannot find the exit, is recorded against your sending domain and IP, counts towards the 0.3 percent threshold Gmail publishes, and damages delivery for every other recipient. A prominent unsubscribe is a deliverability feature, not a leak.
Yes. Add List-Unsubscribe and List-Unsubscribe-Post to the h= tag of your DKIM signature. Headers not covered by the signature can be added or replaced in transit without breaking it, and an unsubscribe URI is exactly the header an attacker would want to rewrite. Signing it also stops a relay from adding a second, conflicting one.
Ready to ship

Make leaving easy. Keep the inbox open.

Pinlyx ships signed one-click unsubscribe on every marketing send, keeps transactional mail out of it, and writes each removal to a suppression list checked at send time.

Free forever plan · GDPR-ready · No credit card required

We value your privacy

We use cookies to improve our site, analyze traffic, and personalize ads. You can accept all, reject non-essential, or customize your choices. Read our Cookie Policy.