Webhooks Guide

Webhooks deliver real-time event notifications to your server when things happen in Verifa — sessions complete, screening finds matches, identities update, and more. This guide covers setup, security, event filtering, and best practices.

Quick setup

1. Create a webhook endpoint

$curl -X POST https://api.withverifa.com/api/v1/webhooks/endpoints \
> -H "X-API-Key: vk_live_your_key_here" \
> -H "Content-Type: application/json" \
> -d '{
> "url": "https://your-app.com/webhooks/verifa",
> "enabled_events": ["session.approved", "session.declined", "session.requires-review"],
> "description": "Production webhook"
> }'
1{
2 "id": "webhook_abc123",
3 "url": "https://your-app.com/webhooks/verifa",
4 "secret": "whsec_abc123def456...",
5 "enabled_events": ["session.approved", "session.declined", "session.requires-review"],
6 "enabled": true,
7 "created_at": "2026-02-01T12:00:00Z"
8}

Store the secret securely — you need it to verify webhook signatures. The secret is only returned on creation and rotation.

2. Handle events

1const express = require("express");
2const crypto = require("crypto");
3
4const app = express();
5
6app.post("/webhooks/verifa", express.raw({ type: "application/json" }), (req, res) => {
7 // Verify signature
8 const signature = req.headers["x-verifa-signature"];
9 const expected = crypto
10 .createHmac("sha256", process.env.VERIFA_WEBHOOK_SECRET)
11 .update(req.body)
12 .digest("hex");
13
14 if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
15 return res.status(401).send("Invalid signature");
16 }
17
18 // Process event
19 const event = JSON.parse(req.body);
20 console.log(`Received ${event.event} for session ${event.data.session_id}`);
21
22 // Respond immediately — process asynchronously
23 res.status(200).send("OK");
24
25 // Queue for async processing
26 processEvent(event);
27});

3. Test it

Send a test event to verify your endpoint is working:

$curl -X POST https://api.withverifa.com/api/v1/webhooks/endpoints/webhook_abc123/test \
> -H "X-API-Key: vk_live_your_key_here"
1{
2 "success": true,
3 "http_status": 200,
4 "url": "https://your-app.com/webhooks/verifa"
5}

Event catalog

Session events

EventDescription
session.createdA new verification session was created.
session.startedThe user opened the capture URL.
session.expiredThe capture token expired before completion.
session.approvedVerification approved (auto or manual).
session.declinedVerification rejected.
session.requires-reviewSession needs manual review.
session.awaiting_externalWorkflow paused at external gate.
session.redactedPII and documents permanently deleted.
session.retention-expiredRetention window elapsed; data auto-redacted.
session.link_generatedA shareable verification link was created.
session.resubmission-requiredImage quality insufficient; user must re-submit.

Screening events

EventDescription
screening.completedA screening check finished.
screening.monitoring.new_hitsContinuous monitoring found new matches.
screening.monitoring.clearMonitoring run completed with no new hits.
check.completedA standalone check completed.
check.matchedA standalone check found matches.
check.monitoring.new_hitsCheck monitoring found new hits.
check.monitoring.clearCheck monitoring found no new hits.

Identity events

EventDescription
identity.createdNew identity record created.
identity.updatedIdentity data updated.
identity.archivedIdentity archived.
identity.restoredIdentity restored from archive.
identity.tag-addedTag added to identity.
identity.tag-removedTag removed from identity.
identity.relationship.createdIdentity relationship established.
identity.relationship.deletedIdentity relationship removed.

Case events

EventDescription
case.createdReview case created.
case.claimedCase claimed by a reviewer.
case.approvedCase approved (final decision).
case.rejectedCase rejected (final decision).

Document events

EventDescription
document.uploadedDocument file uploaded.
document.classifiedDocument type detected.
document.extractedData extracted from document.
document.verifiedDocument verification completed.
document.comparedDocument compared against another.
document.redactedDocument permanently deleted.

Quality assurance events

EventDescription
smart_qa.finding.createdQA finding generated.
smart_qa.finding.criticalCritical QA finding detected.

