Short answer
List-Unsubscribe is an email header that gives mail apps a way to unsubscribe someone without opening the message: a mailto: address, an HTTPS URL, or both (RFC 2369). One-click unsubscribe adds a second header, List-Unsubscribe-Post: List-Unsubscribe=One-Click, which tells Gmail, Yahoo and other providers they can unsubscribe the reader with a single HTTPS POST to that URL (RFC 8058). The message also needs a DKIM signature that covers both headers.
Gmail and Yahoo require one-click unsubscribe on marketing and subscribed messages from bulk senders, and want unsubscribes honoured within two days. Pure transactional email such as password resets, sign-in codes and receipts doesn't need the headers, and is better without them. Digests, product updates and notifications people can switch off do need them.
What the two headers do
| Topic | List-Unsubscribe | List-Unsubscribe-Post |
|---|---|---|
| Spec | RFC 2369 (1998) | RFC 8058 (2017) |
| Contains | One or more URLs in angle brackets: mailto:, https: or both | Exactly List-Unsubscribe=One-Click |
| What the mail app does | Sends an email to the mailto: address, or opens the URL | Sends an HTTPS POST to the URL in List-Unsubscribe; the reader never leaves their inbox |
| Needs | Nothing else | An HTTPS URL in List-Unsubscribe and a DKIM signature covering both headers |
| Meets Gmail's one-click rule | No, not on its own | Yes, together with List-Unsubscribe |
The headers are what put an Unsubscribe link next to the sender's name in Gmail and other mail apps. Google shows it only for messages that pass its own eligibility checks, so adding the headers doesn't guarantee the button appears. A visible link in the email body is still expected as well: it can go to a preferences page rather than unsubscribing straight away.
Raw header examples
RFC 2369: mailto and a web page
List-Unsubscribe: <mailto:unsubscribe@example.com?subject=unsubscribe>
List-Unsubscribe: <mailto:unsubscribe@example.com>, <https://example.com/unsubscribe/opaque-token>Each URL sits in angle brackets. With several, separate them with commas; the mail app uses the leftmost one it supports. A message carries one List-Unsubscribe header, so the two lines above are alternatives, not a pair.
RFC 8058: one-click unsubscribe
List-Unsubscribe: <https://example.com/unsubscribe/opaque-token>, <mailto:unsubscribe@example.com?subject=unsubscribe>
List-Unsubscribe-Post: List-Unsubscribe=One-ClickWhen the reader clicks Unsubscribe, their mail provider sends this request to your URL. There are no cookies and no login: everything you need to identify the reader and the list has to be in the URL.
POST /unsubscribe/opaque-token HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 26
List-Unsubscribe=One-ClickRFC 8058 also requires a valid DKIM signature whose h= tag lists both headers, so the receiver knows they came from the signing domain and weren't added on the way:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=selector1;
h=from:to:subject:date:message-id:list-unsubscribe:list-unsubscribe-post;
bh=...; b=...RFC 8058 rules for the endpoint
- One HTTPS URL in
List-Unsubscribe. Amailto:can sit next to it, but Google says amailto:on its own doesn't meet its one-click requirement. List-Unsubscribe-Postholds exactlyList-Unsubscribe=One-Click.- The URL identifies the reader and the list. The POST carries no other information. RFC 8058 says to use an opaque or hard-to-forge token rather than a plain email address, and to check it, so nobody can unsubscribe your readers by guessing URLs.
- Unsubscribe on the POST and answer 200. Don't redirect (the RFC forbids it, because redirected POSTs often become GETs), and don't ask for a login or a confirmation step.
- Don't unsubscribe on a GET. The same URL may be opened in a browser, and link-scanning security tools fetch URLs in email. Show a confirmation page on GET and act on the POST.
- Accept both encodings. Providers send the body as
application/x-www-form-urlencodedormultipart/form-data. - Sign with DKIM after the headers are added, with both headers in
h=.
Gmail and Yahoo's one-click requirements
| Topic | Gmail | Yahoo |
|---|---|---|
| Who it applies to | Senders of more than 5,000 messages a day to Gmail accounts | Bulk senders (Yahoo doesn't publish a number) |
| Which messages | Marketing and subscribed messages | Marketing and subscribed messages |
| Method | RFC 8058 one-click headers with an HTTPS URL; mailto: alone doesn't count | RFC 8058 POST highly recommended; mailto: acceptable |
| Visible link in the body | Required | Required; may go to a preferences page |
| Honour unsubscribes within | 48 hours (recommended in Google's FAQ) | 2 days |
From Google's sender guidelines, Google's sender FAQ and Yahoo's sender best practices.
Last checked on each vendor's public page.
Google says it doesn't automatically reject or spam-folder mail just for missing one-click unsubscribe, but senders who don't meet the requirements aren't eligible for its delivery mitigation, and readers who can't unsubscribe easily are more likely to press Report spam. Microsoft's rules for Outlook.com recommend a working unsubscribe link. The full set of authentication and volume rules is in Google, Yahoo and Microsoft sender requirements.
The law sets its own floor. In the US, the FTC's CAN-SPAM guide says commercial email needs an opt-out that keeps working for at least 30 days after sending and is honoured within 10 business days, and that transactional or relationship messages are exempt from most of the Act. Other countries have their own rules.
Does transactional email need List-Unsubscribe?
No. Google's FAQ says one-click unsubscribe is required only for marketing and promotional messages, and gives password resets, reservation confirmations and form submission confirmations as examples of transactional mail that's excluded. The same FAQ adds that "message recipients, not Google, determine the nature of the messages they receive", so what counts is how your readers see a message, not what you call it.
| Unsubscribe headers? | Why | |
|---|---|---|
| Password reset, sign-in code, magic link | No | The reader just asked for it |
| Receipt, invoice, order or shipping update | No | Part of a transaction they made |
| Security alert, new sign-in, changed email address | No | They must get it even if they've opted out of everything else |
| Activity notifications they can switch off ("someone commented") | Yes | Readers see them as subscribed mail |
| Weekly digest or usage report | Yes | Subscribed mail |
| Onboarding tips, feature announcements, upgrade nudges | Yes | Marketing or subscribed mail |
| Newsletter | Yes | Marketing |
Adding the headers to a password reset isn't harmless. A reader who clicks Unsubscribe on it usually lands on your suppression list, and then their next password reset doesn't arrive. Keep unsubscribe for mail people can do without, and send account and security mail without it. Don't mix the two in one message either: Google's guidelines say not to put promotions in receipts. Send them as separate emails.
How Groundmail sets the headers
Groundmail adds the one-click headers for you, based on each email's category, and runs the unsubscribe endpoint. Each category also goes out on its own servers and IPs, so a product announcement never shares IPs with your sign-in codes.
| Category | Unsubscribe headers | What one-click does |
|---|---|---|
transactional (the default) | Off. Turn on per send with unsubscribe: true | Adds the address to your suppression list |
product | On automatically | Opts the reader out of product email only; transactional email still arrives |
newsletter (approved accounts) | Always on; can't be turned off | Opts the reader out of newsletter email only |
From the emails API docs and suppressions docs.
When managed unsubscribe is on, Groundmail adds both headers with a signed HTTPS link bound to the first to address, and replaces {{unsubscribe_url}} in your subject, HTML and text with a link to a confirmation page. The one-click URL only unsubscribes on a POST; opening it in a browser shows the confirmation page, so link scanners can't unsubscribe anyone by accident.
List-Unsubscribe: <https://app.groundmail.dev/api/unsubscribe?token=...>
List-Unsubscribe-Post: List-Unsubscribe=One-Clickimport { Groundmail } from 'groundmail'
const groundmail = new Groundmail(process.env.GROUNDMAIL_API_KEY!)
await groundmail.emails.send({
from: 'Acme <digest@mail.acme.com>',
to: 'jane@example.com',
subject: 'Your week in Acme',
html: '<p>...</p><p><a href="{{unsubscribe_url}}">Unsubscribe from the weekly digest</a></p>',
category: 'product', // adds List-Unsubscribe and List-Unsubscribe-Post
})- Afterwards: a send in that category to someone who opted out returns
422withdetails.category_unsubscribed, and acontact.unsubscribedwebhook tells your app, withdata.scopeofcategoryorall. - Templates: set
unsubscribe_enabledon a template, and product templates turn it on for you. - Your own endpoint: send with
unsubscribe: falseand pass your ownList-UnsubscribeandList-Unsubscribe-Postinheaders, or set them as headers over the SMTP relay. Newsletter email always uses Groundmail's. - Re-subscribes: list and remove opt-outs with
GETandDELETE /suppressions?type=category_opt_out, only when the reader asked to hear from you again. - Platforms: with tenants, an unsubscribe from one customer's email applies to that customer only. See sending email on behalf of your customers.
How to check your headers
- 01Look at a received messageIn Gmail, open the message, then the three dots and Show original. Check that
List-Unsubscribeholds anhttps:URL andList-Unsubscribe-PostreadsList-Unsubscribe=One-Click. - 02Check the DKIM signature covers themIn the same view, find the
DKIM-Signaturefor your domain and check itsh=tag listslist-unsubscribeandlist-unsubscribe-post, and thatAuthentication-Resultsshowsdkim=pass. The header analyzer reads the results for you. - 03Run a deliverability testThe free email deliverability test checks for one-click unsubscribe on bulk mail, along with SPF, DKIM, DMARC and content.
- 04Call your endpoint the way a provider would
curl -i -X POST -d 'List-Unsubscribe=One-Click' 'https://example.com/unsubscribe/opaque-token'should return200with no redirect, and the reader should be gone from the list.
Common mistakes
| Mistake | What happens | Fix |
|---|---|---|
Only a mailto: URL | Doesn't meet Gmail's one-click requirement | Add an HTTPS URL and List-Unsubscribe-Post |
List-Unsubscribe-Post without an HTTPS URL | Providers can't do the POST, so no one-click | Put the HTTPS URL first in List-Unsubscribe |
| Headers not covered by DKIM | Providers may not offer one-click | Add the headers before signing; check h= |
| The endpoint redirects or asks for a login | The POST fails and the reader stays subscribed | Unsubscribe on the POST and return 200 |
| Unsubscribing on GET | Security scanners that open links unsubscribe your readers | Confirm on GET, unsubscribe on POST |
| The reader's email address in plain text in the URL | Anyone can unsubscribe anyone | Use a signed or random token |
| Headers on password resets and receipts | One click and the reader stops getting account email | Only add them to mail people can do without |
| One unsubscribe for everything | Leaving a digest also stops receipts | Unsubscribe from that kind of mail only |
| Unsubscribes processed in a weekly batch | More mail after they asked to stop, and spam reports | Honour them within 2 days, ideally at once |
Frequently asked questions
What is the List-Unsubscribe header?
An email header, defined in RFC 2369, that lists a mailto: address or URL for unsubscribing from the mail. Mail apps use it to show an Unsubscribe link near the sender's name, so readers can leave without opening the message or hunting for a footer link.
What is one-click unsubscribe?
RFC 8058's extension to List-Unsubscribe. With List-Unsubscribe-Post: List-Unsubscribe=One-Click and an HTTPS URL in List-Unsubscribe, the mail provider unsubscribes the reader with one HTTPS POST, with no web page, login or confirmation. The message needs a DKIM signature covering both headers.
Is a mailto List-Unsubscribe enough for Gmail?
No. Google's FAQ says mailto links don't meet its one-click requirement: you need List-Unsubscribe-Post and an HTTPS URL in List-Unsubscribe. Yahoo accepts mailto but highly recommends the RFC 8058 POST method. Sources: Google, Yahoo.
Do transactional emails need a List-Unsubscribe header?
No. Gmail and Yahoo require one-click unsubscribe only for marketing and subscribed messages. Password resets, sign-in codes, receipts and security alerts don't need it, and adding it risks readers suppressing the account email they need.
Why doesn't Gmail show an Unsubscribe link for my emails?
Gmail shows the link next to the sender's name only for messages that pass its own eligibility checks: correct one-click headers covered by DKIM, the sender requirements, and a sending history without high spam reports. The headers alone don't guarantee it.
How fast do I need to process unsubscribes?
Yahoo says within 2 days, and Google recommends 48 hours. In the US, CAN-SPAM allows up to 10 business days for commercial email. Processing them immediately is simplest.
Does Groundmail add List-Unsubscribe automatically?
For product and newsletter email, yes, with one-click and a hosted unsubscribe endpoint. Transactional email, the default, goes out without it unless you send with unsubscribe: true. See the emails API docs.
Sources
Facts on this page about other companies' products, prices and policies come from these public pages. They change, so check them before you decide.