Skip to content
day3
All guides
Compliance6 min read

One-click unsubscribe: what RFC 8058 actually requires

Two headers, one POST, no confirmation page. One-click unsubscribe is a small standard that a surprising number of senders implement incorrectly, and since 2024 Gmail and Yahoo treat getting it wrong as a deliverability problem.

The short version

  • It takes two headers, not one: List-Unsubscribe carrying an HTTPS URL, and List-Unsubscribe-Post carrying the literal value List-Unsubscribe=One-Click.
  • The mailbox provider sends a POST to your URL. It must unsubscribe the recipient on that POST alone. A confirmation page or a login makes the implementation non-compliant.
  • You still need a visible unsubscribe link in the message body. One-click is in addition, not instead.
  • Gmail expects the unsubscribe to take effect within two days.
  • Sending it on transactional mail is a mistake. It belongs on marketing and bulk mail.

Where this came from

The List-Unsubscribe header has existed since RFC 2369 in 1998, and for most of that time it was a courtesy: a hint some mail clients would surface as an unsubscribe button, pointing at either a URL or a mailto address. It had a design flaw. Some clients would fetch the URL to check it, and a plain GET request to an unsubscribe link is indistinguishable from a person clicking it, which meant automated scanning could unsubscribe people who never asked.

RFC 8058, published in 2018, fixed that by moving the action to POST and requiring the sender to opt in explicitly with a second header. In February 2024 Gmail and Yahoo made it a requirement for bulk senders rather than a nicety, with one-click support specifically expected on marketing mail from June 2024.

The two headers

Both headers are required. One without the other does nothing.
List-Unsubscribe: <https://example.com/u/9fb2c1a4e7>
List-Unsubscribe-Post: List-Unsubscribe=One-Click

List-Unsubscribe holds the URL, in angle brackets. It may hold a comma-separated list including a mailto: alternative, and if it does, the HTTPS URL should come first. List-Unsubscribe-Post holds exactly one value, List-Unsubscribe=One-Click, and its presence is what tells the mailbox provider that a POST to that URL is safe and will be honoured.

When a recipient presses the unsubscribe button their mail client shows, the provider sends a POST to your URL with List-Unsubscribe=One-Click as the request body, content type application/x-www-form-urlencoded. Your endpoint must unsubscribe them and return a success status.

The four ways people get it wrong

  • Sending List-Unsubscribe without List-Unsubscribe-Post. The header is then treated as the old 1998 courtesy version, and one-click does not apply. This is the most common mistake.
  • Answering the POST with a confirmation page. The standard requires the POST itself to complete the unsubscribe. "Are you sure?" is exactly what one-click removes, and a provider that gets a page instead of a completed action may treat your implementation as broken.
  • Requiring authentication on the URL. The recipient is not logged in and the POST comes from the mailbox provider, not from a browser session. The URL has to carry its own unguessable token and work unauthenticated.
  • Putting it on transactional email. A password reset with an unsubscribe header invites someone to opt out of a message they need. One-click belongs on marketing and bulk mail.

The endpoint

The URL should carry a token that identifies the subscription without being guessable and without encoding the email address in a readable form. Sequential ids or base64-encoded addresses both let anyone unsubscribe anyone by iterating.

The shape of the request your endpoint receives
POST /u/9fb2c1a4e7 HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 26

List-Unsubscribe=One-Click

Return 200 on success. Be idempotent: providers retry, and a second POST for an already-unsubscribed address should succeed rather than error. And process it promptly. Gmail's guidance is that the unsubscribe takes effect within two days, which in practice means writing the suppression synchronously rather than dropping the request onto a queue you drain nightly.

Why the complaint rate is the real reason to care

The compliance framing undersells this. The practical value of an easy unsubscribe is that it is the alternative to the spam button, and those two actions have wildly different costs to you. An unsubscribe removes one address from your list. A spam complaint tells the mailbox provider that your mail is unwanted, and it is counted against the 0.3% threshold Gmail publishes for bulk senders.

Anything that adds friction to leaving pushes people toward the button that hurts you more. A confirmation page, a login wall, a preferences centre with fifteen checkboxes: each one converts some number of would-be unsubscribes into complaints. Making it trivially easy to leave is the cheapest deliverability work available.

Subscription topics are the one refinement worth adding, because they give someone a way to reduce your email without leaving entirely. That is a different thing from a preferences page that exists to talk people out of unsubscribing.

How day3 handles it

Both headers go on every campaign automatically, with a per-subscription token, and the endpoint suppresses on the POST itself with no confirmation step. The visible footer link ships alongside it, together with the postal address bulk mail is expected to carry. Transactional mail sent through the API does not get the headers, because it should not.

Unsubscribes write to a per-sender suppression list that survives re-import, so bringing the same CSV back next month cannot re-subscribe someone who left.

Questions

What is RFC 8058?
The standard defining one-click unsubscribe. It requires two headers, List-Unsubscribe with an HTTPS URL and List-Unsubscribe-Post with the value List-Unsubscribe=One-Click, and specifies that a POST to that URL must complete the unsubscribe without any further interaction.
Do I need both List-Unsubscribe and List-Unsubscribe-Post?
Yes. List-Unsubscribe alone is the older RFC 2369 behaviour and does not give you one-click. The List-Unsubscribe-Post header is what signals that a POST is safe and will be honoured, and omitting it is the most common implementation mistake.
Can my unsubscribe URL show a confirmation page?
Not for the one-click flow. The POST itself has to complete the unsubscribe. You can show a confirmation page to someone who arrives by clicking the link in the email body, but the POST from the mailbox provider must not require a second step.
Does one-click unsubscribe replace the link in the email?
No. Keep the visible unsubscribe link in the body. Not every mail client surfaces the header button, and opt-out rules generally expect a clear mechanism in the message itself.
Should transactional email have an unsubscribe header?
No. Password resets, receipts and magic links are messages the recipient needs, and offering to opt them out of those is a mistake. One-click unsubscribe belongs on marketing and bulk mail.
How fast do I have to process an unsubscribe?
Gmail's guidance for bulk senders is within two days. In practice that means writing the suppression as part of handling the request rather than batching it into a job you run overnight.

day3 handles all of this by default.

Authenticated domains, one-click unsubscribe, double opt-in, and automatic suppression. Billed by emails sent, from $1/month.