Webhook endpoints are part of the API, so they need a Premium or Pro plan — the same requirement as
POST /oauth/token. See Plans.Register an endpoint
url (required) and description (optional). Anything else is rejected. The call answers 201:
Where the signing secret lives
YourwebhookSecret is a 256-bit value shown in the app under Settings → Developers, next to your Client Id and Client Secret. The same value comes back from an authenticated GET /users/me.
To rotate it, use Refresh in that screen or call:
Events
Twelve events cover the lifecycle.started fires when a step begins, successful when it clears, failed when it is definitively lost.
Payload
Every payload has the same two-key shape: atype and a data object.
_externalUserId and _metadata are copied from the link that produced the verification. If the link carried no externalUserId, the field arrives as an empty string; with no metadata, _metadata is {}.
Geolocation on terminal events
verification.successful and verification.failed also carry data.geolocation, when a location was captured. Intermediate events never do — at verification.started the capture has not happened yet.
null, so treat every field as optional.
Verify the signature
VU signs the payload with HMAC-SHA256 over the exact request body, keyed with your accountwebhookSecret, and sends the hex digest in the X-Signature-SHA256 header.
Verify against the raw body. Parsing and re-serializing the JSON first will change the bytes and break the comparison.
Delivery and retries
That budget is far too small to absorb a slow handler, so:- Answer immediately, then process asynchronously. Acknowledge inside a few hundred milliseconds and push the work to a queue.
- Be idempotent. The same event can arrive more than once, and
verification.startedis re-emitted on the adaptive branch under some retry paths. - Do not treat webhooks as the only source of truth. Reconcile with
GET /verifications/{id}/status?linkId={linkId}for anything that matters commercially — a verification whose webhook was lost still has a correct status on the API. - Read the result before it expires. Past the verification’s
expiresAt,GET /verifications/{id}answers410. See Plans for how that window is calculated.
Manage endpoints
PATCH accepts url and description. Every route requires the same Bearer token as the rest of the API.
The
/webhook-endpoints routes live on the same base URL as POST /links: https://api.identity.vu-one.com/api/v1. There is no separate host. If they answer 404 with given resource is not implemented, the route did not match: check the base URL, path, and method on the Errors page.Next steps
- Read extracted verification data in the KYC Results guide.
- Understand how liveness events map to webhook types in the Liveness guide.
- Review error codes if webhook registration fails on the Errors page.