Suped

How should one-click unsubscribe links handle GET vs POST requests?

Published 18 May 2025
Updated 7 Oct 2026
11 min read
Summarize with
RFC 8058 one-click unsubscribe endpoint handling GET inspection and POST opt-out requests.
Updated on 7 Oct 2026: We clarified RFC 8058 requirements and expanded the endpoint tests for safe GET and POST handling.
A one-click unsubscribe URL should treat GET as safe inspection and POST as the unsubscribe action. If a browser visit, link scanner, preview system, or security gateway sends GET, the endpoint should show a confirmation page, redirect to a preference center, or return a harmless status. It should not suppress the address.
The actual one-click action belongs behind POST, using the URL in the List-Unsubscribe header plus the List-Unsubscribe-Post header. When a mailbox provider supports that flow, it obtains user consent in its interface, then submits the unsubscribe request to the sender with POST. That split keeps automated link checking from turning into accidental list removal.
The important caveat: the header does not tell Microsoft, Google, corporate gateways, or security scanners to avoid the URL. It tells supporting clients how to perform a confirmed unsubscribe. Scanners still fetch links. Your endpoint has to make those fetches safe.

HTTP methods and unsubscribe actions

Use this production rule: GET displays information, POST changes subscription state after validation. That applies even when the URL exists only in the List-Unsubscribe header and not in the visible email body.
  1. GET: Return a page, redirect, no-op response, or method explanation. Do not unsubscribe.
  2. POST: Validate the signed token and the one-click form value, unsubscribe the address for the right list or topic, and return success.
  3. HEAD: Treat it like inspection. Return headers only and make no subscription change.
  4. Other methods: Return 405 Method Not Allowed with an Allow header listing GET, HEAD, and POST. Do not change subscription state.
Fast diagnosis
If pasting the List-Unsubscribe URL into a browser immediately opts out the recipient, the endpoint has a bug. A browser visit is a GET request. It should not be enough to change consent.
That rule also answers the common Microsoft concern. If you see unsubscribe events coming from Microsoft-owned or Microsoft-hosted IP space, look at the method first. If those requests are GET, the scanner exposed a server-side flaw. If they are valid POST requests with the one-click body, correlate them with the native unsubscribe flow and consent records before assigning a cause.

How the headers should look

The header pair is simple. Include exactly one of each header field. List-Unsubscribe must contain one HTTPS URI and can also carry a mailto fallback. List-Unsubscribe-Post must contain only the value List-Unsubscribe=One-Click, which tells supporting clients that the HTTPS URI accepts an RFC 8058 one-click POST.
Example headerstext
List-Unsubscribe: <https://u.example.com/o/abc123>, <mailto:unsubscribe@example.com?subject=unsubscribe> List-Unsubscribe-Post: List-Unsubscribe=One-Click
A one-click POST arrives as a form-style request to the HTTPS URI. The URI must identify the recipient and the list or topic because RFC 8058 provides no extra recipient fields in the POST body. Use a signed opaque URL token as the authorization control; mailbox providers do not share a browser session with your site.
Expected POST shapehttp
POST /o/abc123 HTTP/1.1 Host: u.example.com Content-Type: application/x-www-form-urlencoded List-Unsubscribe=One-Click
The sender still needs a visible unsubscribe option in the message body for promotional mail. That footer link can open a preference page, but it does not replace the RFC 8058 header flow.

RFC 8058 requirements beyond the method

The GET-versus-POST split is central, but full RFC 8058 compliance also depends on message signing and exact endpoint behavior.
  1. HTTPS URI: Include one HTTPS URI in List-Unsubscribe. A mailto URI can be an additional fallback.
  2. DKIM coverage: At least one valid DKIM signature must cover both List-Unsubscribe and List-Unsubscribe-Post in the same signature's h= tag.
  3. Request context: Do not depend on cookies, HTTP authorization, or data from an earlier browser session.
  4. Body encoding: Accept multipart/form-data and application/x-www-form-urlencoded with the one-click value.
  5. Redirects: Return success directly. RFC 8058 says the sender must not return an HTTPS redirect for the POST.
  6. Receiver consent: A receiver must not send the POST without user consent, although the RFC leaves the consent interface to the receiver.
