Supresi
Workspace Anda memiliki daftar supresi: kumpulan alamat email yang tidak kami kirimi pesan. Hard bounce dan laporan spam otomatis masuk ke daftar ini, dan Anda juga bisa menambahkan alamat secara manual. Mengirim berulang kali ke alamat yang bounce atau melaporkan spam dapat membuat domain Anda diblokir oleh penyedia kotak masuk, jadi kami menghentikan pengiriman tersebut sebelum keluar dari platform.
Berhenti berlangganan tidak termasuk dalam daftar ini. Berhenti berlangganan mencatat preferensi yang dinyatakan oleh penerima, bukan fakta keterkiriman, sehingga tercatat di tab Preferences. Lihat Tautan berhenti berlangganan untuk penjelasan cara kerjanya.
Kelola daftar ini di Email > Suppressions, melalui supresi API, atau dengan bird email suppressions.

Tiga alasan dan apa yang diblokir
Setiap record memiliki reason yang menjelaskan mengapa alamat tersebut terdaftar, dan kebijakan applies_to yang mengatur kategori mana yang diblokir:
| Alasan | applies_to | Kategori marketing | Kategori transaksional |
|---|---|---|---|
| hard_bounce | all | Diblokir | Diblokir |
| complaint | non_transactional | Diblokir | Diizinkan |
| manual | all | Diblokir | Diblokir |
Pembagian ini mengikuti arti dari masing-masing alasan:
- hard_bounce: alamat tidak ada. Mengirim ke alamat ini tidak berguna di kategori mana pun, jadi semua pengiriman diblokir.
- complaint: pernyataan tentang email yang tidak diinginkan. Seseorang yang melaporkan newsletter Anda sebagai spam mungkin masih membutuhkan reset kata sandi atau konfirmasi pesanan, jadi hanya pengiriman non-transaksional yang diblokir.
- manual: keputusan yang dibuat secara sengaja oleh Anda atau tim Anda. Kami tidak mempertanyakan keputusan itu, jadi supresi manual memblokir setiap kategori, termasuk transaksional.
Satu alamat dapat memiliki satu record per alasan, sehingga hard bounce dan laporan spam sebelumnya berdampingan sebagai record terpisah, dan pengiriman tetap diblokir selama record pemblokir mana pun masih ada. Kami menerapkan prinsip gagal-tertutup untuk apa pun yang tidak dikenali: jika sebuah record memiliki applies_to yang belum pernah ditemui integrasi Anda, perlakukan sebagai memblokir setiap kategori, karena begitulah kami memperlakukannya.
Note: reason: unsubscribe is deprecated on the suppressions API. Unsubscribes now record a preference instead of a suppression, so ?reason=unsubscribe matches nothing.
Cara alamat ditambahkan secara otomatis
Kami menambahkan supresi sebagai respons terhadap sinyal penerima, jadi bounce atau laporan spam tidak memerlukan tindakan dari Anda:
| Pemicu | Supresi yang dihasilkan |
|---|---|
| Hard bounce (email.bounced) | reason: hard_bounce, origin: bounce_event, applies_to: all |
| Hard bounce out-of-band (email.out_of_band_bounce) | reason: hard_bounce, origin: bounce_event, applies_to: all |
| Laporan spam (email.complained) | reason: complaint, origin: complaint_event, applies_to: non_transactional |
Berhenti berlangganan, baik melalui tautan di badan email maupun tombol satu klik, tidak muncul di sini: tindakan tersebut mencatat preferensi di tab Preferences alih-alih menambahkan baris ke daftar ini.
Hanya bounce kelas hard yang menghasilkan supresi, dan tabel klasifikasi menunjukkan nilai bounce_class mana yang termasuk hard. Dua hasil yang tampak seperti kegagalan tetap membiarkan alamat dapat dikirim:
- Soft bounce dan deferral (email.deferred, atau email.bounced dengan bounce_type: "soft"): kegagalan sementara seperti kotak masuk penuh. Kami mencoba lagi.
- Penolakan sisi pengirim: kegagalan pembuatan dan penolakan kebijakan adalah masalah pada pengiriman, bukan pada alamat. Hal ini menghasilkan event email.rejected dan tidak ada supresi.
Sinyal berulang untuk alamat yang sudah disupresi dengan alasan yang sama tidak mengubah record asli, termasuk created_at-nya. Record menyimpan source_email_id dan source_recipient_id, yang menghubungkan supresi otomatis kembali ke pesan dan penerima yang menyebabkannya. Kedua field tersebut menjawab pertanyaan dukungan "why did this person stop getting our email", dan bernilai null pada penambahan manual.
Setiap penambahan, otomatis maupun manual, memicu event email_suppression.created ke endpoint webhook Anda dengan suppression_id, email yang disupresi, reason, dan workspace_id, sehingga sistem Anda dapat mencerminkan daftar tanpa polling:
Contoh kode
{
"type": "email_suppression.created",
"timestamp": "2026-07-23T14:52:03.192524705Z",
"data": {
"email": "user@example.com",
"reason": "manual",
"suppression_id": "sup_01ky7qckqrf06r38g49b9kxdbc",
"workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf"
}
}Mengelola supresi melalui API
API menambahkan, mencantumkan, mencari, dan menghapus record satu per satu. Alamat diubah ke huruf kecil sebelum disimpan dan dicari, dan tidak pernah muncul di path URL, karena path masuk ke log akses dan alamat email adalah data pribadi. Untuk menemukan record suatu alamat, filter daftar dengan ?email=.
Contoh SDK mengakses supresi melalui metode raw-request setiap klien, yang membawa autentikasi, percobaan ulang, dan penanganan base-URL yang sama seperti typed call. Bentuk respons adalah yang Anda deklarasikan.
Tambahkan alamat
type Suppression = { id: string; email: string; reason: string };
const suppression = await bird.request<Suppression>({
method: "POST",
path: "/v1/email/suppressions",
body: { email: "user@example.com" },
});client.post("/v1/email/suppressions", body={"email": "user@example.com"})var suppression struct {
Id string `json:"id"`
Email string `json:"email"`
Reason string `json:"reason"`
}
if err := client.Post(context.Background(), "/v1/email/suppressions", map[string]any{
"email": "user@example.com",
}, &suppression); err != nil {
log.Fatal(err)
}$suppression = $bird->post('/v1/email/suppressions', body: [
'email' => 'user@example.com',
]);curl -X POST https://us1.platform.bird.com/v1/email/suppressions \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "email": "user@example.com" }'Di CLI, bird email suppressions mencakup list dan remove; menambahkan alamat dilakukan melalui API.
Penambahan manual mendapatkan reason: manual dan applies_to: all, sehingga memblokir setiap kategori. Panggilan ini idempoten: supresi baru mengembalikan 201 Created, dan alamat yang sudah disupresi secara manual mengembalikan 200 OK dengan record yang sudah ada, bukan konflik. Bagaimanapun hasilnya, body berisi objek supresi:
Contoh kode
{
"applies_to": "all",
"created_at": "2026-07-23T14:52:03.192524705Z",
"email": "user@example.com",
"id": "sup_01ky7qckqrf06r38g49b9kxdbc",
"origin": "api_key",
"reason": "manual",
"scope": {
"id": "ws_01ky7m21hjffh9s8kq76gyb1xf",
"type": "workspace"
}
}Field origin mencatat bagaimana record tersebut dibuat. Penambahan manual mendapatkan api_key atau user, tergantung apakah pemanggil melakukan autentikasi dengan kunci API atau sesi dashboard. Penambahan otomatis mendapatkan bounce_event atau complaint_event, tergantung sinyal mana yang membuatnya.
Daftar dan pencarian
type Suppressions = { data: Array<{ id: string; email: string; reason: string }> };
const suppressions = await bird.request<Suppressions>({
method: "GET",
path: "/v1/email/suppressions?limit=25",
});
console.log(suppressions.data.length);suppressions = client.get("/v1/email/suppressions?limit=25")
print(len(suppressions["data"]))var out struct {
Data []struct {
Email string `json:"email"`
Reason string `json:"reason"`
} `json:"data"`
}
if err := client.Get(context.Background(), "/v1/email/suppressions?limit=25", &out); err != nil {
log.Fatal(err)
}
fmt.Println(len(out.Data))$suppressions = $bird->get('/v1/email/suppressions', query: ['limit' => 25]);bird email suppressions list --limit 25curl "https://us1.platform.bird.com/v1/email/suppressions?limit=25" \
-H "Authorization: Bearer $BIRD_API_KEY"Daftar menggunakan paginasi kursor, terbaru lebih dulu, dan dapat difilter berdasarkan reason. Untuk memeriksa satu alamat, kirimkan sebagai parameter query email:
const suppressions = await bird.request({
method: "GET",
path: "/v1/email/suppressions?email=user@example.com",
});
console.log(suppressions.data.length);suppressions = client.get("/v1/email/suppressions?email=user@example.com")
print(len(suppressions["data"]))var out struct {
Data []struct {
Email string `json:"email"`
Reason string `json:"reason"`
} `json:"data"`
}
if err := client.Get(context.Background(), "/v1/email/suppressions?email=user@example.com", &out); err != nil {
log.Fatal(err)
}
fmt.Println(len(out.Data))$suppressions = $bird->get('/v1/email/suppressions', query: ['email' => 'user@example.com']);bird email suppressions list --email user@example.comcurl "https://us1.platform.bird.com/v1/email/suppressions?email=user@example.com" \
-H "Authorization: Bearer $BIRD_API_KEY"Array data yang kosong berarti alamat tersebut tidak disupresi, dan beberapa record dikembalikan jika lebih dari satu alasan berlaku. Filter email mencocokkan secara case-insensitive berdasarkan prefiks, jadi alamat lengkap mengembalikan record alamat tersebut dan fragmen seperti alice mengembalikan setiap alamat yang disupresi yang diawali dengannya.
Hapus alamat
await bird.request({
method: "DELETE",
path: "/v1/email/suppressions/sup_01ky7qckqrf06r38g49b9kxdbc",
});client.delete("/v1/email/suppressions/sup_01ky7qckqrf06r38g49b9kxdbc")if err := client.Delete(context.Background(), "/v1/email/suppressions/sup_01ky7qckqrf06r38g49b9kxdbc", nil); err != nil {
log.Fatal(err)
}$bird->delete('/v1/email/suppressions/sup_01ky7qckqrf06r38g49b9kxdbc');bird email suppressions remove sup_01ky7qckqrf06r38g49b9kxdbc --yescurl -X DELETE https://us1.platform.bird.com/v1/email/suppressions/sup_01ky7qckqrf06r38g49b9kxdbc \
-H "Authorization: Bearer $BIRD_API_KEY"Mengembalikan 204 No Content. Penghapusan bersifat permanen: kami tidak menyimpan apa pun, dan alamat tersebut dapat dikirim lagi. Menghapus berdasarkan alamat memerlukan dua panggilan, pencarian ?email= untuk mendapatkan ID lalu penghapusan, dan alamat yang disupresi karena beberapa alasan memerlukan setiap record pemblokir dihapus. Berhati-hatilah saat menghapus record hard_bounce, karena alamat yang masih tidak ada akan bounce pada pengiriman berikutnya dan menyupresi dirinya sendiri lagi.
Apa yang terjadi saat Anda mengirim ke alamat yang disupresi
Kami menolak penerima di tempat yang dapat Anda lihat. Penerima mendapatkan recipient_id dan muncul di daftar penerima pesan dengan status rejected. Event API dan webhook Anda mencatat event email.rejected dengan rejection_reason: "recipient_suppressed". Penerima lainnya dikirim secara normal.
Pesan itu sendiri tetap diterima dengan 202, bahkan ketika semua penerimanya disupresi. Kami menyelesaikan supresi setelah menerima pengiriman, saat kami memproses pesan, jadi alamat yang Anda tambahkan sekarang berlaku dalam beberapa menit dan tidak menghentikan pengiriman yang sudah berjalan.
Pengujian dengan sandbox
Sandbox pengujian menjalankan penanganan supresi secara deterministik. Mengirim ke suppressed@messagebird.dev berperilaku seolah-olah alamat tersebut ada di daftar Anda: penerima ditolak dengan rejection_reason: "recipient_suppressed" dan tidak pernah mencapai pengiriman. Alamat bounce dan laporan spam di sandbox (bounce@messagebird.dev, complaint@messagebird.dev) menjalankan hasilnya melalui pipeline event yang sesungguhnya tanpa menulis apa pun ke daftar supresi Anda, sehingga alamat uji yang sama tetap dapat digunakan ulang di setiap percobaan.
Langkah selanjutnya
- Kategori: transactional versus marketing, dan bagaimana kategori berinteraksi dengan kebijakan supresi
- Tautan berhenti berlangganan: cara opt-out mencatat preferensi yang dinyatakan alih-alih supresi
- Event dan webhook: payload email.rejected dan event siklus hidup yang memicu supresi otomatis
- Sandbox pengujian: alamat khusus untuk menyimulasikan setiap hasil pengiriman
- Referensi API: Suppressions: skema request dan response lengkap
- Apa yang terjadi ketika seseorang berhenti berlangganan: video yang mengikuti satu penerima dari halaman berhenti berlangganan hingga pengiriman yang ditolak
Sumber daya terkait
Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini. Sumber daya tersedia dalam bahasa Inggris.
Pahami konsepnyaWhat is one-click unsubscribe, and how do I implement List-Unsubscribe?Jelajahi kemampuannyaEmail opt-outsIkuti jalur pembelajaranOperate messaging reliably
Dapatkan ringkasan implementasi