Webhooks
Complete guide for receiving identity verification events in your application. Learn how to set up webhook endpoints, handle events, and implement reliable event processing.
IDV SDK Feature
Webhooks are used to receive server-side notifications for identity verification events. Events are sent to your server when verification status changes occur.
Quick Start
Get webhook events up and running in minutes with these essential steps:
- Create Endpoint - Set up a public HTTPS URL to receive events
- Handle Events - Process verification events in your application
- Configure & Test - Set up authentication and validate events
What You'll Receive
verification.completed - Approved
Sent when identity verification completes successfully with an approved decision.
{
"eventId": "550e8400-e29b-41d4-a716-446655440000",
"eventType": "verification.completed",
"eventVersion": "1.0",
"timestamp": "2024-01-15T10:30:00.000Z",
"source": "vecu-idv",
"data": {
"verificationId": "ver_1234567890",
"referenceId": "customer_1234567890",
"configurationId": "your_configuration_id",
"previousStatus": "in_progress",
"currentStatus": "completed",
"decision": "approved",
"previousDecision": "review",
"reasons": [
"identity_resolution_success",
"document_validation_success",
"address_validation_success"
],
"completedAt": "2024-01-15T10:30:00.000Z"
}
}
verification.completed - Rejected
Sent when verification completes but identity cannot be verified.
{
"eventId": "6b3d2f1e-c8a7-4d5f-9e1b-3a7c9d4e2f5a",
"eventType": "verification.completed",
"eventVersion": "1.0",
"timestamp": "2024-01-15T10:35:00.000Z",
"source": "vecu-idv",
"data": {
"verificationId": "ver_0987654321",
"referenceId": "customer_0987654321",
"configurationId": "your_configuration_id",
"previousStatus": "in_progress",
"currentStatus": "completed",
"decision": "rejected",
"previousDecision": "review",
"reasons": [
"document_validation_failure",
"address_correlation_failure",
"fraud_alerts"
],
"completedAt": "2024-01-15T10:35:00.000Z"
}
}
verification.status_changed
Sent when the verification status or decision changes during the verification process.
{
"eventId": "9f2e8c4a-7d3b-4e1f-8a6c-5b9d2e3f4a7b",
"eventType": "verification.status_changed",
"eventVersion": "1.0",
"timestamp": "2024-01-15T10:28:00.000Z",
"source": "vecu-idv",
"data": {
"verificationId": "ver_1234567890",
"referenceId": "customer_1234567890",
"configurationId": "your_configuration_id",
"previousStatus": "pending",
"currentStatus": "in_progress",
"decision": "review",
"previousDecision": null,
"reasons": ["input_completeness"]
}
}
Reverification Events
When using startReverification(), your webhook endpoint receives reverification-specific events with the reverification.* event type prefix and verification IDs starting with reverify.
reverification.completed
{
"eventId": "550e8400-e29b-41d4-a716-446655440000",
"eventType": "reverification.completed",
"eventVersion": "1.0",
"timestamp": "2024-01-15T10:30:00.000Z",
"source": "vecu-idv",
"data": {
"verificationId": "reverify_1234567890",
"referenceId": "customer_1234567890",
"previousStatus": "in_progress",
"currentStatus": "completed",
"decision": "approved",
"reasons": ["FACE_MATCHED", "LIVENESS_CHECK_PASSED"]
}
}
Webhook Configuration
Webhook URL Requirements
- Must be a valid HTTPS URL
- Should be publicly accessible
- Must support POST method with JSON content type
- Must respond within 30 seconds
- Should return HTTP 2xx status codes for successful processing
Example: https://api.yourclient.com/webhooks/vecu-idv
Authentication Types
None (No Authentication)
{
"type": "none"
}
Basic Authentication
{
"type": "basic",
"username": "your_username",
"password": "your_password"
}
Headers sent: Authorization: Basic <base64-encoded-credentials>
Bearer Token Authentication
{
"type": "bearer",
"token": "your_bearer_token"
}
Headers sent: Authorization: Bearer your_bearer_token
OAuth2 Authentication
{
"type": "oauth2",
"clientId": "your_client_id",
"clientSecret": "your_client_secret",
"tokenUrl": "https://auth.provider.com/token",
"scopes": ["webhook", "read"]
}
Headers sent: Authorization: Bearer current_access_token
Webhook Events
Event Types
| Event Type | Description |
|---|---|
verification.status_changed | General status change event |
verification.completed | Verification successfully completed |
verification.failed | Verification failed |
reverification.status_changed | Reverification status change |
reverification.completed | Reverification completed |
reverification.failed | Reverification failed |
Event Payload Structure
{
"eventId": "550e8400-e29b-41d4-a716-446655440000",
"eventType": "verification.completed",
"eventVersion": "1.0",
"timestamp": "2024-01-15T10:30:00.000Z",
"source": "vecu-idv",
"data": {
"verificationId": "ver_1234567890",
"referenceId": "your_reference_id",
"configurationId": "your_configuration_id",
"previousStatus": "pending",
"currentStatus": "completed",
"previousDecision": "review",
"decision": "approved",
"reasons": ["identity_resolution_success", "document_validation_success"],
"completedAt": "2024-01-15T10:30:00.000Z"
}
}
Verification Statuses
| Status | Description |
|---|---|
pending | Verification is queued or starting |
in_progress | Verification is actively processing |
completed | Verification process finished - check decision |
failed | Technical failure occurred |
expired | Verification session expired |
unknown | Status could not be determined |
Status Details and Resume Behavior
Understanding how each status affects user experience when re-initiating verification:
-
pending- Verification link has been generated and the user is completing the capture process. Resume behavior: If a user (based on referenceId) re-initiates a verification while in this state, a new verification session will be started. -
in_progress- Document capture is complete and the user is in the Information Verification screen in the SDK. Resume behavior: If a user (based on referenceId) re-initiates a verification while in this state, the existing verification session will be resumed. -
completed- Check decision field for outcome (e.g., approved, rejected). Resume behavior: If a user (based on referenceId) re-initiates a verification while in this state, a new verification session will be started. -
failed- System error, timeout, or configuration issue. Resume behavior: If a user (based on referenceId) re-initiates a verification while in this state, a new verification session will be started. -
expired- User exceeded the 24-hour capture window. Note: verification will not expire once it reaches thein_progressstate. Resume behavior: If a user (based on referenceId) re-initiates a verification while in this state, a new verification session will be started. -
unknown- Unexpected state or communication issue. Resume behavior: If a user (based on referenceId) re-initiates a verification while in this state, a new verification session will be started.
Decision Types
| Decision | Description |
|---|---|
approved | Identity verification passed all required checks |
rejected | Identity verification failed |
manual_review | Flagged for manual review by an operator |
review | Automated review process in progress (temporary) |
inconclusive | Technical issue prevented decision |
Using referenceId for Event Correlation
The referenceId field in webhook events enables you to correlate verification events with your internal customer records. This is your primary key for tracking and managing verifications.
Tracking Multiple Events
All webhook events for the same customer share the same referenceId. Use this to:
- Link multiple
verification.status_changedevents - Connect initial verification to reverification events
- Update customer records in your database
- Maintain audit trails and verification history
Example: Customer Verification Timeline
// Initial verification
{
"eventType": "verification.completed",
"data": {
"verificationId": "ver_123",
"referenceId": "customer_12345", // Your stable customer ID
"decision": "approved"
}
}
// Later: Reverification for same customer
{
"eventType": "reverification.completed",
"data": {
"verificationId": "reverify_456",
"referenceId": "customer_12345", // Same referenceId links them
"decision": "approved"
}
}
// Your webhook handler can now correlate these events:
const customer = await db.customers.findByReferenceId("customer_12345");
customer.verifications.push({ verificationId, decision, timestamp });
Stable referenceId Required
For effective correlation, always provide a stable customer identifier as
the referenceId when starting verifications. If you rely on the SDK's
auto-generated timestamp-based IDs, each verification will have a different
referenceId, preventing correlation.
Reason Codes Reference
Complete reference for all reason codes returned in webhook events. These codes explain why a verification decision was made and help you determine the appropriate next steps.
Code Format
Reason codes may appear in different formats depending on your backend configuration. Handle codes case-insensitively where possible.
Positive Reason Codes
These codes indicate successful validation checks and support approval decisions:
| Category | Code | Description |
|---|---|---|
| Identity | identity_resolution_success | Identity successfully resolved |
| Identity | FACE_MATCHED | Face matches document photo |
| Document | document_validation_success | Document verification passed |
| Document | DOCUMENT_VALIDATED | Document successfully verified |
| Document | document_processing | Document processing details |
| Biometric | LIVENESS_CHECK_PASSED | Liveness detection passed |
| Government | GOVERNMENT_VALIDATION_PASSED | Government database validation passed |
| Address | address_validation_success | Address verified successfully |
| Phone | phone_validation_success | Phone number verified |
| Phone | phone_characteristics | Phone service information |
email_validation_success | Email address verified | |
email_characteristics | Email pattern information | |
| Age | age_validation_success | Age verification passed |
| Account | account_correlation_match | Account data correlates |
| Account | account_history | Account historical activity |
| Name | name_correlation_match | Name matching succeeded |
| Safety | deceased_check_clear | Not reported as deceased |
| Safety | sim_swap_clear | No SIM swap detected |
| Safety | watchlist_clear | No watchlist matches found |
| Safety | positive_list_matches | Positive list matches |
| Data | input_completeness | Data completeness verified |
| Device | device_information | Device analysis information |
| Network | consortium_data | Consortium network information |
| Network | fraud_network_positive_indicators | Network analysis positive |
| Synthetic | synthetic_positive_indicators | Synthetic identity positive |
Risk Reason Codes
These codes indicate validation failures or risk factors that may lead to rejection or review:
| Category | Code | Description |
|---|---|---|
| Document | document_validation_failure | Document verification failed |
| Document | INVALID_DOCUMENT | Document is invalid |
| Document | DOCUMENT_QUALITY_ISSUE | Document image quality insufficient |
| Document | DOCUMENT_VALIDATION_WARNING | Document validation warning |
| Biometric | LIVENESS_CHECK_FAILED | Liveness detection failed |
| Biometric | LIVENESS_CHECK_WARNING | Liveness detection warning |
| Biometric | FACE_MISMATCH | Face does not match document photo |
| Biometric | FACE_MATCH_WARNING | Face match warning |
| Biometric | SELFIE_QUALITY_ISSUE | Selfie image quality insufficient |
| Biometric | SPOOF_DETECTED | Spoofing attempt detected |
| Government | GOVERNMENT_VALIDATION_FAILED | Government database validation failed |
| Government | GOVERNMENT_VALIDATION_WARNING | Government validation warning |
| Identity | identity_resolution_failure | Cannot resolve identity |
| Identity | EXISTING_USER_DETECTED | Existing user match detected |
| Identity | ssa_verification_failure | SSN verification failed |
| Identity | ssn_issues | Social Security Number problems |
| Identity | deceased_indicators | Identity shows as deceased |
| Identity | age_verification_failure | Age verification failed |
| Address | address_validation_failure | Address validation failed |
| Address | address_correlation_failure | Address correlation failed |
| Address | address_type_risk | Risky address type detected |
| Address | address_zip_issues | ZIP code validation failures |
| Phone | phone_validation_failure | Phone validation failed |
| Phone | phone_type_risk | Risky phone type detected |
| Phone | phone_age_risk | Phone age and porting risk |
| Phone | phone_network_risk | Phone network risk |
email_validation_failure | Email validation failed | |
email_risk_patterns | Email risk patterns | |
email_age_risk | Email age risk | |
email_geolocation_risk | Email geolocation risk | |
| Account | account_mismatch | Account information mismatch |
| Account | account_issues | Account problems |
| Fraud | fraud_alerts | Fraud alert indicators found |
| Fraud | synthetic_identity | Synthetic identity detected |
| Fraud | first_party_fraud | First-party fraud indicators |
| Fraud | identity_fraud | General identity fraud risk |
| Fraud | transaction_fraud | Transaction fraud history |
| Fraud | consortium_risk | Consortium risk indicators |
| Network | ip_geolocation_risk | IP geolocation risk |
| Network | proxy_vpn_risk | Proxy/VPN risk |
| Device | device_risk | High-risk device characteristics |
| Watchlist | watchlist_matches | Found on watchlists |
| Watchlist | alert_list_matches | Alert list matches |
| Watchlist | negative_list_matches | Negative list matches |
| Watchlist | suspect_list_matches | Suspect list matches |
| System | service_errors | Service processing errors |
Retry Logic and Reliability
Automatic Retries
The webhook delivery service implements automatic retry logic with exponential backoff:
- Maximum retries: 3 attempts per webhook
- Base delay: 60 seconds
- Timeout: 30 seconds per request
Retry Schedule
- Initial attempt: Immediate
- First retry: 60 seconds after failure
- Second retry: 120 seconds after first retry failure
- Third retry: 240 seconds after second retry failure
Retry Conditions
Webhooks are retried for:
- Network errors (connection failures, timeouts)
- Server errors (HTTP 5xx status codes)
- Rate limiting (HTTP 429 status code)
Webhooks are NOT retried for:
- Client errors (HTTP 4xx, except 429)
- Invalid webhook URLs
- Authentication failures
Webhook Endpoint Implementation
Response Requirements
Your webhook endpoint should:
- Respond quickly - Process within 30 seconds
- Return appropriate status codes:
200-299: Success (delivery confirmed)429: Rate limited (will retry)500-599: Server error (will retry)400-499(except 429): Client error (will not retry)
Example Handler (Node.js)
app.post('/webhooks/vecu-idv', (req, res) => {
const event = req.body;
switch (event.eventType) {
case 'verification.completed':
const { verificationId, decision, reasons } = event.data;
if (decision === 'approved') {
await updateUserVerificationStatus(verificationId, 'verified');
await sendWelcomeEmail(event.data.customerInfo.email);
} else if (decision === 'rejected') {
await updateUserVerificationStatus(verificationId, 'failed');
await notifyUserOfVerificationFailure(event.data, reasons);
}
break;
case 'verification.status_changed':
await updateVerificationProgress(event.data);
break;
}
res.status(200).json({ status: 'processed', eventId: event.eventId });
});
Security Considerations
- HTTPS Only - Always use HTTPS endpoints
- SSL Certificate Verification - Production requires valid certificates
- Input Validation - Validate all incoming webhook data
- Rate Limiting - Implement rate limiting on your endpoints
- IP Allowlisting - Consider restricting to known VEC-IDV IP ranges
- Authentication - Use webhook authentication for additional security
Testing Your Webhook
Use this sample payload to test your webhook implementation:
{
"eventId": "test-event-12345",
"eventType": "verification.completed",
"eventVersion": "1.0",
"timestamp": "2024-01-15T10:30:00.000Z",
"source": "vecu-idv",
"data": {
"verificationId": "test-ver-123",
"referenceId": "test-ref-456",
"configurationId": "test-configuration",
"previousStatus": "in_progress",
"currentStatus": "completed",
"decision": "approved",
"previousDecision": "review",
"reasons": [
"identity_resolution_success",
"document_validation_success",
"address_validation_success"
],
"completedAt": "2024-01-15T10:30:00.000Z"
}
}
Configuration Management API
The Configuration Management API allows you to programmatically manage webhook configurations. Complete API documentation with detailed request/response schemas is available in the OpenAPI/Swagger specification provided with your API access package.
Example Configuration Request
{
"configurationId": "generated-config-id",
"configuration": {
"name": "Production Webhook",
"webhookUrl": "https://api.example.com/webhooks/vecu",
"authSettings": {
"type": "bearer",
"credentials": {
"token": "your-webhook-bearer-token"
}
},
"authorizationPoolSettings": {
"firstAcceptCancelsOthers": true,
"authorizationExpiryDays": 30,
"poolExpiryDays": 30,
"maxAuthorizationsPerPool": 10,
"maxPoolsPerVin": 5,
"pushNotificationsEnabled": false,
"autoIssueCredential": true
}
},
"setActive": true
}
Authorization Pool Settings
The authorizationPoolSettings object configures behavior for the authorization-pool service. If omitted, default values are applied automatically.
firstAcceptCancelsOthersbooleanDefault: trueWhen true, the first accepted authorization cancels all other pending authorizations in the pool.
authorizationExpiryDaysintegerDefault: 30Number of days until an authorization expires (1-90).
poolExpiryDaysintegerDefault: 30Number of days until an authorization pool expires (1-90).
maxAuthorizationsPerPoolintegerDefault: 10Maximum number of authorizations allowed per pool (1-50).
maxPoolsPerVinintegerDefault: 5Maximum number of active pools allowed per VIN (1-20).
pushNotificationsEnabledbooleanDefault: falseEnable push notifications for authorization events.
notificationPrioritystringPriority level for push notifications: HIGH, NORMAL, or LOW. Only used
if pushNotificationsEnabled is true.
autoIssueCredentialbooleanDefault: trueAutomatically issue a credential when an authorization is accepted.
Default Values
If authorizationPoolSettings is not provided in the request, the system
automatically applies default values. You only need to specify settings you
want to override.
Active Configuration
Only one configuration can be active at a time per environment. Setting
setActive: true automatically deactivates the previous configuration.
Next Steps
- Testing Guide - Set up mock webhook servers
- Web SDK Demo - See webhook events live
- API Reference - SDK methods reference