Webhooks

Receive signed events the moment a verification changes status.

Events

EventFired when
verification.in_progressUser started the hosted flow
verification.reviewProvider routed the case to manual review
verification.approvedApproved (automatically or by an analyst)
verification.declinedDeclined (automatically or by an analyst)
verification.expiredTTL elapsed

Payload

{
  "id": 17,
  "event": "verification.approved",
  "created_at": "2026-08-17T21:41:26+00:00",
  "data": {
    "id": "0192c1a0-...",
    "object": "verification",
    "status": "approved",
    "previous_status": "in_progress",
    "subject_ref": "user-42",
    "checks": {
      "document": { "result": "passed" },
      "liveness": { "result": "passed" },
      "face_match": { "result": "passed", "score": 0.97 }
    },
    "extracted": { "full_name": "…", "date_of_birth": "…" }
  }
}

Verifying signatures

Each endpoint gets its own secret (vf_whsec_…). Every delivery includes:

X-VeriFlow-Event: verification.approved
X-VeriFlow-Signature: t=1723930886,v1=5257a869e7…

The v1 value is HMAC-SHA256("{timestamp}.{body}", secret). Verify like this:

// PHP
[$t, $v1] = array_map(fn ($p) => explode('=', $p), explode(',', $sig));
$expected = hash_hmac('sha256', $t[1].'.'.$rawBody, $secret);
hash_equals($expected, $v1[1]); // true → authentic

Retries

Failed deliveries retry with exponential backoff (2, 4, 8 … 60 min) up to 5 attempts. Inspect and re-trigger from Admin → Webhooks → Recent deliveries.