One-click unsubscribe and the List-Unsubscribe header
One-click unsubscribe lets a recipient leave your list from the mail app itself, without opening a web page. You enable it with two headers: List-Unsubscribe, which holds an HTTPS address that identifies the recipient and the list, and List-Unsubscribe-Post: List-Unsubscribe=One-Click. Both must be covered by a valid DKIM signature. When the person clicks unsubscribe, the mailbox provider sends an HTTPS POST to that address, and your server removes them on the spot, with no login and no confirmation step. Gmail and Yahoo require it of bulk senders for marketing and subscribed mail.
The List-Unsubscribe header
The header is older than the one-click rules. RFC 2369 (1998) defines a family of list headers, and its section 3.2 describes List-Unsubscribe as the command that removes the recipient from the list. The value is one or more URLs in angle brackets, separated by commas. Section 2 of the RFC says the URLs are in order of preference from left to right, and a mail client uses the leftmost one it supports. Section 3 allows at most one List-Unsubscribe field per message.
The original header worked with any URL, usually a mailto: address. That left a problem, which RFC 8058 explains in section 1: anti-spam systems often fetch every link in a message header automatically, so a sender cannot tell whether a GET request came from a person or a filter. Senders protected themselves with a landing page and a confirm button, and the unsubscribe stopped being one click.
How one-click works (RFC 8058)
RFC 8058 solves this by adding a second header that tells the receiver it may unsubscribe with a POST request. A POST is something a link scanner does not send on its own, and section 3.2 says the receiver must not send it without the user's consent.
The rules for senders are in section 3.1 and section 4:
- Put exactly one
List-Unsubscribeand oneList-Unsubscribe-Postheader in the message. List-Unsubscribemust contain one HTTPS URI. It may also contain other URIs, such asmailto:.List-Unsubscribe-Postmust contain the single pairList-Unsubscribe=One-Click, nothing else.- The URI must carry enough information to identify the recipient and the list, because the POST has no other arguments. It should use an opaque, hard-to-forge value rather than the plain address and list name, and your server should check that value.
- The message must have a valid DKIM signature that lists both headers in its
h=tag. Without it, section 4 says, the receiver should not offer one-click unsubscribe for that message. - Your server must not answer with a redirect. Section 3.1 notes that redirected POSTs have not worked reliably.
On the receiving side, the mailbox provider posts the body List-Unsubscribe=One-Click to your URI, either as multipart/form-data or as application/x-www-form-urlencoded. The RFC also says the request must not carry cookies, HTTP authorization or other context, so the unsubscribe cannot be tied to earlier web activity.
Example headers
A message with a one-click link and a mailto: fallback:
List-Unsubscribe: <https://example.com/u/8f3kq2z7hw>,
<mailto:unsubscribe@example.com?subject=unsubscribe-8f3kq2z7hw>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=s2026;
h=from:to:subject:date:message-id:list-unsubscribe:list-unsubscribe-post;
bh=...; b=...What the mailbox provider sends when the person clicks unsubscribe:
POST /u/8f3kq2z7hw HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
List-Unsubscribe=One-ClickThe token 8f3kq2z7hw stands in for whatever opaque value your system issues per recipient and list. Section 8 of RFC 8058 has more examples, including a multipart body.
mailto or https
| Item | mailto: only | HTTPS with List-Unsubscribe-Post |
|---|---|---|
| How it reaches you | An email to your unsubscribe address | An HTTPS POST to your endpoint |
| What you must run | A mailbox and a parser for incoming requests | A web endpoint |
| Gmail one-click requirement | Not met | Met |
| Yahoo | Accepted | Highly recommended |
Google's sender guidelines FAQ says mailto: links are still supported but do not meet its one-click requirement, and that a link to a landing page does not comply with RFC 8058. Yahoo's sender best practices accept mailto: but highly recommend the POST method. Keeping both in the header costs nothing: a client that cannot POST can still use the mailto:.
What Gmail and Yahoo require
Both providers set the rule for bulk senders; the Gmail and Yahoo sender requirements guide covers who counts as one.
Gmail. Google's email sender guidelines say that senders of 5,000 or more messages a day must support one-click unsubscribe in marketing and subscribed messages, and must also include a clearly visible unsubscribe link in the body. The FAQ adds the details:
- One-click is required only for marketing and promotional messages. Transactional mail, such as password resets and reservation confirmations, is exempt (see transactional vs marketing email).
- An unsubscribe removes the person only from the list that the message belongs to.
- Google recommends processing the request within 48 hours.
- If your unsubscribe links are unavailable for an extended period, you no longer meet the requirement and lose eligibility for Gmail's mitigation help.
Yahoo. Yahoo asks bulk senders for a working List-Unsubscribe header that supports one-click for marketing and subscribed messages, a clearly visible link in the body (it may lead to a preference page), and an unsubscribe process that does not require users to log in. Yahoo says to honor unsubscribes within 2 days.
Outlook.com does not require the one-click headers, but sending them does no harm; see Outlook sender requirements.
Build the POST endpoint
The endpoint is small, but each detail matters:
- Issue a token per recipient and list. Store it, or derive it with a keyed hash (HMAC) so it cannot be guessed. Do not put the plain email address in the URL.
- Accept POST without a session. No login, no cookies, no CSRF token. Many web frameworks reject cross-site POSTs by default, so exempt this route explicitly.
- Read both encodings. Accept
application/x-www-form-urlencodedandmultipart/form-data, and check that theList-Unsubscribefield equalsOne-Click. - Answer directly. Return a 2xx status from the same URL. Never send a 3xx redirect.
- Make it idempotent. A second POST for the same token should succeed quietly, not fail, because a person may click twice or a request may be repeated.
- Act at once. Write the address to your suppression list in the same request, and sync it to every system that sends to that list. Both providers' deadlines are about two days; aim for immediate.
- Keep GET harmless. Section 3.2 of RFC 8058 says the POST target is the same address a person would open manually. A GET to that URL should show a page with an unsubscribe button, never unsubscribe by itself, since link scanners fetch it.
- Reject bad tokens with a 4xx status and do nothing.
Sign the message after you add the headers. If a later step in your pipeline adds or rewrites List-Unsubscribe after DKIM signing, the signature breaks and the one-click option may disappear. The DKIM selectors and key rotation guide covers how signing keys are published.
Test it
- Send a message to a mailbox you own and open its raw source ("Show original" in Gmail). Confirm both headers are present, DKIM passes, and
list-unsubscribeandlist-unsubscribe-postappear in theh=tag. - Check that the signing key is published with the DKIM checker.
- Simulate the provider's request with both encodings:
curl -i -X POST -d 'List-Unsubscribe=One-Click' https://example.com/u/8f3kq2z7hw
curl -i -X POST -F 'List-Unsubscribe=One-Click' https://example.com/u/8f3kq2z7hw- Expect a 2xx status and no
Locationheader. Send the same request again and expect the same result. - Send a GET and confirm the person is still subscribed. Change one character of the token and confirm the request is rejected.
- Confirm the address is suppressed in every sending system.
Do not treat a missing unsubscribe button in Gmail as proof of a fault: Google's FAQ says the button at the top of a message appears only when the message passes Gmail's automated eligibility checks.
The in-body unsubscribe link
The header and the body link do different jobs, and you need both. The header serves the mail app's own button. The body link serves people who look for it in the message, and it is what many laws ask for.
In the United States, the FTC's CAN-SPAM compliance guide says commercial messages must offer a clear way to opt out, that you must honor an opt-out within 10 business days, and that the mechanism must keep working for at least 30 days after you send. You may not charge a fee, ask for personal information beyond the email address, or require more than a reply email or a visit to a single web page. Other countries have their own rules; check the ones that apply to your recipients.
Gmail's FAQ says that when the one-click header is present, the body link does not itself have to be one-click: it may lead to a preference page where people can pick topics or a lower frequency. Gmail and Yahoo's two-day windows are much shorter than CAN-SPAM's, so process both kinds of request the same way, at once.
Why it matters for deliverability
RFC 8058 states the reasoning plainly: when unsubscribing is hard, people report the mail as spam instead, and streams with many spam reports lose inbox placement. Spam reports count against your sender reputation and show up in feedback loops and in Google Postmaster Tools. An unsubscribe costs you one recipient; a complaint costs you standing with every recipient at that provider.
Questions
Do transactional emails need one-click unsubscribe?
Not at Gmail, whose FAQ limits the requirement to marketing and promotional messages. Yahoo applies it to marketing and subscribed messages. A receipt or password reset does not need the headers.
Does the DKIM signature have to use my From: domain?
RFC 8058 asks for a valid DKIM signature that covers both headers; it does not name the signing domain. For bulk mail to Gmail and Yahoo you need DMARC alignment anyway, so sign with your own domain and you meet both rules at once.
Can I ask people why they are leaving?
Not in the one-click flow: RFC 8058 says one-click has no way to ask the user anything, such as which list to leave. Put a short optional survey or a preference choice on the page your body link opens instead.
Try it
Check that your signing key is published with the DKIM checker, and clean old addresses with bulk email verification before your next campaign.
Related
- Glossary: suppression list and complainer.
- The valid status: why complaints hurt.
- How to clean an email list.
Related guides
- Gmail and Yahoo sender requirements
- Email feedback loops explained
- Transactional vs marketing email
- DKIM selectors and key rotation
- Sender reputation explained
- All guides
Sources
- RFC Editor: RFC 8058, Signaling One-Click Functionality for List Email Headers: sender and receiver rules, DKIM coverage, no cookies or redirects, examples.
- RFC Editor: RFC 2369, The Use of URLs as Meta-Syntax for Core Mail List Commands: the
List-Unsubscribeheader, URL order and one field per message. - Google: Email sender guidelines FAQ: which messages need one-click,
mailto:and landing pages, 48 hours, eligibility checks. - Google: Email sender guidelines: one-click and a visible body link for senders of 5,000 or more messages a day.
- Yahoo: Sender best practices: one-click header, POST vs
mailto:, body link, no login, 2 days. - FTC: CAN-SPAM Act, A Compliance Guide for Business: opt-out rules, 10 business days, 30 days.
How we wrote this: drafted by the email-validation.org team with the help of AI writing tools, from our product documentation and the sources linked in the text.