Onboarder

API Documentation

Webhooks

Receive real-time notifications about events in your unboarder account.

Overview

Webhooks allow your application to receive real-time HTTP notifications when specific events occur in your Onboarder account. Instead of polling the API, webhooks push data to your server as events happen. Configure your webhook endpoints in the unboarder dashboard, then implement handlers to process the events.

  • Real-time event notifications
  • HMAC-SHA256 signature verification for security
  • Automatic retry with exponential backoff
  • Flexible event filtering with wildcard support

Setting Up Webhooks

  1. Go to your unboarder dashboard at dashboard.onboarder.com
  2. Navigate to Developers → Webhooks
  3. Click "Add Endpoint" and enter your webhook URL (must be HTTPS)
  4. Select the events you want to receive (e.g., verification.*, form.*)
  5. Save and copy your webhook secret - you'll need this to verify signatures
  6. Implement the webhook handler on your server using the examples below

Webhook Events

Subscribe to specific events or use wildcards to receive all events in a category.

EventDescription
verification.*All verification events
verification.completedKYC verification completed successfully
verification.failedKYC verification failed
verification.pendingKYC verification is pending review
verification.createdNew verification session created (API-Only/SDK pattern)
verification.submittedVerification submitted for processing (API-Only/SDK pattern)
verification.expiredVerification session expired without submission
country.blockedUser attempted verification from blocked country
fraud.detectedPotential fraudulent verification detected
reverification.requiredUser needs to re-verify (expired or updated requirements)
biometric.*All biometric enrollment and verification events
biometric.enrollment.completedUser completed biometric enrollment (face and/or voice)
biometric.verification.passedBiometric verification passed (transaction authorization)
biometric.verification.failedBiometric verification failed (fraud attempt or poor quality)
transaction.authorizedUser authorized a transaction with biometric authentication
user.createdNew user account created
consent.grantedUser granted OAuth consent to access their data
consent.revokedUser revoked OAuth consent

Webhook Payload

When an event occurs, unboarder sends an HTTP POST request to your webhook URL with the following structure:

{
"id": "evt_5RtY9xMp6qKLn3N8Q1",
"type": "verification.completed",
"created": "2024-01-15T10:30:00Z",
"data": {
"object": {
"id": "ver_2NxZ8wKN5pPQj4L7M9",
"userId": "user_abc123",
"type": "nin",
"status": "verified",
"result": {
"verified": true,
"confidence": 0.98,
"data": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1990-01-15",
"documentNumber": "12345678901"
}
},
"createdAt": "2024-01-15T10:25:00Z",
"completedAt": "2024-01-15T10:30:00Z"
}
}
}

Implementing Webhook Handlers

unboarder signs all webhook requests with HMAC-SHA256. Always verify the signature to ensure the request came from unboarder and hasn't been tampered with.

Signature Headers

  • X-unboarder-Signature: The signature hash
  • X-unboarder-Timestamp: Unix timestamp of when the signature was created

Webhook Handler Implementation

const crypto = require('crypto');
const express = require('express');
const app = express();
function verifyWebhookSignature(payload, signature, secret, timestamp) {
// Prevent replay attacks (optional but recommended)
const tolerance = 300; // 5 minutes
const currentTime = Math.floor(Date.now() / 1000);
if (Math.abs(currentTime - timestamp) > tolerance) {
throw new Error('Webhook timestamp is too old');
}
// Create signature
const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
// Compare signatures
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express.js endpoint example
app.post('/webhooks/unboarder', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-unboarder-signature'];
const timestamp = req.headers['x-unboarder-timestamp'];
const secret = process.env.WEBHOOK_SECRET;
try {
const payload = JSON.parse(req.body);
const isValid = verifyWebhookSignature(payload, signature, secret, timestamp);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook based on event type
switch (payload.type) {
case 'verification.completed':
console.log('Verification completed:', payload.data.object.id);
// Update your database, send notifications, etc.
break;
case 'verification.failed':
console.log('Verification failed:', payload.data.object.id);
break;
case 'form.submission.created':
console.log('New form submission:', payload.data.object.id);
break;
default:
console.log('Unhandled event type:', payload.type);
}
res.status(200).json({ received: true });
} catch (error) {
console.error('Webhook error:', error);
res.status(400).json({ error: 'Webhook processing failed' });
}
});
app.listen(3000, () => console.log('Webhook server running on port 3000'));

Retry Behavior

If your endpoint returns a non-2xx status code or times out, unboarder will retry the webhook with exponential backoff:

  • Attempt 1: Immediately
  • Attempt 2: 5 minutes later
  • Attempt 3: 15 minutes later
  • Attempt 4: 1 hour later
  • Attempt 5: 6 hours later

After 5 failed attempts, the webhook delivery is marked as failed. You can view failed deliveries and retry them manually from your dashboard.

Best Practices

  • Always verify webhook signatures to ensure requests are from unboarder
  • Respond with 2xx status code quickly (within 10 seconds), then process the webhook asynchronously
  • Implement idempotency - handle duplicate events gracefully using the event ID
  • Use HTTPS endpoints only for security
  • Monitor your webhook endpoint health and failure rates in the dashboard
  • Rotate webhook secrets periodically for enhanced security
  • Store event IDs in your database to prevent duplicate processing

Testing Webhooks

To test your webhook integration:

  • Use the "Send Test Event" button in your dashboard to send sample webhook events
  • Use tools likengrok to expose your local development server
  • Check the webhook logs in your dashboard to see delivery status and responses
  • Verify that your handler correctly processes different event types
  • Test signature verification by intentionally sending invalid signatures