E-posta & SMTP Sunucu

    List-Unsubscribe Başlığı Kurulumu

    Tek tıkla abonelikten çıkma başlığının doğru kurulumu ve sık yapılan biçim hataları.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Bir kullanıcı mektubunuzu artık istemediğinde iki seçeneği vardır: en alta inip abonelikten çıkma bağlantısını aramak ya da doğrudan "spam" düğmesine basmak. İkincisi hem daha kolaydır hem de size çok daha pahalıya patlar. List-Unsubscribe başlığı, alıcı sağlayıcının mektubun üstünde kendi arayüzünde bir "abonelikten çık" düğmesi göstermesini sağlar ve bu düğme, spam düğmesinin hemen yanında durur. Amaç basittir: şikâyeti abonelikten çıkmaya dönüştürmek.

    Bu yazıda List-Unsubscribe başlığının iki biçimini (mailto: ve https:), RFC 8058 ile gelen tek tıkla çıkış (List-Unsubscribe-Post) mekanizmasını, başlığın hangi mektuplara konulması gerektiğini, Postfix–PHP–kampanya aracı tarafında nasıl uygulanacağını ve en sık yapılan biçim hatalarını anlatacağım. Doğru kurulmuş bir başlık, hem teslimat oranınızı yükseltir hem de büyük sağlayıcıların toplu gönderici şartlarından birini karşılar.

    Başlık Ne İşe Yarar ve Kim Gösterir#

    List-Unsubscribe, mektubun başlıklarına eklenen ve alıcının abonelikten çıkmak için kullanabileceği bir veya iki adres taşıyan alandır. Kullanıcı bunu doğrudan görmez; gören taraf alıcı posta istemcisi ya da web arayüzüdür. Gmail, Outlook, Yahoo ve modern istemcilerin çoğu bu başlığı gördüğünde gönderen adının yanında ya da mektubun üstünde bir bağlantı gösterir.

    Başlığın var olması tek başına yeterli değildir; sağlayıcılar bunu göstermeden önce genellikle iki koşul arar. Birincisi, mektubun kimlik doğrulamasından geçmiş olması — yani SPF ve DKIM'in doğrulanması. İkincisi, göndericinin makul bir itibara sahip olması. Kimlik doğrulaması olmayan bir mektupta düğme genellikle hiç gösterilmez, çünkü sahte bir mektuptaki çıkış bağlantısı kullanıcıyı tehlikeye atabilir. Bu yüzden başlığı kurmadan önce SPF ve DKIM tarafınızın sağlam olduğundan emin olun; SPF yazımı için SPF kaydı yazma rehberi işinizi görür.

    Başlık, ilgili birkaç alandan yalnızca biridir. Tam bir liste mektubunda şu üçlüyü birlikte görmek yaygındır:

    List-Id: Firmaniz Aylik Bulten <bulten.firmaniz.com>
    List-Unsubscribe: <https://firmaniz.com/cikis?t=9f3c21a7>, <mailto:[email protected]>
    List-Unsubscribe-Post: List-Unsubscribe=One-Click
    

    List-Id mektubun hangi listeye ait olduğunu bildirir ve kullanıcıların istemci tarafında kural yazmasını kolaylaştırır. Asıl iş yapan alan ise ikincisidir.

    mailto ve https Biçimleri#

    List-Unsubscribe değeri, köşeli parantez içinde bir veya birden çok URI taşır ve bunlar virgülle ayrılır. İki tür kullanılır:

    BiçimNasıl çalışırAvantajıDezavantajı
    mailto:İstemci boş bir mektup gönderirSunucu tarafında kolay işlenir, JavaScript gerekmezGönderim gecikebilir, bounce alabilir
    https:Sağlayıcı POST isteği gönderirAnında işlenir, doğrulanabilirEndpoint'in her zaman ayakta olması gerekir

    En sağlam kurulum ikisini birlikte vermektir. Sağlayıcı hangisini destekliyorsa onu kullanır; biri çalışmazsa diğeri devreye girer. Sıralamada https: önce yazılır, çünkü çoğu sağlayıcı listedeki ilk desteklediği biçimi seçer ve HTTPS daha hızlı sonuçlanır.

    mailto: biçiminde abone kimliğini adresin yerel kısmına gömmek işinizi çok kolaylaştırır. Postfix'te bunu yakalamak için adres uzantılarını (recipient_delimiter) kullanabilirsiniz:

    # /etc/postfix/main.cf
    recipient_delimiter = +
    

    Bu ayarla [email protected] adresine gelen mektup, cikis kutusuna düşer ve Delivered-To başlığında tam adres korunur. Böylece tek bir kutuda tüm çıkış taleplerini toplayıp kimliği ayrıştırabilirsiniz:

    # /etc/aliases
    cikis: "|/usr/local/bin/abonelik-cikis.sh"
    
    sudo newaliases && sudo systemctl reload postfix
    
    # Gelen çıkış taleplerinin sayısını görmek için
    grep -c "to=<cikis+" /var/log/mail.log
    

    https: biçiminde ise uç noktanız iki tür isteği karşılamalıdır: kullanıcının tarayıcıda tıkladığı GET isteği ve sağlayıcının otomatik gönderdiği POST isteği. İkisi de aynı token'ı kabul etmeli ve aynı sonucu üretmelidir.

    RFC 8058: Tek Tıkla Abonelikten Çıkma#

    Klasik List-Unsubscribe başlığı, sağlayıcının bir onay ekranı göstermesine ya da kullanıcıyı sizin sitenize götürmesine yol açardı. RFC 8058, buna List-Unsubscribe-Post alanını ekleyerek gerçek anlamda tek tıkla çıkışı tanımladı. Değer sabittir ve birebir şu şekilde yazılır:

    List-Unsubscribe-Post: List-Unsubscribe=One-Click
    

    Bu alan varsa, sağlayıcı kullanıcının tıklamasının ardından sizin HTTPS adresinize application/x-www-form-urlencoded gövdeli bir POST isteği gönderir ve gövdede List-Unsubscribe=One-Click parametresi bulunur. Kullanıcı sizin sitenize hiç gitmez.

    Uç noktanızın karşılaması gereken kurallar şunlardır:

    1. HTTPS zorunludur. Düz HTTP adresleri kabul edilmez.
    2. POST isteğini kimlik doğrulaması istemeden işleyin. Sağlayıcı çerez taşımaz, oturum açmaz.
    3. Token URL'de olmalıdır, gövdede beklemeyin. Tahmin edilemez ve tek aboneye özgü olsun.
    4. Hızlı yanıt verin. 200 OK dönün; onay ekranı ya da yönlendirme göstermeyin.
    5. İşlemi eşgüçlü (idempotent) yapın. Aynı token birden çok kez gelirse ikinci istek hata üretmemelidir.
    6. CSRF korumasını bu uç nokta için devre dışı bırakın, aksi halde POST reddedilir.

    PHP tarafında minimal bir uygulama şöyle görünür:

    <?php
    // /cikis endpoint'i — hem GET (tarayıcı) hem POST (tek tıkla) kabul eder
    $token = $_GET['t'] ?? '';
    if (!preg_match('/\A[a-f0-9]{8,64}\z/', $token)) {
        http_response_code(400);
        exit('gecersiz istek');
    }
    
    // Token'i aboneye cevir ve listeden cikar (idempotent olmali)
    aboneligiKapat($token);
    
    // Saglayicinin POST istegine sade 200 don, yonlendirme yapma
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        http_response_code(200);
        exit('ok');
    }
    
    // Tarayicidan gelen kullaniciya kisa bir onay sayfasi goster
    echo 'Abonelikten cikarildiniz.';
    

    Token üretirken tahmin edilemez olmasına dikkat edin; abone kimliğini düz metin yazmak, birinin sırayla deneyerek başkalarını listeden çıkarmasına imkân verir. Rastgele bir değer ya da abone kimliğinin gizli anahtarla HMAC'i uygun olur; hızlıca değer üretmek için hash üretici aracını kullanabilirsiniz.

    Başlığı Hangi Mektuplara Koymalısınız#

    Kural nettir: toplu ve pazarlama amaçlı her mektuba koyun, işlemsel mektuplara koymayın. Şifre sıfırlama, sipariş onayı, fatura ve güvenlik uyarısı gibi mektuplar kullanıcının talep ettiği ve çıkamayacağı iletilerdir; bunlara çıkış başlığı koymak hem anlamsızdır hem de kullanıcı yanlışlıkla tıkladığında kritik bildirimleri kaybeder.

    Mektup türüList-UnsubscribeGerekçe
    Bülten, kampanyaEvet, tek tıkla dahilZorunlu sayılır
    Ürün duyurusu, blog özetiEvetPazarlama iletisi
    Sepet hatırlatmaEvetPazarlama iletisi
    Sipariş onayı, kargo bildirimiHayırİşlemsel
    Şifre sıfırlama, doğrulama koduHayırGüvenlik kritik
    Fatura ve ödeme bildirimiHayırYasal/işlemsel

    Gri bölge, işlemsel bir mektubun içine pazarlama bloğu eklendiğinde oluşur. Sipariş onayının altına "bunları da beğenebilirsiniz" eklerseniz mektup karma hale gelir ve alıcı sağlayıcı bunu pazarlama sayabilir. En temiz çözüm, işlemsel mektupları pazarlama içeriğinden ayrı tutmak ve mümkünse ayrı bir alt alan adından göndermektir.

    Büyük sağlayıcıların günlük belirli bir eşiği aşan göndericilerden bu başlığı zorunlu tutan güncel şartları için Gmail ve Yahoo yeni gönderici kuralları yazısına bakın; orada eşikler ve diğer koşullar bir arada.

    Başlığı Kendi Gönderim Kodunuzda Üretmek#

    Hazır bir kampanya aracı kullanıyorsanız başlık genellikle otomatik eklenir ve sizin yapmanız gereken tek şey, aracın abonelik yönetimi ekranından tek tıkla çıkışı etkinleştirmektir. Kendi kodunuzdan gönderiyorsanız başlığı her alıcı için ayrı ayrı üretmeniz gerekir — çünkü token aboneye özgüdür ve tüm listeye aynı değeri koyarsanız bir kişinin çıkışı herkesi listeden düşürür.

    Kritik nokta, başlığın DKIM imzasının kapsamına girmesidir. İmza h= alanında hangi başlıkların imzalandığı yazar; List-Unsubscribe bu listede yoksa yolda değiştirilebilir ve bazı sağlayıcılar imzalanmamış çıkış başlığını dikkate almaz. OpenDKIM kullanıyorsanız imzalanan başlık listesini genişletin:

    # /etc/opendkim.conf
    SignHeaders  From,To,Subject,Date,Message-ID,MIME-Version,Content-Type,List-Id,List-Unsubscribe,List-Unsubscribe-Post
    

    Servisi yeniden başlattıktan sonra bir test mektubunun DKIM-Signature başlığındaki h= listesinde bu alanların göründüğünü doğrulayın:

    sudo systemctl restart opendkim postfix
    
    # Test mektubunun ham kaynagindan imzalanan basliklari cikarin
    grep -o 'h=[^;]*' /tmp/test-mektup.eml
    

    PHP tarafında gönderim yaparken başlıkları alıcı döngüsünün içinde kurun, dışında değil:

    <?php
    foreach ($aboneler as $abone) {
        $token = hash_hmac('sha256', (string) $abone['id'], GIZLI_ANAHTAR);
        $token = substr($token, 0, 32);
    
        $basliklar = [
            'From: Firmaniz Bulten <[email protected]>',
            'List-Id: Firmaniz Aylik Bulten <bulten.firmaniz.com>',
            'List-Unsubscribe: <https://firmaniz.com/cikis?t=' . $token . '>, '
                . '<mailto:cikis+' . $token . '@firmaniz.com>',
            'List-Unsubscribe-Post: List-Unsubscribe=One-Click',
        ];
    
        gonder($abone['eposta'], $konu, $govde, $basliklar);
    }
    

    HMAC ile üretilen token'ın avantajı, veritabanında ayrı bir tablo tutmanıza gerek kalmamasıdır: gelen token'ı doğrulamak için abone kimliklerini aynı anahtarla yeniden hesaplayıp karşılaştırırsınız. Anahtarı sızdırmadığınız sürece dışarıdan geçerli token üretilemez.

    Kurulumu Doğrulama#

    Başlığı ekledikten sonra gerçekten göründüğünü ve çalıştığını iki adımda sınayın. Önce kendinize bir test mektubu gönderip ham kaynağını açın (Gmail'de "Orijinali göster", Outlook'ta "İleti kaynağını görüntüle") ve başlıkların birebir şu şekilde yer aldığını doğrulayın:

    Authentication-Results: mx.ornek.com; spf=pass; dkim=pass header.d=firmaniz.com
    List-Unsubscribe: <https://firmaniz.com/cikis?t=9f3c21a7>, <mailto:[email protected]>
    List-Unsubscribe-Post: List-Unsubscribe=One-Click
    

    Sonra uç noktanızı, sağlayıcının yapacağı isteğin aynısıyla dışarıdan sınayın:

    # Saglayicinin gonderdigi istegin birebir esdegeri
    curl -i -X POST "https://firmaniz.com/cikis?t=9f3c21a7" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         -d "List-Unsubscribe=One-Click"
    
    # Beklenen: HTTP/1.1 200 OK, kisa gövde, yonlendirme yok
    

    Yanıt 301, 302 ya da 403 ise sağlayıcı bunu başarısız sayar ve düğmeyi göstermeyi bir süre sonra bırakır. Aynı token'ı ikinci kez gönderip yine 200 aldığınızı doğrulayın; eşgüçlülük burada sınanır.

    Gönderim yolundaki TLS ve port ayarlarını da denetlemek isterseniz SMTP test aracı gerekli komutları hazır üretir.

    Sık Yapılan Hatalar#

    Köşeli parantezleri unutmak. Değer mutlaka açılı parantez içinde olmalıdır; parantezsiz yazılan adres birçok istemcide ayrıştırılamaz ve başlık yok sayılır.

    Yalnızca mailto: vermek ve o kutuyu okumamak. Çıkış talepleri bir kutuya düşer, kimse bakmaz, kullanıcı listede kalır ve bir sonraki mektupta spam düğmesine basar. Bu, başlığı hiç koymamaktan daha kötüdür çünkü kullanıcıya çalışmayan bir söz verir.

    List-Unsubscribe-Post koyup HTTPS uç noktası vermemek. Tek tıkla çıkış yalnızca HTTPS ile çalışır; sadece mailto: varken bu alanı eklemek tutarsız bir başlık üretir.

    POST isteğini CSRF korumasına takmak. Uygulama çatısı gelen isteği token'sız bulup 403 döner ve sağlayıcı bunu başarısızlık sayar. Bu uç noktayı korumadan muaf tutun; güvenliği URL'deki tahmin edilemez token sağlar.

    Onay ekranı göstermek. Tek tıkla çıkış, kullanıcıya ikinci bir adım sunulmaması demektir. POST isteğine yönlendirme ya da form dönerseniz mekanizma bozulur.

    Token'ı düz abone kimliği yapmak. ?t=1042 gibi sıralı bir değer, birinin listeyi baştan sona çıkarabilmesi anlamına gelir. Rastgele ya da imzalı token kullanın.

    Çıkışı geciktirmek. Talep alındığında abone en geç birkaç gün içinde listeden çıkmalıdır; devam eden gönderim doğrudan şikâyete dönüşür. En sağlıklısı anında işlemektir.

    Sıkça Sorulan Sorular#

    List-Unsubscribe başlığı zorunlu mu#

    Teknik olarak bir RFC zorunluluğu değildir, ama pratikte zorunlu hale gelmiştir. Büyük sağlayıcılar, günlük belirli bir eşiğin üzerinde toplu mektup gönderen göndericilerden tek tıkla abonelikten çıkma desteğini şart koşar ve bu şartı karşılamayanların teslimat oranını düşürür. Toplu gönderim yapıyorsanız başlığı bir seçenek değil, kurulum adımı olarak görün.

    mailto mu https mi kullanmalıyım#

    İkisini birlikte verin, https: önce olacak şekilde. HTTPS anında işlenir ve tek tıkla çıkış yalnızca onunla mümkündür; mailto: ise HTTPS uç noktanız erişilemez olduğunda ya da sağlayıcı HTTPS'i tercih etmediğinde yedek görevi görür. Yalnızca birini seçmek zorundaysanız HTTPS'i seçin, ama o zaman uç noktanızın kesintisiz ayakta kalması gerekir.

    Tek tıkla abonelikten çıkma nasıl test edilir#

    Kendinize bir test mektubu gönderip ham başlıklarda List-Unsubscribe ve List-Unsubscribe-Post alanlarının göründüğünü doğrulayın, sonra uç noktanıza curl ile POST isteği atarak 200 OK döndüğünü ve abonenin gerçekten listeden çıktığını kontrol edin. Aynı isteği ikinci kez gönderip hata almadığınızı da sınayın; sağlayıcılar aynı talebi tekrarlayabilir.

    Başlığı ekledim ama Gmail düğmeyi göstermiyor#

    En sık sebep kimlik doğrulamadır: SPF ve DKIM geçmiyorsa Gmail düğmeyi göstermez. Test mektubunun Authentication-Results başlığında ikisinin de pass olduğunu doğrulayın. İkinci sebep biçim hatasıdır — köşeli parantez eksikliği ya da List-Unsubscribe-Post değerinin birebir yazılmamış olması. Üçüncü sebep düşük gönderici itibarıdır; yeni bir alan adında düğme bir süre gösterilmeyebilir.

    İşlemsel mektuplara da koymalı mıyım#

    Hayır. Şifre sıfırlama, sipariş onayı, fatura ve güvenlik uyarısı gibi mektuplar kullanıcının talep ettiği iletilerdir ve bunlardan çıkma seçeneği sunmak, kritik bildirimlerin kaybolmasına yol açar. Bu tür mektuplara başlığı koymamak aynı zamanda alıcı sağlayıcıların beklediği davranıştır.

    Abonelikten çıkanı ne kadar sürede listeden çıkarmalıyım#

    Mümkünse anında. Tek tıkla çıkış isteğini aldığınız anda aboneyi bastırma listesine yazmak hem teknik olarak kolaydır hem de en güvenli davranıştır. Toplu işleyen bir sisteminiz varsa bile birkaç günü geçmemelidir; bu süre içinde gönderilen her mektup, spam şikâyetine dönüşme riski taşır.

    Kapanış#

    List-Unsubscribe, kurulumu yarım saat süren ama teslimat oranına etkisi aylarca hissedilen bir başlıktır. Aklınızda dört kural kalsın: HTTPS ve mailto: biçimlerini birlikte, köşeli parantez içinde verin; List-Unsubscribe-Post alanını yalnızca çalışan bir HTTPS uç noktanız varsa ekleyin; uç noktayı CSRF korumasından muaf tutup eşgüçlü ve hızlı yanıt verecek biçimde yazın; ve çıkış talebini anında işleyin. Bir de başlığı yalnızca pazarlama mektuplarına koyun, işlemsel iletilere değil.

    Gönderim altyapınızı kendiniz kurmak isterseniz Postfix, DKIM imzalama ve rDNS kaydı hazır gelen SMTP sunucu paketlerimiz iyi bir başlangıç noktasıdır. Abonelik yönetimi, bastırma listeleri ve tek tıkla çıkış akışının araç düzeyinde yönetilmesini isterseniz e-posta pazarlama hizmetimiz bunu üstlenir; kurumsal posta kutuları için e-posta çözümlerimize, sunucu bakımını devretmek için sunucu yönetimi hizmetimize göz atabilirsiniz.

    List-UnsubscribeTeslimatSMTP

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.