Webhook: terima event email secara real-time
Daftarkan webhook untuk menerima event delivered, bounce, complaint, open, click, dan unsubscribe — lengkap dengan cara verifikasi tanda tangan.
Di halaman ini
Webhook membuat kirim.id mengirim POST ke URL-mu setiap ada kejadian pada email dari akunmu — dari semua jalur: campaign, journey, API, maupun SMTP relay. Dibanding mengecek status berulang-ulang, webhook lebih hemat kuota request dan datanya sampai lebih cepat. Artikel ini membahas cara mendaftarkan webhook, isi payload, dan cara wajib memverifikasi tanda tangannya.
Daftar event#
| Event | Kapan |
|---|---|
delivered | Email diterima server penerima. occurred_at = waktu email diserahkan ke server pengiriman. |
bounce | Ditolak server penerima (sementara maupun permanen). |
complaint | Penerima melapor spam. |
open | Setiap kali email dibuka (bisa lebih dari sekali per email). |
click | Setiap klik link yang dilacak. |
unsubscribe | Penerima berhenti langganan lewat link di email. |
Mengelola webhook#
Endpoint webhook butuh API key dengan scope manage_webhooks.
/v1/webhooksMendaftarkan URL penerima dan event yang ingin kamu terima. Jawaban 201 berisi secret untuk verifikasi tanda tangan.
curl -X POST https://api.kirim.id/v1/webhooks \
-H "Authorization: Bearer $KIRIM_API_KEY" -H "Content-Type: application/json" \
-d '{"url":"https://tokomu.com/webhook/kirim","event_types":["delivered","bounce","complaint","click"]}'
# 201 {"id":3,"url":"https://tokomu.com/webhook/kirim","secret":"q8Xk…40 karakter…","event_types":["delivered","bounce","complaint","click"]}url: wajibhttps://, maks. 255 karakter, tanpa username/password, host harus bisa ditemukan di DNS dan tidak boleh mengarah ke jaringan internal/privat.event_types: minimal satu event dari daftar di atas.Maksimal 10 webhook per akun.
/v1/webhooksDaftar webhook beserta event_types dan is_active.
/v1/webhooks/{id}Menghapus webhook. Jawaban: {"deleted":true}. Pengiriman yang masih antre untuk webhook itu dibatalkan.
Isi payload#
POST https://tokomu.com/webhook/kirim
Content-Type: application/json
X-Kirim-Signature: 5d41402abc4b2a76b9719d911017c592… (hex HMAC-SHA256)
{
"event": "click",
"message_id": "9b1c7e2a-5d0f-4b8e-9a51-3f0c2d6e7a10",
"occurred_at": "2026-09-22T03:10:44+00:00",
"to": "[email protected]",
"channel": "api",
"campaign_id": null,
"metadata": {"order_id": "1001"},
"url": "https://tokomu.com/produk/kaos"
}| Field | Keterangan |
|---|---|
event · message_id · occurred_at | Selalu ada. |
to | Email penerima (null kalau kontaknya sudah dihapus). |
channel · campaign_id | Jalur kirim (api / smtp / app) dan ID campaign bila dari campaign. |
metadata | Metadata yang kamu kirim di POST /messages ({} kalau tidak ada). |
url | Hanya event click: link tujuan yang diklik. |
reason | Hanya event bounce: kode & alasan dari server penerima, mis. 550 mailbox unavailable. |
Field baru bisa ditambahkan kapan saja — abaikan field yang tidak kamu kenal, jangan menolak request karenanya.
Verifikasi tanda tangan (wajib)#
Siapa pun bisa mengirim POST ke URL-mu, jadi selalu pastikan request benar-benar dari kirim.id:
Ambil body mentah — byte persis seperti diterima. Jangan parse JSON lalu encode ulang.
Hitung HMAC-SHA256 dari body itu dengan
secretwebhook, ubah ke hex huruf kecil.Bandingkan dengan header
X-Kirim-Signaturememakai perbandingan waktu-konstan.
<?php
$raw = file_get_contents('php://input');
$expected = hash_hmac('sha256', $raw, getenv('KIRIM_WEBHOOK_SECRET'));
if (! hash_equals($expected, $_SERVER['HTTP_X_KIRIM_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
$event = json_decode($raw, true);
// simpan/antrekan event, lalu jawab 2xx secepatnya
http_response_code(200);Pengiriman ulang & duplikat#
Jawab dengan status
2xxdalam 10 detik (koneksi maks. 5 detik). Redirect tidak diikuti.Kalau gagal atau bukan
2xx, kirim.id mencoba lagi dengan jeda 30, 60, 90, dan 120 detik — maksimal 5 percobaan.Event bisa datang lebih dari sekali atau tidak berurutan. Buat pemrosesanmu aman terhadap duplikat, misalnya dengan menyimpan kombinasi
message_id+event+occurred_at.
Webhook dari langkah journey#
Langkah "Webhook" di journey mengirim ke URL yang kamu atur di dashboard. Payload-nya ditandatangani dengan secret journey (lihat halaman detail journey) memakai cara verifikasi yang sama:
{"event":"journey.webhook","journey":{"id":5,"name":"Welcome Series"},"contact":{"email":"[email protected]","name":"Budi"},
"step":3,"goal_reached":false,"occurred_at":"2026-09-22T03:12:00+00:00"}Webhook journey dicoba hingga 5 kali (jeda 30 detik, 2 menit, 10 menit, 30 menit). Journey tetap berlanjut apa pun hasilnya.
Langkah berikutnya#
Kirim email lewat API — tambahkan
metadataagar event mudah dicocokkan.
Apakah artikel ini membantu?
Artikel terkait
Masih butuh bantuan?
Tim support kirim.id siap membantu · Senin–Jumat, 09.00–17.00 WIB

