DocumentationSign in

Webhooks

19 events, one envelope, a five-step retry schedule, and the endpoint routes — generated from the API's own catalogue.

The events

An endpoint subscribes to any of these 19 event types. GET /v1/developer/applications/{applicationId}/webhooks/events returns the same list from the running API.

Read from the API's webhook event catalogue, schema version 2.0

EventCategoryLabel
sign_in.completedhumanHuman signed in
connection.createdhumanHuman connected for the first time
oauth.authorization.completedhumanHuman authorization completed
consent.grantedhumanHuman consent granted
consent.revokedhumanHuman consent revoked
identity.assurance.increasedhumanHuman assurance increased
identity.assurance.decreasedhumanHuman assurance decreased
privacy.correction.appliedhumanHuman information you hold was corrected
identity.document.renewedhumanAn identity document you hold was renewed
identity.document.expiredhumanAn identity document you hold has expired
identity.document.withdrawnhumanAn identity document is no longer shared with you
identity.document.verification_revokedhumanA document’s verification was revoked
identity.claim.verification_revokedhumanA verified detail is no longer verified
identity.claim.verifiedhumanA detail you hold has been verified again
billing.budget.threshold_reachedbillingBudget threshold reached
billing.budget.exhaustedbillingBudget exhausted
billing.budget.resetbillingBudget period reset
billing.budget.action_appliedbillingBudget action applied
webhook.testsystemWebhook test

The human events are about a person and your application: a sign-in, a consent, a change to a document or claim you hold. The billing events are about your budget. webhook.test is what the test button sends.

The envelope

Every delivery body

id
The event id. Matches the unifyid-event-id header. Deduplicate on it: a retried delivery reuses it.
type
One of the event types above.
version2.0
The envelope version.
occurred_at
ISO 8601.
environment
sandbox or production. Route sandbox events away from production handlers.
application_id
Your application.
actor, subject
Who did it and who it is about, each { type, id } with the person named by your pairwise sub.
correlation_id
Ties the event to the request that caused it: correlation_ and 43 base64url characters, keyed per application. Deliveries caused by one request share it within your application; another application told about the same request receives a different value. It used to be the same for every application a request reached.
data
The event-specific payload. The consent events' data is on Revocation and webhooks.

Every delivery's headers

unifyid-event-id
The event id.
unifyid-event-type
The event type.
unifyid-timestamp
Unix seconds.
unifyid-signature
t=<timestamp>,v1=<hex>: HMAC-SHA256 over <timestamp>.<raw body> keyed with the endpoint's signing secret. Verification code is on Revocation and webhooks.
user-agent
UnifyID-Webhooks/1.0.

How a delivery behaves

  • Five seconds. A delivery that has not answered in five seconds is a failed attempt. Answer 2xx first and do the work afterwards.
  • Redirects are refused. Point the endpoint at its final URL.
  • Five retries, then dead. After a failed attempt the next one waits 1 min, 5 min, 30 min, 2 h, 12 h — about 14.6 h in all — and then the delivery is marked failed.
  • Most 4xx responses are permanent. A 4xx from you ends the delivery at once, except 408, 409, 425 and 429, which retry on the schedule like a 5xx or a timeout.
  • Your response body is never read. Only the status matters.

GET …/webhooks/deliveries/history lists deliveries, newest first, with ?endpointId= to narrow to one endpoint. Each carries a state — queued, retrying, delivered, failed or cancelled — its attempt count and one row per attempt with the status you returned, never the body. POST …/webhooks/deliveries/{deliveryId}/retry sends a failed one again.

Endpoints

An application may hold at most 10 endpoints. Creating one is a passkey-confirmed action in the console session.

POST …/webhooks

urlrequired
Up to 2048 characters. https only in production; a sandbox application outside production may use http and a loopback address, so you can test against a local server. The address is resolved and checked against the egress policy before it is kept.
eventsrequired
An array of event types from the catalogue.
description
Up to 300 characters.

The answer carries signingSecret once. PATCH …/webhooks/{endpointId} changes url, events, description or status (active or disabled), optionally guarded with configurationVersion so two people editing the same endpoint do not overwrite each other. DELETE …/webhooks/{endpointId} removes it and cancels its pending deliveries.

POST …/webhooks/{endpointId}/rotate-secret returns a new signingSecret; POST …/webhooks/{endpointId}/test sends a webhook.test event — { applicationId, message } — through the real delivery path and answers with the delivery's result and the status you returned. A disabled endpoint refuses the test with WEBHOOK_ENDPOINT_DISABLED.

What this does not do

  • Webhooks are not required to go live. No check on the go-live checklist asks for one.
  • A delivery is a notification, not the truth. Your authoritative signal that a consent has ended is still the 401 the next userinfo call returns.
  • The `billing` events are about budgets you may not have configured. They exist in the catalogue whether or not you set one.

Verified against API commit 234dba22 on 2026-10-18. The routes, scopes, checklist, events and limits on these pages are read from that export, not typed.