Dokumentasi Developer

Webhooks

Webhook adalah notifikasi bertanda tangan yang memberi tahu bahwa catatan berubah. Ambil konten terbaru dari REST API.

Event webhook

EventTerpicu saat
note.endedSesi rekaman selesai dan transkrip finalnya sudah bisa diambil. Terpicu sekali per sesi rekaman โ€” catatan dengan beberapa sesi akan memicunya beberapa kali.
note.summary.generatedRingkasan selesai dibuat dan sudah bisa diambil.
note.updatedField yang terlihat dari luar (judul, konten) berubah setelah catatan berakhir. Di-debounce โ€” rentetan suntingan cepat digabung menjadi satu event.
note.deletedCatatan dihapus (data.reason: "deleted") atau keluar dari cakupan visibilitas kredensial Anda (data.reason: "access_lost").

Ada juga dua service event: endpoint.verification (dikirim saat endpoint dibuat dan saat URL-nya berubah; balas dengan 2xx untuk mengaktifkan endpoint) dan endpoint.test (dikirim saat Anda menekan "Kirim tes" di console atau memanggil API tes).

Isi request

Webhook adalah notifikasi ringan: isinya hanya identifier dan status, tidak pernah konten transkrip atau ringkasan. Ambil kontennya dari REST API menggunakan note_id.

JSON
{
  "event_id": "5f8c0a5e-...",
  "event_type": "note.ended",
  "occurred_at": "2026-08-12T05:20:00Z",
  "data": {
    "note_id": "note_abc123",
    "recording_session_id": "rec_456",
    "revision": 7,
    "transcript_status": "ready",
    "summary_status": "pending"
  }
}

Verifikasi signature

Setiap pengiriman ditandatangani sesuai spesifikasi Standard Webhooks dengan secret whsec_... yang diterbitkan saat endpoint dibuat:

HTTP
POST /webhooks/alt HTTP/1.1
Content-Type: application/json
webhook-id: 5f8c0a5e-...
webhook-timestamp: 1765515600
webhook-signature: v1,K5oZfzN95Z9UVu1EsPQmSmZQGGVfCM0jaZ0lPI4dvLU=
signature
signed_content = "{webhook-id}.{webhook-timestamp}.{raw request body}"
signature     = base64( HMAC-SHA256( base64url_decode(secret_after_whsec_), signed_content ) )
  • Verifikasi terhadap raw request body โ€” jangan serialisasi ulang JSON-nya.
  • Bandingkan signature dengan perbandingan constant-time.
  • Tolak timestamp yang sudah basi (kami menyarankan toleransi ยฑ5 menit) untuk mencegah replay attack.
  • Tolak request yang signature-nya tidak cocok dengan 4xx. Contoh kode receiver yang berfungsi: Mulai Cepat langkah 4.

Kegagalan pengiriman dan retry

  • Balas dengan 2xx dalam 10 detik. Selain itu dihitung sebagai kegagalan. Balas dulu, proses secara asinkron.
  • Pengiriman yang gagal diulang dengan backoff yang makin panjang (30 detik โ†’ 5 menit โ†’ 30 menit โ†’ 2 jam โ†’ 12 jam โ†’ 12 jam, maksimal 7 percobaan).
  • Endpoint yang gagal berkali-kali berturut-turut otomatis dinonaktifkan.
  • Redirect tidak diikuti; URL webhook harus merespons langsung lewat HTTPS.

Tangani event duplikat

Pengiriman bersifat at-least-once: event yang sama bisa datang lebih dari sekali (retry, kirim ulang dari console). Simpan catatan berumur pendek berisi event_id yang sudah diproses dan lewati duplikatnya.

Tangani event yang tidak berurutan

Event bisa datang tidak berurutan (retry, pengiriman paralel). Jangan berasumsi event yang datang terakhir adalah kondisi terbaru. Setiap perubahan yang terlihat dari luar menaikkan revision catatan (ditetapkan server, monoton naik): simpan revision terakhir yang sudah Anda terapkan untuk tiap catatan dan abaikan apa pun dengan revision yang sama atau lebih rendah. Kalau ragu, ambil ulang catatan itu dari REST API โ€” API selalu mengembalikan revision terkini.

Periksa perubahan yang terlewat

  • Webhook bisa terlewat (downtime lebih lama dari jendela retry, endpoint dinonaktifkan). Panggil GET /v1/notes?updated_after=<last sync> secara berkala untuk menyusul.
  • note.deleted dengan reason: "access_lost" berarti catatan tersebut keluar dari cakupan kredensial Anda (misalnya catatan pribadi dipindahkan ke teamspace). Perlakukan persis seperti penghapusan: hapus atau blokir akses ke salinan yang Anda simpan.
  • Polling inkremental saja tidak bisa mendeteksi penghapusan atau hilangnya akses. Ambil daftar seluruh catatan secara berkala (pakai include_deleted=true untuk melihat tombstone): setiap ID catatan yang Anda simpan tetapi tidak lagi muncul di daftar berarti sudah dihapus atau keluar dari cakupan Anda.