Skip to main content
Webhooks deliver real-time HTTP POST notifications when events occur in your account, eliminating the need to poll for status changes.

Events

EventTrigger
session.completedVerification session finished processing
session.approvedSession approved — identity verified
session.declinedSession declined — failed checks or suspicious data
session.expiredSession expired before completion
aml.completedAML screening finished processing
aml.match_foundPotential matches found against watchlists or PEP databases
aml.monitoring.matchContinuous monitoring detected new AML matches
transaction.flaggedTransaction flagged for manual review
transaction.blockedTransaction automatically blocked by risk rules
biometric.completedBiometric authentication finished processing
database.validatedDatabase validation completed
face.duplicate_foundFace search detected a duplicate identity
credential.createdReusable KYC credential issued
credential.sharedCredential shared with another organization
credential.verifiedShared credential verified by another organization
credential.revokedCredential revoked
video.completedVideo recording or live agent call finished
video.reviewedVideo KYC reviewed and decision made
liveness.failedActive liveness challenge failed
risk.threshold_exceededSession risk score exceeded configured threshold
ambient.alertAmbient verification detected a risk change (warning or critical severity)

Payload Structure

session.completed
{
  "event": "session.completed",
  "data": {
    "session_id": "ses_a1b2c3d4e5f6",
    "status": "approved",
    "risk_score": 12,
    "decision": "approved",
    "completed_at": "2026-03-15T14:30:00Z"
  },
  "timestamp": "2026-03-15T14:30:01Z",
  "webhook_id": "wh_evt_9f8e7d6c5b4a"
}
FieldTypeDescription
eventstringEvent type identifier
dataobjectEvent-specific payload (varies by event type)
timestampstringISO 8601 timestamp
webhook_idstringUnique delivery ID — use for idempotency

Signature Verification

Every webhook includes an X-Verilock-Signature header with an HMAC-SHA256 signature.
Always verify signatures before processing webhook data. Your webhook secret is available in Dashboard > Settings > Webhooks.
$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret    = getenv('VERILOCK_WEBHOOK_SECRET');

$expected = hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

$event = json_decode($payload, true);

match ($event['event']) {
    'session.completed'    => handleSession($event['data']),
    'aml.match_found'      => handleAmlMatch($event['data']),
    'transaction.blocked'  => handleBlocked($event['data']),
    'ambient.alert'        => handleAmbientAlert($event['data']),
    default                => null,
};

http_response_code(200);

Retry Policy

Failed deliveries (non-2xx response within 10 seconds) are retried with exponential backoff:
AttemptDelayElapsed
1st retry10s~10s
2nd retry60s~70s
3rd retry5min~6min
After 3 failed retries, the delivery is marked as failed. View and retry failed deliveries from your dashboard.

Best Practices

Respond immediately

Return 200 as soon as you receive the webhook. Process events asynchronously via a job queue.

Idempotency

Store processed webhook_id values and skip duplicates to ensure exactly-once processing.

Verify signatures

Always validate X-Verilock-Signature using timing-safe comparison before processing any data.