{
"verification_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "declined",
"external_id": "user_12345",
"external_metadata": {
"plan": "premium"
},
"reason": "document.face.mismatch",
"timestamp": "2026-09-29T12:05:00+00:00",
"document": {
"type": "passport",
"issuing_country": "DE",
"issuing_subdivision": null,
"fields": {
"first_name": "JANE",
"middle_name": null,
"last_name": "DOE",
"date_of_birth": "1990-04-12",
"gender": "F",
"nationality": "DE",
"place_of_birth": "BERLIN",
"address": null,
"document_number": "C01X00T47",
"issue_date": "2020-04-14",
"expiry_date": "2030-04-13"
}
}
}Decision webhook
The event ProofAge sends to your webhook URL when a verification changes status.
{
"verification_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "declined",
"external_id": "user_12345",
"external_metadata": {
"plan": "premium"
},
"reason": "document.face.mismatch",
"timestamp": "2026-09-29T12:05:00+00:00",
"document": {
"type": "passport",
"issuing_country": "DE",
"issuing_subdivision": null,
"fields": {
"first_name": "JANE",
"middle_name": null,
"last_name": "DOE",
"date_of_birth": "1990-04-12",
"gender": "F",
"nationality": "DE",
"place_of_birth": "BERLIN",
"address": null,
"document_number": "C01X00T47",
"issue_date": "2020-04-14",
"expiry_date": "2030-04-13"
}
}
}Headers
Hex HMAC-SHA256 of {X-Timestamp}.{raw body} with the workspace's active secret key; for a webhook subscription, with the secret key that created it (the active key once that one is deleted).
Unix time, in seconds, when the request was signed.
The workspace's public key (pk_test_… or pk_live_…).
ID of this delivery. A retry of the same delivery keeps it; use it to ignore duplicates.
Body
The verification this event is about.
The status the verification moved to. On a data.updated event, the current status, unchanged.
approved, declined, resubmission_requested, review, abandoned, expired Your identifier for the person, as sent when the verification was created.
The metadata you attached when creating the verification, returned as sent.
Show child attributes
Show child attributes
The decision reason code when the status is declined or resubmission_requested; null otherwise. Also null on the resubmission_requested a facial age estimation sends when it asks the person for an ID (GET reports that verification as documents_required). When attempts run out, the declined event carries the last attempt's reason. See Decision reasons.
When the status changed, ISO 8601.
What happened. status.updated: the verification moved to status. data.updated: someone on your team corrected document fields; status is the current status, which a correction never changes, document carries the corrected values and changed_fields names what changed. A payload without event, such as a retry of a delivery created before this field existed, means status.updated. Webhook subscriptions receive status.updated only.
status.updated, data.updated The same object GET /v1/verifications/{id}/document returns, without media and meta, read from the attempt that decided the verification. Identity (KYC) workspaces receive eleven fields; age verification workspaces receive first_name, last_name, date_of_birth and document_number only, and the other seven keys are absent. null means the field was not read, is not printed on that document, or no document was read at all (a facial age estimation that passed without an ID, a test workspace, a wallet check); document itself is never null. Dates are YYYY-MM-DD and countries ISO 3166-1 alpha-2 (XK for Kosovo); type and gender are open enums. Fields your team corrected show the corrected value. A resend or a manual retry carries the document as it is now; an automatic retry carries the body as first sent. After the person's data is erased, only type and issuing_country are kept. Always present on the workspace webhook; left out of a webhook subscription's deliveries unless it was created with include_document_data.
Show child attributes
Show child attributes
Only on data.updated: the names of what this correction changed, for example ["date_of_birth"]. A name is a key of document.fields, or type, issuing_country or issuing_subdivision. Names only; the new values are in document.
Present and true only when the same face was found behind another verification in the workspace.
Present with duplicate_detected: how many earlier verifications matched.
Present with duplicate_detected: the first matching verification.
Show child attributes
Show child attributes
Optional device and network signals collected during the session. Treat it as informational; its fields may change. Left out of a webhook subscription's deliveries unless it was created with include_document_data.
Show child attributes
Show child attributes
Present when a person in the console approved or declined the verification by hand.
Show child attributes
Show child attributes
Response
Any 2xx acknowledges the delivery.