Register your KYC URL
Merchant KYC events go to a third webhook URL,kyc_url. It is separate from collection_url and payout_url.
Set kyc_url when you register your webhook URLs:
kyc_url with an update:
webhook:write scope. The URL must be HTTPS and must resolve on the public internet.
kyc_url is optional. If you omit it, Blaaiz records the session result and does not deliver it. Read the result from GET a session instead.
Merchant KYC webhooks are signed with the same
signing_secret as your
collection and payout webhooks. You need no second secret.Events
Blaaiz sends no webhook for a session that you cancel, and no webhook for a verdict that arrives after a session is already terminal.
Payload
The body holds two fields:event and data. The timestamp travels in the x-blaaiz-timestamp header, not in the body.
A rejected session looks like this:
Headers
Verify the signature
Blaaiz builds the signature over the timestamp, a full stop, and the request body:Replay window
The signature does not expire on its own. Comparex-blaaiz-timestamp against your own clock and reject anything older than 5 minutes. This stops an attacker from replaying a request that they captured earlier.
Keep your server clock in sync with NTP. A drifting clock rejects valid webhooks.
Delivery and retries
Reply with any HTTP 2xx status to confirm the delivery. Blaaiz retries every other outcome, including a timeout and a connection error.
After the fifth attempt fails, Blaaiz marks the event as failed and stops. Read the session with GET a session to recover the result.
Merchant KYC webhooks use their own retry schedule. It is shorter than the
schedule for collection and payout events.
Handle duplicates
Blaaiz delivers each event at least once, so the same event can arrive twice. Make your handler idempotent. Deduplicate ondata.session_id together with event. A session sends merchant.kyc.session.completed one time, so a second delivery of that pair is a duplicate.
Best practice
- Verify the signature before you read the payload.
- Check the timestamp against your replay window.
- Reply with 2xx within 30 seconds.
- Do the slow work in a background job.
- Treat a repeated
session_idandeventpair as a duplicate.