Add both headers before DKIM signing and check the delivered message, since changes after signing can invalidate the signature. A DKIM pass alone does not prove that the signature covers the unsubscribe headers.
Correct headers do not force a mailbox provider to display a native unsubscribe control. Provider eligibility checks can still consider sender reputation and message classification. Current Google guidance and Yahoo guidance target marketing or subscription mail; transactional messages such as receipts and password resets are excluded.
Google guidance requires RFC 8058 one-click unsubscribe for bulk senders' marketing and subscription messages; mailto alone does not qualify. Yahoo guidance also accepts a functioning mailto unsubscribe header, although it highly recommends the RFC 8058 POST method. Supporting the HTTPS POST flow covers both providers.

GET versus POST behavior

The easiest way to avoid mistakes is to design the endpoint as two separate behaviors that happen to share a URL. The token parsing can be shared, but the state-changing branch should only execute for POST.
GET path
  1. Purpose: Let humans and scanners inspect the URL safely.
  2. Response: Show a confirmation page, preference center, or harmless status.
  3. State: Do not change subscriber status, list membership, or consent records.
POST path
  1. Purpose: Process a confirmed one-click unsubscribe.
  2. Response: Return 200 or 204 directly after validating the token and form value and recording the suppression.
  3. State: Suppress only the intended address, list, brand, or topic.

Method

Action

Status

GET
Show page or no-op
200
HEAD
No state change
200
POST
Validate token and body, then suppress
204
PUT
Reject; include Allow header
405
Recommended endpoint behavior by HTTP method.
Do not try to fix scanner behavior with IP allowlists, user-agent checks, or assumptions about which mailbox provider owns a request. Those signals change. The HTTP method and a valid signed token are more dependable controls.
These success codes are implementation choices, not status codes mandated by RFC 8058. A missing or invalid token, an incorrect form value, or an unsupported content type must leave the subscription unchanged and return an appropriate error response.

Why scanners still hit unsubscribe URLs

Mail systems inspect URLs for safety, reputation, policy, and rendering. They can fetch links in message bodies and headers before a person clicks anything. Some fetches come from mailbox providers, some come from corporate security gateways, and some come from client preview systems.
The List-Unsubscribe-Post header does not block those checks. It only advertises that a one-click POST endpoint exists. That is why the server must be safe by default. A safe endpoint treats every unsolicited GET as inspection.
RFC 8058 unsubscribe flow where GET is a no-op and POST records the suppression.
RFC 8058 unsubscribe flow where GET is a no-op and POST records the suppression.
This is also why a sudden wave of unsubscribes can appear after a mailbox provider changes scanning behavior. The bug can sit unnoticed for months, then a new scanner path starts visiting header URLs. The scanner did not create the unsafe behavior; it revealed it.
For broader inbox compliance, pair endpoint logs with authentication monitoring. Suped's product lets teams use DMARC monitoring and DMARC failure alerts while developers validate the unsubscribe endpoint in HTTP logs.

Implementing the unsubscribe endpoint

Use an unguessable, signed opaque token in the URL. Bind it to the subscriber, list or topic, sending domain, and token version. Keep the token usable for old messages, or provide a safe version-rotation path that still records the opt-out.
Endpoint logic (pseudocode)python
if request.method not in ('GET', 'HEAD', 'POST'): return response(405, headers={'Allow': 'GET, HEAD, POST'}) token = verify_signed_token(request.path) if token is None: return response(403) if request.method == 'GET': log_inspection(token.id) return confirmation_page(token) if request.method == 'HEAD': log_inspection(token.id) return response(200) # No response body if request.mimetype not in ( 'application/x-www-form-urlencoded', 'multipart/form-data' ): return response(415) if request.form.getlist('List-Unsubscribe') != ['One-Click']: return response(400) try: # Durable and idempotent: repeated requests keep the suppression. record_suppression(token.subscriber_id, token.topic_id) except SuppressionStoreUnavailable: return response(503) log_unsubscribe(token.id) return response(204)
Avoid session-only CSRF requirements on the one-click POST route because the mailbox provider is not posting from the subscriber's logged-in browser. A normal website CSRF token breaks this flow. The URL token carries the authorization, and the POST body identifies the one-click action. A valid request does not prove who sent it: anyone with access to the message, including a forwarded copy, can use its token to unsubscribe the original recipient.
  1. Token scope: Include subscriber ID, list or topic ID, sending domain, and a token version.
  2. Token safety: Use a signature or authenticated encryption to prevent tampering. Encoding alone is insufficient. Do not expose raw email addresses or predictable IDs.
  3. Idempotency: Repeated POSTs should still return success and keep the address unsubscribed.
  4. Audit log: Store method, timestamp, IP, user agent, a nonsecret token ID, and result. Redact the full token in access logs and tracing data.
  5. Preference scope: Remove the right mail stream, not every message type unless the user asked for that.
