# Getting verification results with webhooks

Source: https://help.didit.me/integration/webhooks-basics
Updated: 2026-10-12

Didit does not email you when a verification changes status. Set up a webhook so your backend hears about it at once, and verify the signature first.

A webhook is an HTTP request Didit sends to your URL when something changes. Add an
endpoint under **Developers → Webhooks**, subscribe to the events you want - there
is **no wildcard**, list every one - save the signing secret, and verify the
signature before you process anything.

[Video: Webhooks overview - Didit Academy](https://www.youtube.com/watch?v=fX03-WEu_EI&t=192)

Didit doesn't send you an email when a session moves to **In review** or **Declined**. To find out the moment a status changes, without refreshing the console, set up a webhook - a URL on your server that Didit sends the update to automatically.

Webhooks are the **recommended** integration pattern. Polling the decision endpoint works as a fallback, but it's slower, costs more requests, and misses events that are only ever delivered by webhook - data edits made by a reviewer, transaction status changes, and entity-level changes.

## Setting one up

1. **Go to Developers, then Webhooks**

   In the Business Console, open the application (and the environment, Live or Sandbox) you want to receive events for, then go to **Developers → Webhooks**.

2. **Add an endpoint**

   Press **Add endpoint**. Enter your endpoint's public HTTPS **Endpoint URL** and a **Name**, pick the events you want to receive (session status changes at minimum), keep the recommended webhook version (v3) unless you're maintaining an older integration, and confirm on the review step.

3. **Save the signing secret**

   Each endpoint has its own signing secret, shown masked on the endpoint's page. Press **Reveal** and confirm it's you to see it; it hides again within 60 seconds. Save it in your server's configuration - your server uses it to confirm a request really came from Didit rather than an impersonator. If **Reveal** is greyed out for you, contact support. Full verification steps: [Signature verification](https://docs.didit.me/integration/webhooks#signature-verification).

4. **Test it**

   Use **Send test event** to send a fully-formed, signed test event - approved, declined, in review, KYB, entity, and transaction scenarios - to your endpoint. You can validate your integration this way without running an actual verification.

![The Webhooks page in the Didit console listing endpoints with their events and recent delivery success](https://help.didit.me/screenshots/webhooks-light.webp)

*Each endpoint has its own subscribed events, signing secret and delivery log.*

## The events you can subscribe to

There is **no wildcard** - list every event family you want. Spreading them across several endpoints is fine and often cleaner.

| Event | Fires when |
|---|---|
| `status.updated` | A KYC or KYB session's status changes. The one you almost certainly want |
| `data.updated` | Verification data is edited after creation - a reviewer correcting a field |
| `user.status.updated` | A consolidated user moves between ACTIVE, FLAGGED and BLOCKED |
| `user.data.updated` | A consolidated user's profile, counters or identifiers change |
| `business.status.updated` | A consolidated business changes status |
| `business.data.updated` | A consolidated business's data changes |
| `transaction.created` | A transaction is created and its initial verdict is ready |
| `transaction.status.updated` | A transaction's status changes afterwards |
| `travel_rule.status.updated` | A Travel Rule exchange's status changes |

> **Note:** There is no `session.status.updated` or `kyc.completed`. If you subscribed to a
> name that isn't in this list, you'll receive nothing - and it will look exactly
> like a delivery failure. Check the name first.

## What your endpoint should do

- **Verify the signature before anything else.** HMAC the **raw** request body - never a re-serialised version of the parsed JSON, because re-stringifying changes the bytes and the signature won't match. Use a constant-time comparison.
- **Return a 2xx fast.** Didit waits 5 seconds for an answer. Do heavy work asynchronously, after you've responded.
- **Be idempotent.** Key on the event id, or on session id + status + webhook type. Retries and duplicates happen.
- **Handle every status you care about**, including the ones that arrive long after onboarding - an approved session can later move to In review through [ongoing AML monitoring](https://help.didit.me/aml-screening/ongoing-monitoring).
- **HTTPS only.** Plain HTTP endpoints aren't supported.

## Retries

When your endpoint answers with a 5xx or a 404, Didit retries **twice**:

- First retry about 1 minute after the first attempt
- Second retry about 4 minutes after that

A delivery that times out (no answer within 5 seconds) or can't connect is not retried automatically. Every attempt is logged in the endpoint's **Deliveries** list, so you can see exactly what happened rather than guessing, and **Resend** on a delivery sends it again by hand. When a delivery still fails after its retries, your team gets an alert in the console.

> **Warning:** Two retries over five minutes is not a durable queue. If your endpoint is down for
> an hour, those events won't arrive on their own. Resend them from the Deliveries
> list, or reconcile on start-up by polling the decision endpoint for sessions you
> have no terminal status for - webhooks are the fast path, not the only path.

## Behind a firewall or WAF

Didit delivers from the static IP **18.203.201.92** with a `DiditWebhook/2.0` user agent. If your edge blocks unknown clients - Cloudflare's default posture, for instance - allow that IP for the receiving hostname, or deliveries will fail before they reach your code.

## Don't have a backend yet?

You can still monitor results manually in the console's **User verifications** list while you build one out, or use a [no-code verification link](https://help.didit.me/integration/integration-options) in the meantime.

## Next steps

- When a webhook doesn't arrive: [when a webhook never arrives](https://help.didit.me/integration/webhook-troubleshooting)
- Understand what each status means once it arrives: [what each session status means](https://help.didit.me/verification-sessions/session-statuses)
- Full technical reference, including signature verification code samples: [Webhooks](https://docs.didit.me/integration/webhooks)
