Skip to main content
Get notified the moment a verification, screening, or message event happens — instead of polling. Dojah POSTs each event to a URL you register, and signs it so you can confirm it’s genuine.

How webhooks work

You subscribe a URL to a service. When a matching event occurs, Dojah sends an HTTP POST with a JSON body to that URL. Respond 200 to acknowledge receipt.

Subscribe to a service

Register a callback URL against a service with POST /api/v1/webhook/subscribe. You can also fetch and delete subscriptions.
cURL
Documented services include kyc_widget, address, sms, and AML Monitoring, spanning verification, fraud, AML, and messaging events.

Event payload

Events arrive as JSON with the event fields at the top level — unlike REST responses, webhook payloads don’t use the entity wrapper. Always look the event up against your own records using its reference before acting on it.

KYC widget (EasyOnboard) event

Subscribers to the kyc_widget service receive an event when a hosted flow session ends. Its shape follows the flow you built, so expect these three layers:
  • Top level — the summary: reference_id, verification_status, the overall status, the ID captured (id_type, value), and links to the selfie, ID images, and signed PDF.
  • data — one key per step the user went through (user_data, government_data, id, selfie, address, and so on), each with its own status, message, and data.
  • metadata — context about the session, including geo-IP details and anything you passed in when launching the flow.
Match the event to your user with reference_id, which is the value you supplied when you launched the flow.
The file URLs above are truncated and expire. Real payloads carry full pre-signed links that stop working after about an hour — download the files as soon as the event arrives. See File links & expiry.

Verification status values

The verification_status field describes where the session sits in its lifecycle. Only Completed, Failed, and Abandoned are terminal — the other two mean another event is still coming.
Completed means finished, not passed. It only tells you the session ran to the end. Check the top-level status and each step’s status inside data before granting access — in the sample above the session is Completed while address.status and aml.status are both false.
The same values apply across Dojah verifications, not just the widget — see Verification statuses.

Verify events are from Dojah

Before trusting a payload, confirm it came from Dojah using any of these:
1

IP allowlisting

Accept webhook calls only from Dojah’s IP: 135.119.89.106.
2

Signature with payload and secret key (x-dojah-signature)

HMAC SHA256 of the JSON body, keyed with your secret key. Recompute and compare.
3

Signature with secret key only (x-dojah-signature-v2)

SHA256 hash of your secret key alone. Recompute and compare.
Every delivery carries both signature headers, so pick whichever fits your stack — you don’t need to check both.

Signature validation with payload and secret key

Events from Dojah carry the x-dojah-signature header. Its value is a HMAC SHA256 signature of the event payload, signed with your secret key. Verify it before processing the event:
Hash the payload exactly as received. Re-serialising the JSON can reorder keys or change spacing, which produces a different signature, so hash the raw request body. Compare the result with a constant-time function (timingSafeEqual, hmac.compare_digest, hash_equals, hmac.Equal, secure_compare, MessageDigest.isEqual) rather than ==, and reject mismatches with 401.

Signature validation with secret key only

Events from Dojah also carry the x-dojah-signature-v2 header. Its value is a SHA256 hash of your secret key — the payload isn’t part of the hash, so this check works even if you can’t access the raw request body. Verify it before processing the event:
Always verify. Treat unverified webhook calls as untrusted — never grant access or update records from a payload you haven’t authenticated.
File links expire. Any file URLs inside a webhook payload are temporary — see File links & expiry.