Di halaman ini
Webhook
Cloudin POST event ke URL kamu setiap email masuk (atau event lain yang kamu subscribe). Delivery dikirim near-real-time — biasanya beberapa detik setelah email masuk, bukan polling lambat. Cocok buat bot yang nungguin OTP.
Setup
- Buka Layanan → Webhook → Tambah webhook
- Input URL endpoint kamu
- Pilih event types
- Secret muncul sekali — catat untuk verify HMAC
Event types
message.received— email baru masukmessage.deleted— email dihapusaddress.created— address baru di-generatedomain.verified— DNS verify OKdomain.lost— DNS verify gagal 3xservice.suspended/service.reactivated— billing state
Payload format
{
"id": "evt_01HXY...",
"type": "message.received",
"created_at": "2026-05-28T07:00:00Z",
"data": {
"message": {
"id": "msg_01HXY...",
"address": "abc@inbox.brandkamu.id",
"from": "sender@example.com",
"from_name": "OpenAI",
"subject": "Verifikasi Email",
"preview": "Klik link...",
"otp_code": "918203"
}
}
}
otp_code otomatis di-ekstrak dari email verifikasi (angka maupun alfanumerik, mis. 918203 atau G7K2PX). null kalau nggak ada kode terdeteksi.
Filter pengiriman (per-webhook)
Biar bot cuma di-ping untuk email yang relevan, tiap webhook bisa difilter:
- Cuma OTP (
filterOtpOnly: true) — webhook hanya fire kalau email punyaotp_code. Cocok buat automasi signup yang cuma butuh kode verifikasi. - Dari domain tertentu (
filterFromDomain: "openai.com") — webhook hanya fire kalau domain pengirim mengandung nilai ini. Kosong = semua pengirim.
filterOtpOnly / filterFromDomain saat create/update webhook via API.
Verify signature (HMAC SHA256)
Setiap delivery dikirim dengan header:
X-Cloudin-Timestamp— Unix timestampX-Cloudin-Signature—sha256=atas${timestamp}.${rawBody}X-Cloudin-Event— tipe event (mis.message.received)X-Cloudin-Delivery— ID delivery unik (dedup / korelasi)
const crypto = require('crypto');
function verifyWebhook(rawBody, timestamp, signature, secret) {
// Reject kalau >5 menit (anti-replay)
if (Math.abs(Date.now()/1000 - parseInt(timestamp)) > 300) return false;
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(${timestamp}.${rawBody})
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Retry policy
Webhook delivery retry exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | instant |
| 2 | 1 menit |
| 3 | 5 menit |
| 4 | 30 menit |
| 5 | 6 jam |
failed dan tidak di-retry lagi (per event). failureCount webhook ikut naik. Webhook tidak di-disable otomatis — email baru tetap men-generate delivery baru. Pastikan endpoint kamu tetap sehat — pantau delivery dari Layanan → Webhook.
Timeout per delivery: 10 detik. Status sukses: HTTP 2xx-3xx (kecuali 307/308).
Kelola webhook via API
Endpoint webhook CRUD memakai Bearer JWT (dashboard) — bukan API key. :id di path create/list = ID layanan.
| Method | Path | Fungsi |
|---|---|---|
GET | /v1/services/:id/webhooks | List webhook layanan |
POST | /v1/services/:id/webhooks | Buat webhook (secret muncul sekali di response) |
PATCH | /v1/webhooks/:id | Update (url, events, enabled, allowedIps, filterOtpOnly, filterFromDomain) |
DELETE | /v1/webhooks/:id | Hapus webhook |
GET | /v1/webhooks/:id/deliveries | Riwayat delivery (query: status, from, to, cursor, limit) |
GET | /v1/webhooks/:id/stats | Statistik 24 jam / success rate / avg latency |
POST | /v1/webhook-deliveries/:id/retry | Re-queue satu delivery untuk retry |
{
"url": "https://kamu.id/webhook",
"events": ["message.received"],
"enabled": true,
"filterOtpOnly": false,
"filterFromDomain": null,
"allowedIps": []
}
events— minimal 1, dari daftar event di atas.allowedIps— opsional, maksimal 10 IP; kalau diisi, hanya IP itu yang diterima worker sebagai sumber verifikasi. URL private/loopback ditolak (BAD_REQUEST).- Melewati batas 5 webhook per layanan →
429 QUOTA_EXCEEDED. - Retry delivery yang sudah
success→409 CONFLICT.