Webhook Itu Seperti Kurir yang Mengetuk Pintu: Cara Kerja, Bedanya dengan Polling, dan Cara Mengamankannya
Oleh Tim APIPedia, Tim Engineering APIPedia · Terbit · 10 menit baca
Webhook itu seperti kurir yang mengetuk pintu: server lain mengabari aplikasi Anda saat ada kejadian. Begini cara kerja dan cara mengamankannya.

Webhook adalah cara sebuah server mengabari aplikasi Anda secara otomatis, lewat HTTP POST ke URL yang Anda daftarkan, tepat saat sebuah kejadian terjadi. Analogi paling gampang: webhook itu seperti kurir paket yang mengetuk pintu rumah. Anda tidak perlu bolak-balik ke pos satpam untuk bertanya "paket saya sudah datang belum?", karena kurirnya sendiri yang datang membawa kabar.
Konsep ini dipakai hampir di semua layanan modern: notifikasi pembayaran lunas, status pengiriman berubah, email dibuka, atau kode baru masuk ke repositori. Artikel ini membahas cara kerja webhook langkah demi langkah, bedanya dengan polling, kenapa kiriman bisa datang dua kali, dan empat pemeriksaan yang wajib ada supaya "kurir gadungan" tidak bisa masuk.
Ringkasan cepat: istilah apa saja yang perlu Anda tahu?
Ada delapan istilah yang paling sering muncul saat membahas webhook, dan semuanya punya padanan di dunia kirim paket.
| Istilah | Artinya | Analogi kurir |
|---|---|---|
| Event | Kejadian yang memicu kiriman, misalnya pembayaran lunas | Ada paket untuk Anda |
| Endpoint | URL HTTPS di server Anda yang menerima kiriman | Alamat rumah |
| Payload | Isi kiriman, umumnya JSON | Isi paket |
| Respons 2xx | Tanda bahwa kiriman sudah diterima | Tanda tangan terima |
| Retry | Percobaan ulang bila tidak ada respons 2xx | Kurir datang lagi besok |
| Signature | Tanda tangan HMAC yang membuktikan pengirim dan keutuhan isi | Segel paket |
| Timestamp | Waktu kirim yang ikut ditandatangani | Tanggal di resi |
| Idempoten | Kiriman yang sama diproses dua kali, hasilnya tetap satu | Cek nomor resi sebelum membuka |
Apa itu webhook?
Webhook adalah permintaan HTTP biasa yang arahnya dibalik. Pada panggilan API biasa, aplikasi Anda yang bertanya ke server lain. Pada webhook, server lain yang memanggil aplikasi Anda. Karena itu webhook kadang dijuluki "API terbalik".
Tidak ada protokol khusus di baliknya. Anda cukup menyiapkan satu URL, misalnya https://tokoanda.id/webhook/pembayaran, lalu mendaftarkannya ke layanan pengirim. Setiap kali kejadian yang Anda pilih terjadi, pengirim mengirim POST berisi JSON ke URL itu, kurang lebih seperti ini:
{
"type": "pembayaran.berhasil",
"data": { "order_id": "INV-1042", "jumlah": 150000 }
}
Apa bedanya webhook dengan polling?
Polling berarti aplikasi Anda yang bertanya berulang kali, sedangkan webhook berarti pengirim yang memberi kabar sekali saat ada kejadian. Polling itu seperti bolak-balik ke pos satpam setiap sepuluh menit. Sebagian besar jawabannya "belum ada", tetapi tenaganya tetap terpakai.

