List-Unsubscribe Header: How to Set Up One-Click Unsubscribe the Right Way
Set up the List-Unsubscribe and List-Unsubscribe-Post headers: RFC 8058 syntax, endpoint rules, DKIM signing, testing and Gmail and Yahoo requirements.

To enable one-click unsubscribe you add two headers to every marketing email: List-Unsubscribe: <https://example.com/u/TOKEN> and List-Unsubscribe-Post: List-Unsubscribe=One-Click. The HTTPS URL must accept a POST and unsubscribe immediately with no redirect, no cookies and no login, and both headers must be listed in your DKIM signature. Gmail requires it from bulk senders (5,000+ messages a day) and states that a mailto: or plain link alone does not satisfy the requirement; requests should be honoured within 48 hours (Yahoo says 2 days).
The small "Unsubscribe" link that appears next to the sender name in Gmail and Yahoo is not magic. It is rendered from a pair of email headers that your sending system has to include. Since the Gmail and Yahoo bulk-sender requirements took effect in February 2024, one-click unsubscribe is no longer a nice-to-have for marketing mail: without it, you risk throttling, spam-folder placement and, since Gmail began ramping up enforcement in November 2025, outright rejections.
This guide explains exactly what the headers must look like, what your server has to do when a mailbox provider calls the link, how to sign the headers, and how to test everything before a campaign goes out.
What the List-Unsubscribe headers are
Two specifications define the behaviour:
- RFC 2369 defines
List-Unsubscribe: one or more URIs in angle brackets, separated by commas. The URI can bemailto:orhttps:. Mail clients use it to show an "Unsubscribe" control. - RFC 8058 adds
List-Unsubscribe-Postso the mailbox provider can unsubscribe the user with a single HTTPSPOST, without opening a web page.
Together they look like this:
List-Unsubscribe: <mailto:unsubscribe@example.com?subject=unsubscribe>,
<https://example.com/unsubscribe/6f1c9a7e3b>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
RFC 8058 is strict about the second header: a message must carry exactly one List-Unsubscribe-Post header whose value is the single pair List-Unsubscribe=One-Click, and the List-Unsubscribe header must contain at least one HTTPS URI.
Why you need it: the Gmail and Yahoo rules
| Gmail | Yahoo | |
|---|---|---|
| Who must comply | Senders of close to 5,000 or more messages a day to personal Gmail accounts; once reached, bulk-sender status is permanent | "Bulk senders" (the page does not give a numeric definition) |
| One-click headers | Required for marketing and subscribed messages, via RFC 8058 | List-Unsubscribe header required; RFC 8058 POST is highly recommended |
mailto: only | Does not meet the requirement | Acceptable |
| Visible link in body | Required | Required (may lead to a preference page) |
| Honour requests within | 48 hours | 2 days |
| Spam rate | Below 0.10%, never reach 0.30% | Below 0.3% (calculated on mail delivered to the inbox) |
Transactional messages such as password resets and order confirmations are excluded from the one-click requirement at Gmail, although recipients, not senders, decide where the line between promotional and transactional falls. Always re-check the providers' current documentation because details change.
Step 1: Build the headers
- Create a unique, unguessable HTTPS URL per recipient, for example
https://example.com/unsubscribe/<token>, where the token identifies the subscriber and the list. RFC 8058 says the URI must contain enough information to identify the recipient and list so unsubscribing can complete automatically, and should include an opaque or hard-to-forge component. - Optionally add a
mailto:address as a fallback for clients that do not support one-click. Keep in mind that for Gmail the HTTPS one-click pair is what counts. - Add
List-Unsubscribe-Post: List-Unsubscribe=One-Click. It only works when theList-Unsubscribeheader contains an HTTPS URL.
RFC 8058 requires an HTTPS URI for one-click. An http:// link is treated as a plain, non-one-click link and may be ignored by Gmail.
Step 2: Build an endpoint that handles the POST
When a user clicks "Unsubscribe", the mailbox provider sends your URL a request like this. RFC 8058 says the body is the key/value pair, that multipart/form-data is the recommended content type and application/x-www-form-urlencoded is also allowed, and that the request goes to the same URL used for manual unsubscription:
POST /unsubscribe/6f1c9a7e3b HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
List-Unsubscribe=One-Click
Your endpoint must:
- Accept POST and return a
2xxstatus quickly. The RFC does not prescribe a status code, but anything other than success will be treated as a failure by providers. - Unsubscribe immediately, with no login, no CAPTCHA, no confirmation page. The request carries no cookies or authorization headers by design.
- Never answer with a redirect: RFC 8058 states the sender must not return an HTTPS redirect for the POST.
- Be idempotent: calling it twice must not error.
- Never unsubscribe on GET. Anti-spam software and link scanners fetch URLs from message headers automatically; if GET unsubscribes, real subscribers vanish. Show a confirmation page on GET instead.
A minimal handler in three common stacks:
// Node.js (Express)
app.post('/unsubscribe/:token', express.urlencoded({ extended: false }), async (req, res) => {
if (req.body['List-Unsubscribe'] !== 'One-Click') return res.sendStatus(400);
await db.suppress({ token: req.params.token }); // idempotent
res.sendStatus(200);
});
app.get('/unsubscribe/:token', (req, res) => res.send(renderConfirmPage(req.params.token))); // no state change
# Python (Flask)
@app.post('/unsubscribe/<token>')
def unsubscribe(token):
if request.form.get('List-Unsubscribe') != 'One-Click':
return '', 400
suppress(token) # idempotent
return '', 200
// PHP
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['List-Unsubscribe'] ?? '') === 'One-Click') {
suppress($token); // idempotent
http_response_code(200);
}
Step 3: Sign both headers with DKIM
RFC 8058 requires the message to carry at least one valid DKIM signature that covers the List-Unsubscribe and List-Unsubscribe-Post headers, and receivers should not offer one-click for a message where the signature is missing. In the DKIM-Signature header the h= tag lists the signed headers, so confirm it includes both. Most email platforms do this when you enable the feature; if you send through your own MTA, add them to the signed header list.
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=mail;
h=from:to:subject:date:message-id:list-unsubscribe:list-unsubscribe-post; ...
Step 4: Test it before the campaign
- Send a test message to a Gmail and a Yahoo mailbox from the same system that sends your campaigns.
- Look for the Unsubscribe link next to the sender name (Gmail) or in the message header area (Yahoo). It can take a few sends from a new sender before providers show it.
- Open the original message and paste the headers into a header analyzer to confirm both headers are present and DKIM passes.
- POST to your own endpoint with
curland check for a 2xx response and an actual suppression record:
curl -i -X POST -d 'List-Unsubscribe=One-Click' https://example.com/unsubscribe/6f1c9a7e3b
# Expected: HTTP/2 200, and the address now appears in your suppression list.
curl -i https://example.com/unsubscribe/6f1c9a7e3b
# Expected: a confirmation PAGE (200) — and the address is still subscribed.
Designing the suppression behind the endpoint
The endpoint is only the front door. What it writes decides whether the unsubscribe is respected everywhere:
- Scope. Decide whether a click unsubscribes the person from one list, from one category of mail, or from all marketing. Gmail's requirement is that the action the user took in the provider's interface is honoured, so a "list-only" unsubscribe that leaves the person on other promotional streams will keep producing complaints.
- Write before you send. Check the suppression store at send time, not only when a campaign is built. A campaign queued yesterday must not reach someone who unsubscribed this morning, and the 48-hour window in Gmail's FAQ is short.
- Keep the record, not just the flag. Store the address (or a hash), the list, the time and the source (
one-click, manual page,mailtoreply). You need the evidence if a regulator or a provider asks. - Treat the token as a capability. It should identify one recipient and one list, be hard to guess, and ideally not expire, because people use old emails. RFC 8058 notes the server should verify that the opaque part is valid.
- Offer a preference page on GET. One-click removes the person immediately; the human page you show on GET can let them resubscribe or choose a lighter cadence, which recovers some of the audience that would otherwise be lost.
Common mistakes that break one-click
| Mistake | Result | Fix |
|---|---|---|
http:// instead of https:// | One-click ignored | Serve the endpoint over HTTPS |
| Endpoint redirects or needs login | Request treated as failed | Return 200 directly, no auth, no redirect |
| Unsubscribing on GET | Link scanners unsubscribe real users | Only change state on POST |
| Same URL for every recipient | One click removes everyone, or cannot identify the user | Use a unique token per recipient and list |
Headers not in the DKIM h= list | Header may be ignored as unsigned | Add both headers to the signed set |
Only mailto: in the header (Gmail) | Does not meet the one-click requirement | Add the HTTPS URI and the Post header |
| Unsubscribes processed after days | Complaints and policy violations | Suppress in real time, within 48 hours at the latest |
What happens next: keep your lists clean
One-click unsubscribe works hand in hand with list hygiene: people who can leave easily are far less likely to click "Report spam", and complaint rate is the number providers watch most closely. Pair this setup with regular list cleaning, and review your complaint and unsubscribe rates after every send. For the complete set of provider rules see the Gmail and Yahoo bulk sender requirements checklist, and to read the headers of a received test message see how to read email headers.
Frequently asked questions
Do I need both a mailto and an HTTPS List-Unsubscribe link?
Only the HTTPS URL is required for one-click. Adding mailto: is optional and works as a fallback for clients that do not support RFC 8058. Gmail states that a mailto or plain link alone does not meet its requirement.
Why is the Unsubscribe button not showing in Gmail?
Common causes are a missing or unsigned List-Unsubscribe-Post header, an http:// URL, failing SPF, DKIM or DMARC, a very low sending volume or a new sender reputation. Check the headers and authentication results first.
Does one-click unsubscribe replace the unsubscribe link in the email body?
No. Gmail and Yahoo expect both: the header-based one-click option and a clearly visible unsubscribe link in the message.
How long do I have to honour an unsubscribe?
Gmail's FAQ says requests should be honoured within 48 hours, and Yahoo's requirements say within 2 days. Doing it immediately is the safe approach.
Does List-Unsubscribe apply to transactional email?
It is required for promotional and subscribed messages. Gmail excludes purely transactional messages such as password resets, but adding it to subscription-like messages is harmless.


