List-Unsubscribe and one-click unsubscribe: the 2024 requirement
Gmail and Yahoo now require RFC 8058 one-click unsubscribe for bulk senders. Here are both header formats, the POST endpoint contract, and the gotchas that break it.
List-UnsubscribeRFC 8058GmailYahoo
Since February 2024, Gmail and Yahoo require bulk senders to honor one-click unsubscribe under RFC 8058. The header is two lines, the endpoint is one POST, and yet a remarkable number of senders still get it wrong — usually by treating it like a mailto link with extra steps.
The two headers
Email headerstext
List-Unsubscribe: <mailto:[email protected]?subject=unsubscribe>, <https://example.com/u/abc123xyz>
List-Unsubscribe-Post: List-Unsubscribe=One-Click- First header lists two methods: a mailto fallback and an HTTPS endpoint.
- Second header signals RFC 8058 compliance — receivers will POST to the HTTPS URL automatically.
- The mailto address is a fallback for clients that don't support one-click.
The POST endpoint contract
When a Gmail or Yahoo user clicks the native 'Unsubscribe' link, the receiver's server (not the user's browser) sends a POST request to your URL. There is no human in the loop and no chance to show a confirmation page.
What receivers sendhttp
POST /u/abc123xyz HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 26
List-Unsubscribe=One-ClickImplementation checklist
- Generate a per-recipient HMAC token at send time. Never reuse tokens.
- Store the token mapped to the recipient address in your database.
- POST handler validates the token, suppresses the address, and returns 200 OK.
- Suppression must be effective within 2 days — same campaign already in flight should be aborted for that address.
- GET on the same URL should show a friendly confirmation page for users who paste the URL.
Token generation examplets
import { createHmac } from "node:crypto";
function unsubToken(recipient: string, secret: string): string {
return createHmac("sha256", secret)
.update(`unsub:${recipient}`)
.digest("base64url")
.slice(0, 32);
}
const url = `https://example.com/u/${unsubToken(to, process.env.UNSUB_SECRET!)}`;
// Add to headers:
// List-Unsubscribe: <mailto:[email protected]>, <${url}>
// List-Unsubscribe-Post: List-Unsubscribe=One-ClickFrequently asked questions
Keep reading