Hitungan sederhananya begini. Misalkan toko Anda menerima 1.000 pesanan sehari dan pembeli rata-rata butuh 3 menit untuk membayar. Kalau aplikasi mengecek status tiap 10 detik, satu pesanan butuh 180 ÷ 10 = 18 request, jadi totalnya 18.000 request. Dengan webhook, cukup 1.000 kiriman, satu per pembayaran. Ini simulasi hitungan, bukan benchmark, tetapi polanya selalu sama: polling membayar untuk jawaban "belum".
| Aspek | Polling | Webhook |
|---|---|---|
| Siapa yang memulai | Aplikasi Anda | Server pengirim |
| Kecepatan kabar | Tergantung jeda cek | Sesaat setelah kejadian |
| Beban request | Tinggi, banyak yang sia-sia | Sebanding jumlah kejadian |
| Yang perlu disiapkan | Cukup kode pemanggil | URL publik HTTPS dan verifikasi |
| Cocok untuk | Skrip sederhana, cadangan, rekonsiliasi | Notifikasi kejadian di produksi |
Bagaimana cara kerja webhook dari awal sampai akhir?
Satu webhook melewati lima langkah: kejadian, pengiriman, pemeriksaan, tanda terima, lalu pemrosesan.

- Kejadian. Sesuatu terjadi di sistem pengirim, misalnya pembayaran berhasil.
- Kurir berangkat. Pengirim membuat payload JSON, menandatanganinya, lalu mengirim POST ke URL Anda.
- Cek di pintu. Server Anda memeriksa tanda tangan dan waktu kirim sebelum mempercayai isinya.
- Tanda terima. Server Anda membalas status 2xx secepat mungkin.
- Buka paket. Pekerjaan berat, seperti menandai pesanan lunas dan mengirim email, dikerjakan di antrean di belakang.
Kenapa harus membalas cepat?
Pengirim hanya menunggu sebentar, lalu menganggap kiriman gagal. Batasnya berbeda di tiap layanan: ada platform yang memutus koneksi bila tidak ada balasan 2xx dalam 10 detik, sementara spesifikasi Standard Webhooks menyarankan batas waktu 15 sampai 30 detik. Karena itu dokumentasi resmi berbagai penyedia memberi saran yang sama: balas 2xx dulu, baru kerjakan logika yang lama lewat antrean.
Apa yang terjadi kalau server Anda sedang mati?
Pengirim akan mencoba lagi dengan jeda yang makin panjang, mirip kurir yang kembali besok saat rumah kosong. Contoh jadwal di spesifikasi Standard Webhooks dimulai dari langsung, 5 detik, 5 menit, 30 menit, lalu terus memanjang sampai 24 jam. Ada juga penyedia yang mencoba ulang sampai tiga hari. Akibatnya penting untuk dipahami: kabar yang sama bisa tiba lebih dari sekali.
Apa yang sering disalahpahami tentang webhook?
Ada lima anggapan keliru yang paling sering kami temui, dan semuanya wajar terjadi pada pemula.
- "Webhook itu teknologi khusus." Bukan. Webhook hanyalah HTTP POST biasa. Yang berbeda cuma arahnya.
- "Webhook pasti datang tepat satu kali." Tidak. Karena ada percobaan ulang, kiriman yang sama bisa datang dua kali. Urutannya pun tidak dijamin: kabar "faktur dibayar" bisa tiba sebelum "faktur dibuat".
- "URL yang sulit ditebak sudah cukup aman." Belum. URL bisa bocor lewat log atau tangkapan layar. Siapa pun yang tahu URL-nya bisa mengirim kabar palsu "pembayaran lunas" kalau Anda tidak memeriksa tanda tangan.
- "Webhook sama dengan WebSocket." Berbeda. WebSocket adalah sambungan yang terus terbuka, biasanya ke browser. Webhook adalah satu request antar-server yang langsung selesai.
- "Kalau sudah pakai webhook, polling tidak perlu lagi." Tidak selalu. Polling tetap berguna sebagai cadangan, misalnya mengecek ulang pesanan yang statusnya menggantung terlalu lama.
Bagaimana cara mengamankan webhook?
Webhook aman bila server Anda melakukan empat pemeriksaan: tanda tangan, waktu kirim, ID pesan, dan balasan cepat.

