Two ways to unsubscribe
- The link in the email, usually in the footer, which opens a page on your site.
- The inbox’s own button, which uses the
List-Unsubscribeheader. WithList-Unsubscribe-Post: List-Unsubscribe=One-Clickand an https address, Gmail and Yahoo unsubscribe in one step by sending a POST, without opening your site (RFC 8058). Both headers must be covered by the email’s DKIM signature, or inboxes won’t offer the one-click button. Gmail requires one-click unsubscribe of senders of 5,000 or more emails a day (Gmail’s sender guidelines).
What Proxy Mail QA checks on every marketing email
| Check | Fails or warns when |
|---|---|
list_unsubscribe |
There’s no List-Unsubscribe header (it fails), or it has only an email address or a plain http one (it warns) |
one_click_unsubscribe |
No List-Unsubscribe-Post header with an https address, or the email’s DKIM signature doesn’t cover both List-Unsubscribe headers, so an inbox’s button can’t unsubscribe in one step (a warning) |
unsubscribe_link |
The email itself has no unsubscribe or email-preferences link |
after_unsubscribe |
It came after the address unsubscribed from its sender |
The inbox shows both kinds of unsubscribe link for each email, with Open link and Copy.
Test it
- Sign up and opt in with a new address, then trigger a marketing email such as a newsletter.
- Check the email: the checks above show in the inbox.
- Unsubscribe with the link, in your own browser.
- Choose Mark as unsubscribed on that email, with a grace period if marketing already queued may still come (an hour, a day). The inbox says it’s watching for marketing from that sender, with Stop watching.
- Trigger more email: another newsletter should never come, while a receipt or a password reset should.
Any marketing email after that shows a warning in the inbox and on the Accounts page, with Open email, and Reports lists it.
In a test
const link = await qa.waitForLink(address, { type: 'unsubscribe', since: signedUp });
await page.goto(link);
await page.getByRole('button', { name: 'Unsubscribe' }).click();
await qa.markUnsubscribed(address, { service: 'acme.com' });
// Trigger the next campaign, then: no marketing for 10 minutes, receipts allowed.
await qa.expectNoEmail(address, { since: new Date(), category: 'marketing', timeout: 600 });
type: 'list_unsubscribe' returns the header’s one-click address instead: POST List-Unsubscribe=One-Click to it, as an inbox’s button does. Later, in another test or after the next real campaign, checkUnsubscribe(address) lists any marketing that came after. Agents use wait_for_link with kind unsubscribe, mark_unsubscribed and check_unsubscribe, and the test_unsubscribe prompt walks through it.