Reverification
Streamlined identity re-verification for returning users who need to authenticate from a new device or after a security event.
What is Reverification?
Reverification allows users to quickly verify their identity using only a new selfie - no need to re-enter personal information or upload documents again. Perfect for device changes, step-up authentication, or periodic security checks.
When to Use Reverification
Verification vs Reverification
| Scenario | Use Verification | Use Reverification |
|---|---|---|
| New user signing up | ✅ Full identity verification | ❌ No existing identity data |
| User logging in from new device | ❌ Unnecessary friction | ✅ Quick re-authentication |
| Suspicious activity detected | ❌ Overkill for existing user | ✅ Fast security check |
| Periodic re-verification | ❌ Too time-consuming | ✅ Quick security check |
User Experience Comparison
Initial Verification
📋 Personal Info Form
📄 Document Upload
📸 Selfie Photo
Reverification
📸 Selfie Photo Only
✓ Uses data from original verification
✓ No form required
✓ No document upload
Integration Steps
1. Trigger Detection (Your Responsibility)
Detect when reverification is needed based on your business logic:
async function handleUserLogin(userId: string, deviceId: string) {
// Check if this device is registered
const isKnownDevice = await yourDatabase.checkDevice(userId, deviceId);
if (!isKnownDevice) {
// ⚠️ NEW DEVICE DETECTED - Trigger Reverification
return await startReverificationFlow(userId);
}
// Known device - proceed normally
return await grantAccess(userId);
}
Your Decision
YOU decide when to trigger reverification: - New device login - High-value transaction - Suspicious activity - Time-based (every N days) - Risk score threshold
2. Start Reverification Flow
Call the SDK with the referenceId from the original verification:
import { createVecuIDVSDK } from 'vec-idp-web-sdk';
async function startReverificationFlow(userId: string) {
// 1. referenceId is your customer/user ID
const referenceId = userId; // This is what you used during original verification
// 2. Initialize SDK
const sdk = createVecuIDVSDK();
await sdk.updateConfig({
deploymentStage: 'production',
bearerToken: await getYourOAuthToken(),
});
// 3. Start reverification (this triggers the selfie flow)
try {
const cleanup = await sdk.startReverification(
document.getElementById('verification-container'),
{
referenceId: referenceId,
// Optional: Phone number for SMS notifications
phoneNumber: user.phoneNumber, // e.g., '+1-555-123-4567'
sendMessage: true, // Default: true (sends SMS with verification link)
onSuccess: result => {
console.log('Reverification completed!', result);
// User successfully reverified
},
onError: error => {
console.error('Reverification failed:', error);
// Handle error
},
}
);
// The SDK now displays the selfie capture UI
} catch (error) {
// Handle errors (network issues, invalid referenceId, etc.)
console.error('Failed to start reverification:', error);
await showUserError('Unable to verify. Please try again.');
}
}
Optional Parameters
phoneNumber - Provide the user's phone number to receive SMS notifications with the verification link. If omitted, no SMS is sent.
sendMessage - Control whether SMS is sent (default: true). Set to false to disable SMS even if phone number is provided.
What Happens Behind the Scenes
- SDK calls VECU API
- VECU looks up original verification using
referenceId - VECU retrieves verificationId
- Identity provider shows selfie capture UI
- User takes selfie
- Provider performs face match against original documents
- Result delivered via webhook to your server
3. Handle Webhook Results
Same Webhook Endpoint
Reverification uses your existing webhook endpoint from verification. Simply
add handling for the reverification.completed event type - no need to
configure a new webhook URL.
Webhook Event Types:
Your webhook will receive the following event types during reverification:
reverification.status_changed- Intermediate status updates during processingreverification.completed- Final result with statuscompleted(decision: approved/rejected/manual_review)reverification.failed- Final result with statusfailed(system error or unable to process)
Receive and process the reverification decision:
app.post('/webhooks/vecu', async (req, res) => {
const event = req.body;
// Handle intermediate status updates
if (event.eventType === 'reverification.status_changed') {
const { referenceId, status } = event.data;
const userId = await yourDatabase.getUserIdByReference(referenceId);
// Update UI or log progress
await yourDatabase.updateVerificationStatus(userId, status);
await sendProgressUpdate(userId, status);
}
// Handle successful completion
if (event.eventType === 'reverification.completed') {
const { referenceId, decision, verificationId } = event.data;
const userId = await yourDatabase.getUserIdByReference(referenceId);
if (decision === 'approved') {
// ✅ VERIFIED - Grant access
await yourDatabase.registerDevice(userId, currentDeviceId);
await yourDatabase.updateUserSession(userId, { verified: true });
await sendPushNotification(userId, 'Device verified successfully');
} else if (decision === 'rejected') {
// ❌ FAILED - Handle rejection
await yourDatabase.logSecurityEvent(userId, 'reverification_failed');
await handleVerificationFailure(userId);
} else if (decision === 'manual_review') {
// ⚠️ NEEDS REVIEW - Temporary state
await yourDatabase.setUserStatus(userId, 'pending_review');
await sendEmail(userId, 'Your verification is under review');
}
}
// Handle system failures
if (event.eventType === 'reverification.failed') {
const { referenceId, error } = event.data;
const userId = await yourDatabase.getUserIdByReference(referenceId);
// Log error and notify user
await yourDatabase.logError(userId, 'reverification_system_error', error);
await sendEmail(userId, 'Verification unavailable - please try again');
}
// Always return 200 to acknowledge receipt
res.status(200).json({ received: true });
});
Integration Flow
↓
Your Application
✓ Retrieve
referenceId
from database
✓ Call
sdk.startReverification()
↓
VECU SDK
↓
Your Webhook Endpoint
✓ Receive
reverification.completed
event
↓
Step-by-Step Process
1. User Action
- User attempts login from new device
2. Your Application Detects & Triggers
- Detect: New device or security event
- Decide: Reverification needed
- Get
referenceId(same customer ID used in original verification) - Call:
sdk.startReverification(container, { referenceId })
3. VECU API Processing
- Lookup original verification using
referenceId - Call identity provider API to retrieve existing verification record and initiate selfie check
4. User Experience
- Identity provider displays selfie capture UI
- User takes selfie photo
- Liveness detection performed
- Face match against original documents
5. Decision & Result
- Identity provider generates decision (approved/rejected/manual_review)
- VECU API stores result
- Webhook triggered to your endpoint
6. Your Application Responds
- Receive webhook event:
reverification.completed - Process decision (approved/rejected/manual_review)
- Register device or handle rejection
- Grant or deny access to user
Asynchronous Flow
The process is asynchronous - from SDK call to webhook delivery. Your application should show a loading state while the user completes the selfie capture and processing occurs.
Decision Outcomes
Approved ✅
{
"decision": "approved",
"reasons": [
{
"code": "id.selfie.match",
"description": "Selfie matches document photo"
},
{
"code": "id.liveness.passed",
"description": "Liveness check passed"
}
]
}
Your Action: Grant access, register device, allow transaction
Rejected ❌
{
"decision": "rejected",
"reasons": [
{
"code": "id.selfie.no_match",
"description": "Selfie does not match document photo"
}
]
}
Your Action: Deny access, optionally allow retry or escalate to support
Manual Review ⚠️
{
"decision": "manual_review",
"reasons": [
{
"code": "id.selfie.unclear",
"description": "Image quality insufficient for automated decision"
}
]
}
Your Action: Display "under review" message, check status later
Implementation Checklist
- Implement trigger logic (detect new device/high-risk action)
- Use consistent customer ID as
referenceId(same as initial verification) - Add
startReverification()call with user's referenceId - Add
reverification.completedevent handling to existing webhook - Handle reverification decisions (approved/rejected/manual_review)
- Add business logic for device registration
- Add error handling for network/API failures
- Test in sandbox with sample users
- Test all decision outcomes (approved/rejected/manual_review)
- Test webhook delivery and retries
- Test edge cases (invalid referenceId, expired verification)
Frequently Asked Questions
What if the user refuses the selfie?
Your decision. Handle it in your app:
- Lock the account until they complete reverification
- Allow limited access (read-only mode)
- Escalate to manual review
What if the webhook fails to deliver?
We retry automatically:
- 3 attempts with exponential backoff
- If all fail, event goes to Dead Letter Queue
Can I test without a real camera?
Yes, use the interactive demo:
- Experience the flow in our Interactive Demo
- Simulates the complete reverification process
- No camera or real verification required
Try It Now
Interactive Demo
Experience the reverification flow in our Interactive Demo:
- Complete a full verification first (get a
referenceId) - Use the reverification tab to simulate a returning user
- See the simplified selfie-only flow
- Compare the streamlined experience
Next Steps
- Review Webhook Structure: See Webhooks for complete event schemas
- Check API Reference: See API Reference for
startReverification()method details - Try the Interactive Demo: Use the Demo to experience the reverification flow
Support
Questions?
- Review the Troubleshooting Guide
- Check the API Reference
- Contact your VECU integration engineer