The List-Unsubscribe header and one-click unsubscribe
What the List-Unsubscribe and List-Unsubscribe-Post headers do, what RFC 8058 and Gmail require for one-click unsubscribe, an example, and how Boundry adds them.
The List-Unsubscribe header tells a mailbox provider where a recipient can unsubscribe from your messages, so it can show an Unsubscribe button next to the sender instead of making the reader hunt for a link in the footer. One-click unsubscribe, defined in RFC 8058, adds a second header, List-Unsubscribe-Post, which lets the provider send the unsubscribe as a single HTTPS POST without opening a page.
Google's email sender guidelines say that marketing messages and subscribed messages must support one-click unsubscribe for senders of 5,000 or more messages a day to Gmail addresses. Even below that volume, the headers are the cleanest way to give readers an exit that does not end in a spam complaint.
What the two headers do
- List-Unsubscribe holds one or more URIs, in angle brackets, where an unsubscribe request can be sent. It can hold a mailto: address, an https: URL, or both.
- List-Unsubscribe-Post has the single value List-Unsubscribe=One-Click. Its presence tells the receiver that the https: URL accepts a POST and unsubscribes the recipient straight away.
List-Unsubscribe: <https://mail.acme.com/u/OPAQUE-TOKEN>
List-Unsubscribe-Post: List-Unsubscribe=One-ClickWhen the reader presses the provider's Unsubscribe button, the provider sends an HTTPS POST to that URL with the body List-Unsubscribe=One-Click. Your server unsubscribes the address and answers with a success status. The reader never sees your site.
The rules in RFC 8058
- The message has exactly one List-Unsubscribe header and one List-Unsubscribe-Post header, and List-Unsubscribe contains at least one HTTPS URI. A mailto: address may be added beside it.
- The List-Unsubscribe-Post value is exactly List-Unsubscribe=One-Click.
- Both headers must be covered by a valid DKIM signature. Without one, a receiver should not offer one-click unsubscribe for the message.
- The URL must identify the recipient and the list, because the POST carries nothing else, and it should contain an opaque or hard-to-guess token that your server checks. Never put a plain email address in it.
- The endpoint must not redirect. It answers the POST directly.
- The POST arrives without cookies or authorization, so the endpoint cannot depend on a logged-in session.
- The receiver must not POST without the user's consent. A GET to the same URL, which scanners and previewers may make, should never unsubscribe anyone.
Do transactional emails need it?
A password reset, a receipt or a sign-in link is something the recipient asked for, and an unsubscribe button on it makes no sense. Those messages normally go without the headers. Anything the person can opt out of does need them: product news, digests, announcements and any other marketing or subscribed message, including the ones you send from the same account as your transactional mail.
Keep the two kinds apart. Send marketing from its own subdomain, such as news.acme.com, and transactional mail from another. Separate sending subdomains reduce the risk of marketing complaints affecting transactional delivery, but they do not guarantee reputation isolation.
The spam guide explains how sender reputation and complaints decide where a message lands. Why your emails go to spam
How to build it yourself
- Create a per-recipient, per-list token and store it with the address. Make it hard to guess.
- Put it in an HTTPS URL on a domain you control, and add both headers to every message that needs them.
- Make sure your sending path signs List-Unsubscribe and List-Unsubscribe-Post with DKIM. Check the h= tag of the DKIM-Signature header in a delivered message.
- Have the endpoint accept POST, mark the address as unsubscribed at once, and return 200 without a redirect.
- Do not unsubscribe on GET. Show a confirmation page there instead, for people who follow the link from the footer.
- Skip every unsubscribed address before you send. Honour the request quickly, since a reader who presses Unsubscribe and still gets mail will press Report spam next.
How to check that it works
- Send a message to a Gmail address and choose 'Show original' from the three-dot menu.
- Confirm both headers are present and that the DKIM-Signature header lists them in its h= tag.
- Look for the Unsubscribe link next to the sender name in the open message. Gmail decides whether to show it, so its absence is not proof of a fault, but the headers are the first thing to check.
- Post to the URL yourself with curl, using the body List-Unsubscribe=One-Click, and confirm the address is suppressed and no redirect is returned.
Common problems
- The button does not appear. The messages are not DKIM-signed for your domain, the headers are missing from the h= list, or the provider has not decided to show it yet.
- The unsubscribe works on a click but a scanner unsubscribes people before they read the email. The endpoint acts on GET. Act only on POST.
- The POST fails with a redirect. The URL goes through a link tracker or http-to-https redirect. Give the URL straight to your server.
- Readers unsubscribe, then still get mail. The suppression list is not checked at send time, or a second system is also sending to them.
- A transactional email is suppressed because someone unsubscribed from newsletters. If one suppression list covers every message to an address, an unsubscribe blocks transactional mail too, so keep marketing and transactional sending apart.
How Boundry handles it
Boundry can add the headers for you. Managed unsubscribe creates an opaque recipient URL, adds both RFC 8058 headers to the message, and suppresses the address when a mailbox provider posts the one-click request. You do not build the endpoint or keep the suppression list.
The headers do not replace the link in the message body. Google's sender guidelines also expect a clearly visible unsubscribe link in the body of marketing and subscribed messages, and Boundry's managed unsubscribe adds headers only. You provide and host that link yourself, as in the example below.
- Turn it on for a sending domain with managed_unsubscribe_default. Messages from that domain then inherit it whenever unsubscribe is omitted or null.
- Override one message with unsubscribe: true or unsubscribe: false in the send request.
- It needs exactly one recipient on the message. Broadcasts enable it automatically.
- Subscribe a webhook to email.unsubscribed to be told when someone unsubscribes, so your own records stay in step.
- Spam complaints arrive separately as email.complained, and Boundry suppresses those recipients automatically.
{
"from": "Acme <news@mail.acme.com>",
"to": "customer@example.com",
"subject": "Product news",
"html": "<p>What shipped this month.</p><p><a href="https://mail.acme.com/unsubscribe/YOUR-TOKEN">Unsubscribe</a></p>",
"unsubscribe": true
}A managed unsubscribe suppresses the address for the whole project, so every later send to it from that project is blocked, including receipts and password resets, and unsubscribe: false does not get around it. If you use managed unsubscribe, send marketing and transactional mail from separate projects to keep transactional delivery intact. The setting is available through the domains and emails APIs.
The send email guide covers managed unsubscribe, attachments and idempotency keys. Send email with Boundry
Complaints are one of the ways mailbox providers measure a sender. Bounces are the other half. Email bounces, explained
Replies to marketing email are worth reading too. See what to send from instead of a no-reply address. No-reply email addresses
Frequently asked questions
What is the List-Unsubscribe header?
It is an email header holding a URL or mailto: address where a recipient can unsubscribe. Mailbox providers use it to show an Unsubscribe button beside the sender.
What is one-click unsubscribe?
It is the method in RFC 8058. The message carries List-Unsubscribe-Post: List-Unsubscribe=One-Click beside an HTTPS List-Unsubscribe URL, and the mailbox provider unsubscribes the reader with a single POST to that URL.
Does Gmail require one-click unsubscribe?
Google's sender guidelines say marketing messages and subscribed messages must support one-click unsubscribe for senders of 5,000 or more messages a day to Gmail addresses.
Do password reset and receipt emails need it?
No. They are messages the person asked for, and they normally go without the headers. Use them on anything the recipient can opt out of, such as newsletters and product news.
Why must the headers be DKIM-signed?
RFC 8058 requires both headers to be covered by a valid DKIM signature, so a receiver can trust that the unsubscribe link came from the sender. Without it, a receiver should not offer one-click unsubscribe for that message.
Does Boundry add List-Unsubscribe headers?
Yes, as managed unsubscribe. Set unsubscribe: true on a message, or turn on managed_unsubscribe_default for the sending domain. Boundry adds both RFC 8058 headers and suppresses the address when the one-click request arrives. It needs exactly one recipient per message.