Tanda tangan: segel paket
Tanda tangan webhook dibuat dengan HMAC, yaitu hash yang dihitung dari isi pesan dan sebuah kunci rahasia yang hanya diketahui pengirim dan Anda. Server Anda menghitung ulang hash itu dari body yang diterima. Kalau hasilnya sama dengan yang ada di header, pesan itu asli dan isinya tidak diubah di jalan. Hitung dari body mentah, bukan dari JSON yang sudah di-parse lalu disusun ulang, karena satu spasi yang berbeda saja mengubah hasilnya.
Waktu kirim: tanggal di resi
Timestamp ikut ditandatangani supaya penyerang tidak bisa merekam kiriman asli lalu memutarnya ulang minggu depan. Serangan ini disebut replay. Server Anda cukup menolak pesan yang umurnya melewati toleransi. Lima menit adalah nilai bawaan yang umum dipakai pustaka resmi.
ID pesan: nomor resi
Setiap kiriman membawa ID unik, dan percobaan ulang memakai ID yang sama. Simpan ID yang sudah diproses, lalu lewati bila muncul lagi. Dengan begitu pesanan tidak ditandai lunas dua kali dan pembeli tidak menerima dua email.
Contoh kode verifikasi
Fungsi Python berikut menjalankan tiga pemeriksaan pertama memakai pustaka bawaan. Formatnya mengikuti spesifikasi Standard Webhooks: header webhook-id, webhook-timestamp, dan webhook-signature, dengan isi yang ditandatangani berbentuk id.timestamp.body. Kami menguji hasilnya terhadap pustaka resmi standardwebhooks dan tanda tangannya cocok.
import base64, hashlib, hmac, time
TOLERANSI = 5 * 60 # detik; pesan lebih tua dari ini ditolak
sudah_diproses = set() # di produksi: tabel database atau Redis
def verifikasi(secret: str, headers: dict, body: bytes) -> str:
msg_id = headers["webhook-id"]
ts = headers["webhook-timestamp"]
# 1) Tolak kiriman yang terlalu lama (mencegah replay)
if abs(time.time() - int(ts)) > TOLERANSI:
return "TOLAK: timestamp kedaluwarsa"
# 2) Hitung ulang tanda tangan dari body MENTAH, lalu bandingkan
kunci = base64.b64decode(secret.removeprefix("whsec_"))
isi = msg_id.encode() + b"." + ts.encode() + b"." + body
harapan = base64.b64encode(hmac.new(kunci, isi, hashlib.sha256).digest()).decode()
kiriman = [s.split(",", 1)[1] for s in headers["webhook-signature"].split() if s.startswith("v1,")]
if not any(hmac.compare_digest(harapan, s) for s in kiriman):
return "TOLAK: tanda tangan tidak cocok"
# 3) Abaikan kiriman ganda (idempoten)
if msg_id in sudah_diproses:
return "OK: duplikat, dilewati"
sudah_diproses.add(msg_id)
return "OK: diproses"
Kami mengirim lima skenario ke fungsi itu: kiriman asli, kiriman yang sama diulang, isi yang diubah di jalan, kiriman bertanggal kemarin, dan kiriman yang ditandatangani dengan kunci tebakan. Hasilnya:
asli -> OK: diproses
kirim ulang -> OK: duplikat, dilewati
isi diubah -> TOLAK: tanda tangan tidak cocok
kemarin -> TOLAK: timestamp kedaluwarsa
kunci palsu -> TOLAK: tanda tangan tidak cocok
Perhatikan hmac.compare_digest. Fungsi ini membandingkan dua nilai dalam waktu yang konstan, sehingga penyerang tidak bisa menebak tanda tangan dari selisih waktu respons. Satu catatan: nama header dan format tanda tangan berbeda di tiap penyedia, jadi selalu ikuti dokumentasi layanan yang Anda pakai, atau pakai pustaka resminya bila ada.
Di mana webhook dipakai di APIPedia?
Di APIPedia, webhook dipakai pada fitur Email Tracking, dan fitur ini sekaligus contoh bagus karena menyediakan dua cara sekaligus. Saat membuat pelacak buka-email, Anda bisa mengisi webhookUrl berupa URL HTTPS. Begitu email dibuka, APIPedia mengirim POST email.opened ke URL itu dengan tanda tangan HMAC-SHA256. Nilai webhookSecret hanya ditampilkan satu kali saat pelacak dibuat, jadi simpan langsung di environment server Anda.
Anda juga bisa memilih lewat webhookEvents: first untuk kabar saat email pertama kali dibuka, atau every untuk setiap kali dibuka. Kalau belum punya server publik, cara polling tetap tersedia lewat endpoint status pelacak. Pola yang sama berlaku untuk isi saldo: status pembayaran bisa dicek lewat endpoint status isi saldo.
Ada juga inbox webhook di fitur Email, yaitu kotak masuk yang menerima email lewat HTTP POST JSON ke sebuah URL rahasia. URL itu pun hanya tampil sekali, jadi perlakukan seperti API key.
Tips praktis sebelum webhook Anda masuk produksi
Tujuh kebiasaan berikut mencegah sebagian besar masalah webhook di produksi.
- Pakai HTTPS dengan sertifikat yang valid. Banyak pengirim menolak URL HTTP biasa.
- Simpan secret di environment variable, bukan di kode atau repositori. Ganti secara berkala atau segera bila dicurigai bocor.
- Balas 2xx dulu, proses kemudian. Masukkan pesan ke antrean dan kerjakan di belakang.
- Catat ID pesan di database dengan batasan unik supaya duplikat tertolak otomatis.
- Jangan bergantung pada urutan. Bila ragu, ambil data terbaru lewat API pengirim.
- Berlangganan event yang dibutuhkan saja supaya server tidak sibuk menerima kabar yang tidak dipakai.
- Siapkan cadangan. Jalankan pengecekan berkala untuk transaksi yang statusnya menggantung, karena webhook bisa saja tidak sampai.
Pertanyaan yang sering diajukan
Apakah webhook sama dengan API?
Webhook adalah bagian dari cara kerja API, bukan penggantinya. API biasa menjawab saat Anda bertanya. Webhook memberi kabar tanpa ditanya. Keduanya sering dipakai bersamaan: webhook memberi tahu ada perubahan, lalu aplikasi Anda memanggil API untuk mengambil detailnya.
Apakah saya perlu server sendiri untuk menerima webhook?
Ya, Anda perlu URL publik yang bisa diakses pengirim. Bentuknya tidak harus server besar. Fungsi serverless atau layanan otomasi tanpa kode juga bisa menerima webhook. Untuk percobaan di laptop, gunakan alat tunnel yang memberi URL HTTPS sementara.
Kenapa webhook saya datang dua kali?
Kemungkinan besar karena percobaan ulang. Bila server Anda terlambat membalas atau membalas dengan status selain 2xx, pengirim menganggap kiriman gagal lalu mengirimnya lagi. Solusinya bukan mematikan retry, melainkan mencatat ID pesan dan melewati yang sudah diproses.
Status HTTP apa yang harus dibalas?
Balas dengan status 2xx, misalnya 200 atau 204, untuk kiriman yang sah. Status lain, termasuk redirect 3xx, umumnya dianggap gagal dan memicu percobaan ulang. Untuk tanda tangan yang tidak cocok, balas 400 atau 401 dan jangan proses isinya.
Apakah webhook bisa dipakai tanpa coding?
Bisa. Banyak alat otomasi menyediakan URL penerima webhook siap pakai, lalu meneruskan isinya ke spreadsheet, chat, atau email. Namun untuk hal yang menyangkut uang, tetap pastikan alat tersebut memeriksa tanda tangan.
Karena secret webhook sama berharganya dengan kunci akses, baca juga kisah API key AI yang dicuri dalam kasus LLMjacking. Kalau Anda ingin agen AI ikut memakai data dan tool Indonesia, lihat panduan menghubungkan APIPedia ke Claude lewat MCP.
Sumber
Topik: #webhook #api #explainer #keamanan api #hmac #idempotency
${c.about}
Tim APIPedia — Tim Engineering APIPedia
Tim engineering di balik APIPedia yang membangun dan memelihara API data Indonesia - ongkir, OCR KTP, data wilayah, BMKG, hingga server MCP - dan menulis panduan integrasinya dari pengalaman langsung.