> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Entitas Didit: Event Pengguna & Bisnis

> Webhook real-time Didit untuk perubahan entitas Pengguna dan Bisnis: transisi status, pembaruan profil, payload, penandatanganan, coba lagi.



Entity Webhooks Prompt
        Salin prompt ke papan klip



      
      

\<pre>

\````# Goal — subscribe to entity-level webhooks and apply changes to my database

Entity webhooks fire whenever a User or Business entity changes its status or its profile data. Use them to keep your local mirror of Didit entities in sync.

\## Entity-level event catalog

\| `webhook_type` | Trigger |
\|---|---|
\| `user.status.updated` | User entity status changed (`ACTIVE` / `FLAGGED` / `BLOCKED`). Payload includes `previous_status`. |
\| `user.data.updated` | User entity profile / counters / metadata changed. Includes `changed_fields` and a `changes` map of `{previous, current}`. |
\| `business.status.updated` | Business entity status changed. Payload includes `previous_status`. |
\| `business.data.updated` | Business entity profile or aggregates changed. Includes `changed_fields` and `changes`. |

\`activity.created` is accepted in `subscribed_events` and by the Try Webhook tester, but Didit does not deliver it for live traffic. Do not build on it.

Session-level events (`status.updated`, `data.updated`) and transaction events (`transaction.created`, `transaction.status.updated`) live alongside but are separate — see /integration/webhooks for the full catalog.

\## Register a destination

\```bash
curl -X POST https://verification.didit.me/v3/webhook/destinations/ \
-H "x-api-key: $DIDIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Entity sync",
"url": "https://yourapp.com/webhooks/didit",
"webhook_version": "v3",
"subscribed_events": [
  "user.status.updated",
  "user.data.updated",
  "business.status.updated",
  "business.data.updated"
]
}'
\```

Persist the returned destination `secret_shared_key` — that's the HMAC signing key.

\## Payload shape

Entity payloads are flat: there is no `data` wrapper and no `event` key. Read `webhook_type`.

\```json
\{
"event_id": "7f3c2c1e-6a1d-4c36-9d8e-0d3b5f4e2a10",
"webhook_type": "user.status.updated",
"timestamp": 1776333600,
"created_at": 1776333594,
"application_id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"environment": "live",
"vendor_user_id": "9c7d2a30-...",
"vendor_data": "user-42",
"status": "BLOCKED",
"previous_status": "ACTIVE"
}
\```

\`business.*` events use `vendor_business_id` instead of `vendor_user_id`.
\`user.data.updated` / `business.data.updated` payloads keep `status` and add `changed_fields` (array) and `changes` (`{field: {previous, current}}`). Use these to apply minimal diffs to your DB.

\## Verify the signature

Verify X-Signature-V2 (recommended): HMAC-SHA256 of the canonical JSON body with the destination `secret_shared_key`, then a constant-time compare, and reject an X-Timestamp older than 300 seconds. See /integration/webhooks for the signature headers and code samples. Respond `2xx` within **5 seconds**. On a 5xx, 404, timeout or connection failure Didit retries up to 2 times (about 1 minute, then about 4 minutes later); see /integration/webhooks#retry-policy.

\## Idempotency

Every delivery carries a unique `event_id`. De-dupe on it. Fallback compound key: `(application_id, webhook_type, vendor_data, timestamp)`.

\## Failure modes

\- Wrong `webhook_version` (e.g. v2) → singular fields and older event names; v3 is required for entity events plural-array contract.
\- Slow handler → retried; budget < 5s; do heavy work async.
\- Unknown event type → log and 200; new event types may be added.

\## Apply-decision pseudocode

