RFC 8058 defines one-click as an HTTP POST from the mailbox provider to the URL in the List-Unsubscribe header, with the body List-Unsubscribe=One-Click and a Content-Type: application/x-www-form-urlencoded. The endpoint must return a 2xx and unsubscribe the reader without any further interaction. Gmail and Yahoo built one-click into the February 2024 bulk-sender rules — 5,000-a-day senders whose endpoint 5xx’s, times out, or requires a session cookie are treated as if the header were missing, and the message drops into spam.
The static validator tells you the headers are well-formed. This tool tells you the endpoint actually accepts the POST and returns a compliant response. The two are the necessary-and-sufficient pair — the header can be perfect and the endpoint still broken; the endpoint can respond correctly to a browser GET and refuse the POST. Nobody currently offers this test publicly.
This tool fires a real POST. Only test endpoints on domains you control or campaigns you legitimately received. Requests are rate-limited to five per hour per target host, and private / loopback / link-local IPs are refused before any request goes out.
Static header check first → live POST test second. The static list-unsub validator tells you the headers are well-formed. This one tells you the endpoint actually works.
What the tool does
Paste the raw email headers (the list-unsub-validator parser extracts the https URL for you) or pass the URL directly. The tool then:
- Refuses non-HTTPS URLs. RFC 8058 mandates https; anything else is rejected before the request goes out.
- Refuses private-network hosts. The URL’s host is resolved and compared against RFC 1918, loopback, link-local, and unique-local ranges. Any match is refused (the check re-runs on every redirect hop, so a 302 to
http://192.168.1.1/is caught). - Fires the POST.
Content-Type: application/x-www-form-urlencoded, bodyList-Unsubscribe=One-Click, 10-second timeout, dedicated User-Agent (nanopost-list-unsub-live-tester/0.1). - Follows redirects — up to three hops, each one flagged in the trace. Gmail and Yahoo do follow redirects, but each hop adds latency and a failure mode; the tool exposes what happens so you can see it.
- Classifies the outcome. 2xx is PASS per RFC 8058 §5. 401/403 is FAIL with “endpoint requires auth”. 405 is FAIL with “endpoint won’t accept POST”. 429 is FAIL with “rate-limited”. Any 5xx or timeout is FAIL. Every verdict quotes the actual response code, response headers, and the first 500 chars of the body.
Why this needs a server-side hop
Browsers block the cross-origin POST that RFC 8058 requires. The endpoint owner would need to send a Access-Control-Allow-Origin header that permits the tool’s origin, plus allow the Content-Type: application/x-www-form-urlencoded — which is technically a “simple” content type, but combined with the non-standard List-Unsubscribe=One-Click body a lot of CORS setups reject it anyway. And since we deliberately don’t want to warm the endpoint’s CORS cache with a preflight from every reader on the web, the POST goes from a nanoPost server, not from the browser.
Rate-limiting is per target host, not per reader IP: we don’t want any one sender’s endpoint to be hammered, but we also don’t want to throttle a reader who happens to be testing the same mailing list twice.
Failure modes it will surface
- Endpoint returns 405 Method Not Allowed. Common where the ESP wired the header to a page that renders an unsubscribe form on GET but doesn’t route POST. Fix: register a POST handler on the same URL.
- Endpoint returns 401 or 403. Common where the endpoint expects a session cookie from the reader’s browser — a Marketo-style hosted unsubscribe page, for instance. Fix: split into two URLs, one for the one-click POST (accepts unauthenticated), one for the browser flow.
- Endpoint redirects through more than three hops. Usually a chain from campaign → tracking → confirmation page. Fix: land the one-click POST on the terminal handler; save the redirect chain for the browser flow.
- Endpoint times out. The one-click POST must respond in seconds; slow endpoints get treated as if they’d 5xx’d.
- Endpoint 5xx’s. Straightforward. Either the endpoint is down or the POST body is triggering an unhandled exception in the handler.
- Endpoint returns 2xx but the reader isn’t unsubscribed. The tool can’t verify that side-effect from a single POST — it only verifies the response contract. To confirm the unsubscribe happened, cross-check the sender’s suppression list after firing.
When you’re ready to check further
- The static list-unsub validator is the header-level pair to this tool. Run it first — a message that fails the header check will never satisfy the bulk-sender floor regardless of how the endpoint responds.
- The header auth visualizer reads the same header block into a visual SPF / DKIM / DMARC / ARC chain — useful for tracing a
dmarc=failthat would tank the sender’s bulk-sender score even with a working unsubscribe endpoint. - The DNS auth checker reads the live SPF, DKIM, DMARC, MTA-STS, and TLS-RPT records for a domain and scores them against Gmail, Yahoo, and Microsoft 365 bulk-sender rules.
