One-click odhlášení podle RFC 8058: hlavičky List-Unsubscribe, endpoint a kdy je povinné
Jak fungují hlavičky List-Unsubscribe a List-Unsubscribe-Post, kdy je Gmail a Yahoo vyžadují, jak napsat endpoint, který přijme POST bez potvrzovací stránky, a proč se odhlášení vyplatí i u informačních e-mailů, které povinné nemají.
One-click odhlášení znamená, že příjemce klikne na tlačítko „Odhlásit" přímo v rozhraní Gmailu nebo Yahoo a je hotovo; žádná stránka, žádné přihlašování, žádné „opravdu?". Technicky jsou to dvě hlavičky e-mailu a jeden HTTP endpoint, který přijme POST. Od roku 2024 jde u hromadných odesílatelů o povinnost, u ostatních o jednu z nejlevnějších investic do doručitelnosti. Tady je, jak to celé funguje a jak to napsat.
Dvě hlavičky
List-Unsubscribe je starší hlavička z RFC 2369. Obsahuje jednu nebo více adres v lomených závorkách, kam se dá odhlásit: HTTPS odkaz, mailto:, nebo obojí.
List-Unsubscribe-Post přidal RFC 8058 a má vždy přesně jednu hodnotu. Říká poštovnímu klientovi: „na HTTPS adresu z předchozí hlavičky můžeš poslat POST a tím odhlášení provést bez účasti uživatele".
List-Unsubscribe: <https://firma.cz/odhlasit?t=7f3a…>, <mailto:odhlasit@firma.cz?subject=unsub-7f3a>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
Když Gmail obě hlavičky najde (a odesílatel má slušnou reputaci), zobrazí u zprávy tlačítko „Odhlásit". Po kliknutí pošle na HTTPS adresu:
POST /odhlasit?t=7f3a… HTTP/1.1
Host: firma.cz
Content-Type: application/x-www-form-urlencoded
List-Unsubscribe=One-Click
RFC 8058 navíc vyžaduje, aby byla zpráva podepsaná DKIM a podpis pokrýval obě hlavičky; poštovní klient pak ví, že hlavičky nepřidal někdo po cestě. Pokud posíláte přes relay s ověřenou doménou, DKIM podpis hlavičky zahrnuje automaticky.
Kdy je to povinné
Google a Yahoo od února 2024 vyžadují one-click odhlášení u hromadných odesílatelů (Google: 5 000 a více e-mailů denně na Gmail) pro marketingové a odběrové e-maily. Odhlášení musí být zpracováno do dvou dnů a kromě hlaviček má být odhlašovací odkaz viditelný i v těle zprávy. Microsoft pro Outlook.com v roce 2025 doporučuje totéž. Celý seznam požadavků máme v článku o požadavcích Gmailu, Yahoo a Seznamu.
Pro transakční e-maily (potvrzení objednávky, faktura, reset hesla) to Google výslovně nevyžaduje; nejsou odběr, zákazník si je nemůže „odhlásit". A podle zákona 480/2004 Sb. musí mít možnost odmítnutí každé obchodní sdělení, bez ohledu na objem, takže funkční odhlášení v hlavičce je rozumný způsob, jak tu povinnost splnit i u menších odesílatelů.
Proč to dělat i u „informačních" e-mailů
Mezi potvrzením objednávky a newsletterem je šedá zóna: tipy k používání produktu, „co je nového", připomínky nedokončeného nastavení, týdenní přehledy, žádosti o recenzi. Nejsou to objednávky, zákazník je nemusí chtít, a když ho otravují, má dvě možnosti: najít odhlášení, nebo kliknout na „Spam". Druhá možnost je o jedno kliknutí blíž.
Každé označení za spam se počítá do míry stížností, kterou Gmail měří na celou doménu. Pár desítek stížností na týdenní přehled zhorší doručitelnost potvrzení objednávek ze stejné domény. Tlačítko „Odhlásit" vedle odesílatele tu stížnost odvede jinam: příjemce se odhlásí, vy ztratíte jednoho čtenáře přehledu, reputace zůstane.
Praktické pravidlo: hlavičky přidávejte u všeho, co není nutné k plnění smlouvy. U faktury a resetu hesla ne, u „tipů na začátek" ano, i když je posíláte dvaceti lidem denně.
Jak napsat endpoint
1. Token na příjemce a typ odběru. Do odkazu nedávejte e-mail ani ID uživatele. Vygenerujte náhodný token (nebo podepsaný řetězec s HMAC), uložte si k němu adresu a typ e-mailů, kterých se týká. Token nesmí být uhodnutelný a nesmí se dát použít k ničemu jinému než k odhlášení.
2. POST provede odhlášení okamžitě a bez interakce. Žádné přesměrování, žádné „potvrďte", žádný požadavek na přihlášení. Odpovězte 200 OK (klidně s prázdným tělem) ideálně do pár sekund. Tělo požadavku s hodnotou List-Unsubscribe=One-Click můžete zkontrolovat, ale endpoint by měl fungovat i bez ní.
3. GET zobrazí stránku pro lidi. Stejnou adresu kliknou i uživatelé z těla e-mailu. Pro GET ukažte jednoduchou stránku s tlačítkem „Odhlásit", případně volbou, co přesně chtějí vypnout. Neodhlašujte na GET automaticky; některé antivirové brány odkazy v e-mailech otevírají a odhlásily by lidi, kteří nic nechtěli.
4. Idempotence. Druhý POST se stejným tokenem vrátí také 200. Token nezneplatňujte po prvním použití; Gmail může požadavek zopakovat a uživatel může kliknout dvakrát.
5. Zapište to. Uložte čas, token a zdroj (hlavička vs. odkaz v těle). Hodí se pro doklad podle zákona i pro odhalení chyb.
6. Žádný rate limit na token, mírný na IP. Odhlášení má projít vždy. Ochranu proti zahlcení řešte na úrovni IP a velikosti požadavku.
Minimální ukázka v Node.js (Express):
app.post('/odhlasit', async (req, res) => {
const sub = await findSubscriptionByToken(req.query.t)
if (sub) await unsubscribe(sub) // idempotentní
res.status(200).end() // vždy 200, i pro neznámý token
})
app.get('/odhlasit', async (req, res) => {
res.send(renderUnsubscribePage(req.query.t)) // stránka s tlačítkem
})
Pro neznámý token vracejte také 200; jinak podle odpovědi půjde zjistit, které tokeny existují.
7. mailto: jako záloha. Někteří klienti HTTPS variantu nepoužijí. Adresa odhlasit@firma.cz s předmětem obsahujícím token a jednoduché zpracování příchozí pošty pokryje i je. Pokud ji neumíte zpracovat automaticky, radši ji vynechte, než aby žádosti ležely ve schránce.
Jak hlavičky přidat při odesílání
Přes SMTP relay jsou hlavičky součást zprávy, kterou posílá vaše aplikace nebo knihovna; relay je předá beze změny a podepíše je DKIM. V PHPMaileru je to addCustomHeader(), v Nodemaileru pole headers, v Pythonu msg['List-Unsubscribe'] = ….
Přes REST API TopEmail pošlete obě hlavičky v poli headers požadavku (povolené jsou List-Unsubscribe, List-Unsubscribe-Post a libovolné X-*):
{
"from": "Můj e-shop <info@muj-eshop.cz>",
"to": ["zakaznik@example.com"],
"subject": "Novinky z e-shopu",
"html": "<p>…</p>",
"headers": {
"List-Unsubscribe": "<https://muj-eshop.cz/odhlasit?t=TOKEN>, <mailto:odhlasit@muj-eshop.cz?subject=TOKEN>",
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
}
}
Podrobnosti v popisu API.
Jak zkontrolovat, že to funguje
- Pošlete si zprávu na Gmail, otevřete „Zobrazit originál" a najděte obě hlavičky. Zkontrolujte, že DKIM podpis má v
h=seznamuList-UnsubscribeaList-Unsubscribe-Post. - Pošlete POST ručně (
curl -X POST -d 'List-Unsubscribe=One-Click' 'https://firma.cz/odhlasit?t=…') a ověřte, že odpověď je 200 a odběr vypnutý. - Nepanikařte, když Gmail tlačítko nezobrazí. Zobrazuje ho jen odesílatelům s dostatečnou reputací a historií; chybějící tlačítko není chyba implementace.
- Po odhlášení přestaňte posílat do dvou dnů, ideálně okamžitě. Nejlepší pojistka je kontrola stavu odběru těsně před odesláním, ne jednou denně v dávce.
Shrnutí
List-Unsubscribes HTTPS (a volitelně mailto) +List-Unsubscribe-Post: List-Unsubscribe=One-Click, obojí pokryté DKIM.- Povinné u hromadných odesílatelů marketingových e-mailů od 2024; u transakčních ne.
- Vyplatí se u všech e-mailů, které zákazník nepotřebuje k plnění smlouvy, protože odhlášení je levnější než stížnost.
- Endpoint: POST odhlásí hned a vrátí 200, GET zobrazí stránku, token je náhodný a idempotentní.
- Odhlášení promítněte do odesílání co nejdřív, nejpozději do dvou dnů.
Pro marketingové kampaně TopEmail není určený, ale informační e-maily k vašemu produktu přes něj posílat můžete; podrobnosti k tomu, co je a není transakční, najdete v častých dotazech.
Transakční e-maily z vaší domény přes API nebo SMTP, od 0,025 do 0,06 Kč za e-mail podle objemu, prvních 1 000 e-mailů měsíčně zdarma. Registrace zdarma, bez platební karty.
Registrovat zdarma →