\```ts
switch (event.webhook_type) {
case "user.status.updated":
await db.users.update({ vendor_data: event.vendor_data }, { status: event.status });
break;
case "user.data.updated":
for (const field of event.changed_fields) {
  await db.users.update({ vendor_data: event.vendor_data }, { [field]: event.changes[field].current });
}
break;
case "business.status.updated":
case "business.data.updated": /* same shape, businesses table, keyed by vendor_business_id */ break;
}
\```

\## Sources of truth

\- /integration/webhooks — destinations, signatures, retries, full event catalog
\- /management-api/webhook/create-destination — endpoint schema
\- /entities/users/operations — operations that emit user events
\- /entities/businesses/operations — operations that emit business events
\- /integration/integration-prompt — canonical end-to-end prompt````

\</pre>



      
      

Tempel ke

Setiap perubahan pada status atau data profil entitas User atau Business mengirimkan webhook agar sistem Anda dapat merespons secara real time.
Gunakan webhook entitas untuk menyinkronkan data profil, meneruskan pemblokiran ke sistem lain, atau memicu alur kepatuhan hilir.## Katalog event| Event | Pemicu |
| - | - |
| `user.status.updated` | Status entitas User berubah (`ACTIVE` ↔ `FLAGGED` ↔ `BLOCKED`) |
| `user.data.updated` | Kolom profil entitas User berubah (nama, tanggal lahir, foto, penghitung agregat, metadata) |
| `business.status.updated` | Status entitas Business berubah |
| `business.data.updated` | Kolom profil entitas Business berubah (nama legal, nomor registrasi, negara, penghitung) |> [!NOTE]
>
> `activity.created` diterima di `subscribed_events` dan tercakup oleh penguji **Try Webhook**, tetapi Didit saat ini tidak mengirimkannya untuk trafik produksi.
> Jangan membangun pencerminan linimasa berdasarkan event ini.Didit juga mengirimkan event sesi, transaksi, dan sesi bisnis yang merujuk ke kolom entitas. Lihat:- [Webhook KYB](https://docs.didit.me/id/business-verification/webhooks.md): event sesi bisnis
- [Webhook Pemantauan Transaksi](https://docs.didit.me/id/transaction-monitoring/webhooks.md): event transaksi
- [Referensi webhook](https://docs.didit.me/id/integration/webhooks.md): verifikasi tanda tangan, percobaan ulang, dan tujuan## Bentuk payloadWebhook entitas bersifat datar: tidak ada pembungkus `data` dan tidak ada kunci `event`.
Baca `webhook_type` untuk merutekan event.```json theme={null}
{
  "event_id": "7f3c2c1e-6a1d-4c36-9d8e-0d3b5f4e2a10",
  "webhook_type": "user.status.updated",
  "timestamp": 1776333600,
  "created_at": 1776333594,
  "application_id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
  "environment": "live",
  "vendor_user_id": "9c7d2a30-2f98-4d4f-9d2d-1a7c4b1e5b6a",
  "vendor_data": "user-42",
  "status": "BLOCKED",
  "previous_status": "ACTIVE"
}
```| Kolom | Deskripsi |
| - | - |
| `vendor_user_id` / `vendor_business_id` | Pengenal Didit untuk entitas. Event `business.*` menggunakan `vendor_business_id`. |
| `vendor_data` | Pengenal Anda untuk entitas. |
| `status` | `ACTIVE`, `FLAGGED` atau `BLOCKED`. |
| `previous_status` | Hanya pada `*.status.updated`. |
| `changed_fields` dan `changes` | Hanya pada `*.data.updated`. |
| `created_at` | Detik Unix saat entitas terakhir diperbarui. |
| `timestamp` | Detik Unix saat Didit mengirimkan webhook. |### `user.status.updated` / `business.status.updated`Dikirim pada setiap perubahan status.
Payload memuat `status` dan `previous_status`.
Payload tidak menjelaskan alasan perubahan status: buka entitas di konsol jika Anda memerlukan penyebabnya.### `user.data.updated` / `business.data.updated`Dikirim ketika kolom profil berubah.
`changed_fields` mencantumkan kolom yang berubah, dan `changes` berisi nilai `previous` dan `current` untuk setiap kolom.```json theme={null}
{
  "event_id": "5d1e8f9a-0c32-4b6a-a7b6-2b9d6f0a3c41",
  "webhook_type": "user.data.updated",
  "timestamp": 1776333700,
  "created_at": 1776333694,
  "application_id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
  "environment": "live",
  "vendor_user_id": "9c7d2a30-2f98-4d4f-9d2d-1a7c4b1e5b6a",
  "vendor_data": "user-42",
  "status": "ACTIVE",
  "changed_fields": ["full_name", "session_count"],
  "changes": {
    "full_name": { "previous": null, "current": "John Doe" },
    "session_count": { "previous": 2, "current": 3 }
  }
}
```Kolom yang dapat muncul di `changed_fields` adalah:- User: `vendor_data`, `display_name`, `full_name`, `date_of_birth`, `metadata`, `portrait_image`, `issuing_states`, `approved_emails`, `approved_phones`, `features`, `session_count`, `approved_count`, `declined_count`, `in_review_count`, `first_session_at`, `last_session_at`.
- Business: `vendor_data`, `display_name`, `metadata`, `legal_name`, `registration_number`, `country_code`, `session_count`, `approved_count`, `declined_count`, `in_review_count`, `features`, `first_session_at`, `last_session_at`.Gunakan `changed_fields` dan `changes` untuk menyinkronkan hanya kolom yang berubah.## Pengiriman, percobaan ulang, dan penandatangananSemua webhook entitas mengikuti kontrak pengiriman standar:- **Ditandatangani** dengan HMAC-SHA256 di header `X-Signature-V2` (direkomendasikan), menggunakan `secret_shared_key` dari tujuan. `X-Signature` dan `X-Signature-Simple` yang sudah tidak digunakan lagi juga dikirim, bersama `X-Timestamp`.
- **Dicoba lagi** hingga 2 kali, setelah sekitar 1 menit dan sekitar 4 menit, ketika endpoint Anda merespons 5xx atau 404, mengalami timeout, atau gagal terhubung. [Referensi webhook](https://docs.didit.me/id/integration/webhooks.md#kebijakan-coba-lagi) memuat kebijakan lengkapnya.
- **Idempoten**: setiap webhook memiliki `event_id` yang unik dalam payload; lakukan deduplikasi di sisi Anda.Lihat [Referensi webhook](https://docs.didit.me/id/integration/webhooks.md) untuk pengaturan tujuan dan contoh kode verifikasi tanda tangan.## BerlanggananBerlangganan event entitas di tujuan webhook melalui Management API atau Business Console:```bash theme={null}
curl -X POST https://verification.didit.me/v3/webhook/destinations/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Entity sync",
    "url": "https://yourapp.com/webhooks/didit",
    "subscribed_events": [
      "user.status.updated",
      "user.data.updated",
      "business.status.updated",
      "business.data.updated"
    ]
  }'
```## Langkah selanjutnya> [card] [Referensi webhook](https://docs.didit.me/id/integration/webhooks.md)
>
> Tujuan, tanda tangan, percobaan ulang, dan verifikasi.> [card] [Buat tujuan](https://docs.didit.me/id/management-api/webhook/create-destination.md)
>
> Daftarkan endpoint webhook baru.> [card] [Operasi pengguna](https://docs.didit.me/id/entities/users/operations.md)
>
> Perubahan yang memicu webhook pengguna.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.