Event filtering

Subscribe to specific events or use "*" to receive all events:

$curl -X PATCH https://api.withverifa.com/api/v1/webhooks/endpoints/webhook_abc123 \
> -H "X-API-Key: vk_live_your_key_here" \
> -H "Content-Type: application/json" \
> -d '{
> "enabled_events": ["session.approved", "session.declined", "screening.monitoring.new_hits"]
> }'

Payload format

All webhook payloads follow this structure:

1{
2 "event": "session.approved",
3 "data": {
4 "session_id": "session_abc123",
5 "external_ref": "user_abc123",
6 "status": "approved",
7 "is_sandbox": false,
8 "created_at": "2026-02-01T12:00:00Z"
9 },
10 "created_at": "2026-02-01T12:05:00Z"
11}

The data object contents vary by event type. Session events include session_id, external_ref, and status. Identity events include identity_id and the changed fields.

Signature verification

Every webhook includes an X-Verifa-Signature header — an HMAC-SHA256 hash of the raw request body signed with your endpoint’s secret.

Always verify signatures to prevent spoofed events. Use the raw request body (not parsed JSON) for verification, and use a constant-time comparison function.

Retry behavior

If your endpoint returns a non-2xx status or doesn’t respond within 30 seconds, Verifa retries with exponential backoff:

AttemptDelay
1st retry~30 seconds
2nd retry~2 minutes
3rd retry~8 minutes
4th retry~32 minutes
5th retry~2 hours

After 5 failed retries, the delivery is marked as failed.

Circuit breaker

If an endpoint accumulates 10 consecutive failed deliveries (all retries exhausted), Verifa automatically disables the endpoint and sends an email notification to your organization’s admins. Re-enable it in the dashboard or via API after fixing the issue.

Managing endpoints

Rotate the signing secret

$curl -X POST https://api.withverifa.com/api/v1/webhooks/endpoints/webhook_abc123/rotate-secret \
> -H "X-API-Key: vk_live_your_key_here"

Returns the new secret. Update your verification code before the old secret stops working.

Clone an endpoint

Duplicate an endpoint with a new secret (useful for migration):

$curl -X POST https://api.withverifa.com/api/v1/webhooks/endpoints/webhook_abc123/clone \
> -H "X-API-Key: vk_live_your_key_here"

View delivery history

$curl https://api.withverifa.com/api/v1/webhooks/endpoints/webhook_abc123/deliveries \
> -H "X-API-Key: vk_live_your_key_here"

Retry a failed delivery

$curl -X POST https://api.withverifa.com/api/v1/webhooks/deliveries/webhookdlv_abc123/retry \
> -H "X-API-Key: vk_live_your_key_here"

Key inflection

Control the casing of payload keys per endpoint:

$curl -X PATCH https://api.withverifa.com/api/v1/webhooks/endpoints/webhook_abc123 \
> -H "X-API-Key: vk_live_your_key_here" \
> -H "Content-Type: application/json" \
> -d '{
> "key_inflection": "camel"
> }'

Options: snake (default), camel, kebab.

Best practices

  • Respond quickly. Return 200 immediately and process the event asynchronously. If your handler takes too long, the delivery may time out and trigger unnecessary retries.

  • Handle duplicates. Use the session_id or event data to deduplicate. In rare cases (network issues, retries), you may receive the same event more than once.

  • Verify signatures. Always validate the X-Verifa-Signature header using the raw body and a constant-time comparison. Never process unverified events.

  • Exempt from CSRF. If your framework has CSRF protection, exempt your webhook endpoint path.

  • Use specific events. Subscribe only to the events you need rather than "*". This reduces noise and makes your handler simpler.

  • Monitor delivery health. Check the delivery history in the dashboard regularly. If you see frequent failures, investigate timeouts or errors on your endpoint.

  • Webhooks — Quick reference for event types and payload format
  • Sessions — Session events and lifecycle
  • Screening & Reports — Screening event details
  • Errors — Error codes returned by webhook API endpoints