Practical response handling
Return a fast success response only after durably recording a valid unsubscribe. Do not return a redirect, login page, CAPTCHA step, or preference-center detour. Record the suppression before starting any asynchronous downstream work. If storage fails, return an error rather than success. Check the suppression list again before sending queued campaigns.
Google guidance recommends honoring unsubscribe requests within 48 hours and lists missed processing deadlines as a reason bulk senders lose delivery support or mitigations. Yahoo guidance requires processing within two days. These timelines come from provider guidance, not RFC 8058. Immediate suppression prevents another scheduled campaign from reaching the recipient.
For the visible footer link, use a human page on GET. That page can include a button that submits POST with the same one-click form value if it uses this endpoint. This protects against body-link scanners while preserving a clear unsubscribe path for people whose client does not support the native header UI.

Testing before rollout

Test the message headers, the endpoint method handling, and the final consent record. A header can look correct while the endpoint still unsubscribes on GET, so do not stop at header validation.
Suped's email tester checks the delivered message's unsubscribe headers alongside authentication and deliverability signals. Verify DKIM header coverage and endpoint behavior separately in the raw message and HTTP logs. For a wider domain check, use the domain health checker alongside your HTTP access logs.

Email tester

Send a real email to this address. Suped shows a results button when the test is ready.

?/43tests passed
Run direct endpoint tests with curl or an equivalent HTTP client. The exact client matters less than proving that GET does not change the database and POST changes only the intended record.
Manual endpoint testsbash
# Use a controlled test subscriber and a real token. curl -i https://u.example.com/o/abc123 curl -I https://u.example.com/o/abc123 curl -i -X POST https://u.example.com/o/abc123 \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data 'List-Unsubscribe=One-Click' curl -i -X POST https://u.example.com/o/abc123 \ --form 'List-Unsubscribe=One-Click'
GET and HEAD should leave the subscriber active. Both POST variants should record suppression for the intended list, and repeated valid requests should succeed without changing that scope. Do not add curl's redirect-following option when testing: inspect the first response to catch an unexpected redirect. A complete one-click test plan also covers mailbox-client rendering, footer links, mailto handling, and unsubscribe processing time.
Check failure cases as well as the successful request. These are recommended endpoint checks, not additional RFC 8058 requirements.
  1. Send a missing or altered token and confirm that the endpoint rejects it without changing subscription state.
  2. Send an empty body, a wrong one-click value, and an unsupported content type. Confirm that none creates a suppression.
  3. Send a valid POST without cookies or HTTP authorization. Confirm that it succeeds without login or a CSRF challenge.
  4. Repeat a valid POST after the address is already unsubscribed. Confirm direct success and no duplicate side effects.
  5. Simulate unavailable suppression storage. Confirm an error response, then verify that a later valid request can still succeed.
  6. Check a queued campaign and a different list after the opt-out. Confirm that the intended stream stops and other subscription choices remain intact.

Common one-click unsubscribe mistakes

Most one-click unsubscribe problems come from treating a URL as the action instead of treating the HTTP method as part of the action. The URL identifies the request. The method gates state changes; the signed token and form value validate the unsubscribe request.
  1. GET unsubscribe: A crawler, previewer, or mailbox scanner can remove real subscribers.
  2. Shared token: One token across multiple lists makes audit trails weak and consent scope unclear.
  3. Weak logging: Without method-level logs, every complaint becomes guesswork.
  4. Forced login: A one-click POST should not require a session, password, or CAPTCHA.
  5. Missing fallback: Keep a visible footer unsubscribe option for clients that ignore the header.
Do not rely on scanner detection
Blocking known scanner IPs creates a fragile system. A valid user can sit behind the same network path, and a new scanner can arrive tomorrow. Method-based handling fixes the root problem.
The one-click requirements sit next to authentication and complaint controls in current bulk-sender programs. Suped's product can centralize DMARC reporting and authentication alerts; keep unsubscribe evidence in your own HTTP and consent logs.

Frequently asked questions

DMARC monitoring

Start monitoring your DMARC reports today

Suped DMARC platform dashboard
What you'll get with Suped
Real-time DMARC report monitoring and analysis
Automated alerts for authentication failures
Clear recommendations to improve email deliverability
Protection against phishing and domain spoofing