Webhooks

Overview

Webhooks allow you to receive real-time notifications when verifications are completed. Instead of polling our API for status updates, we'll automatically send verification results to your specified URL endpoint as soon as they're available.


How Webhooks Work

The Webhook Flow

  1. Setup: You configure a webhook URL in the Partner Portal

  2. Verification Process: A user completes their verification

  3. Automatic Notification: We immediately send the verification results to your webhook URL

  4. Processing: Your application receives and processes the verification data

Benefits of Using Webhooks

  • Real-time Updates: Get notified instantly when verifications complete

  • Reduced API Calls: No need to continuously poll for status updates

  • Better User Experience: Process results immediately and update your application

  • Reliable Delivery: Automatic retry mechanism ensures delivery


Creating a Webhook in the Partner Portal

Step-by-Step Setup

1. Navigate to Webhook Management

  1. Log into the Partner Portal

    • Go to your partner dashboard

    • Navigate to the main menu

  2. Access Webhook Settings

    • Click on "Webhooks" in the sidebar

    • You'll see your existing webhooks (if any) and options to create new ones

2. Create Your First Webhook

  1. Start Webhook Creation

    • Click the "Create Webhook" button

    • This opens the webhook configuration form

  2. Configure Basic Settings

    Webhook URL (Required)

    • Enter your endpoint URL: https://your-domain.com/webhook

    • This is where we'll send verification notifications

    • Must be a valid HTTPS URL for security

    Status

    • Toggle "Active" to enable the webhook

    • You can create inactive webhooks and enable them later

3. Advanced Configuration (Optional)

Webhook Authentication Header

  • Enter a key/value header verification

  • We'll add that header to each webhook request

4. Save Your Webhook

  1. Review Settings

    • Double-check your webhook URL

    • Ensure all settings are correct

  2. Create Webhook

    • Click "Save Webhook" or "Create"

    • Your webhook is now active and ready to receive notifications

Example Webhook Configuration

Webhook URL: https://api.yourcompany.com/webhooks/cr3dentials
Status: Active
Header: secret: your-secure-secret-key-here

Managing Your Webhooks

Viewing Webhook Details

In the Webhooks section, you can see:

  • Webhook URL: The endpoint we're sending notifications to

  • Status: Active/Inactive status

  • Created Date: When the webhook was set up

  • Last Delivery: Timestamp of the most recent notification

  • Success Rate: Percentage of successful deliveries

Webhook Actions

For each webhook, you can:

  • Edit: Modify the URL, secret, or payload template

  • Test: Send a test notification to verify your endpoint

  • View Logs: See delivery history and any errors

  • Deactivate: Temporarily disable notifications

  • Delete: Permanently remove the webhook

Monitoring Webhook Health

  1. Delivery Status

    • Green: Webhook is delivering successfully

    • Yellow: Some delivery issues (temporary failures)

    • Red: Multiple delivery failures

  2. Troubleshooting Failed Deliveries

    • Check webhook logs for error details

    • Verify your endpoint is responding with 2xx status codes

    • Ensure your server responds within 10 seconds


Understanding Webhook Notifications

When Webhooks Are Triggered

We send webhook notifications when:

  • ✅ A verification is successfully completed

  • ✅ A verification fails

  • ✅ A verification expires

  • ✅ Manual review is completed

Default Webhook Payload

When a verification completes, your webhook will receive:

{
  "type": "verification.completed",
  "status": "success",
  "data": {
    "verificationId": "ver_abc123",
    "sessionId": 123,
    "stepId": 456,
    "status": "VERIFIED",
    "proofData": {
      "income": {
        "monthlyAmount": 5000,
        "verified": true,
        "source": "chase-bank"
      }
    },
    "formattedData": {
      "incomeVerified": true,
      "verificationScore": 95
    },
    "metadata": {
      "dataSource": "chase-bank",
      "processingTimeMs": 15000,
      "verifiedAt": "2024-01-15T14:30:00Z"
    }
  }
}

Payload Fields Explained

Field
Description

type

Event type (e.g., "verification.completed")

status

Overall result: "success" or "failed"

data.verificationId

Unique identifier for this verification

data.sessionId

Your session ID from when you created the verification

data.status

Detailed verification status

data.proofData

Raw verification data from the source

data.formattedData

Processed, ready-to-use verification results

data.metadata

Additional information about the verification process


Implementing Your Webhook Endpoint

Basic Webhook Handler Example

// Node.js/Express example
app.post('/webhook/cr3dentials', (req, res) => {
  try {
    const webhook = req.body;
    
    // Process the verification result
    if (webhook.type === 'verification.completed') {
      handleVerificationCompleted(webhook.data);
    }
    
    // Always respond with 200 to acknowledge receipt
    res.status(200).json({ received: true });
    
  } catch (error) {
    console.error('Webhook processing error:', error);
    res.status(500).json({ error: 'Processing failed' });
  }
});

function handleVerificationCompleted(data) {
  // Update your database
  updateUserVerificationStatus(data.sessionId, data.status);
  
  // Send notification to user
  if (data.status === 'VERIFIED') {
    sendSuccessNotification(data.sessionId);
  } else {
    sendFailureNotification(data.sessionId);
  }
}

Security Best Practices

1. Verify Webhook Signatures

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  const calculatedSignature = hmac
    .update(JSON.stringify(payload))
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(calculatedSignature)
  );
}

// Use in your webhook handler
app.post('/webhook/cr3dentials', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const isValid = verifyWebhookSignature(req.body, signature, 'your-secret');
  
  if (!isValid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Process webhook...
});

2. Handle Duplicate Deliveries

const processedWebhooks = new Set();

app.post('/webhook/cr3dentials', (req, res) => {
  const webhookId = req.body.data.verificationId;
  
  // Check if we've already processed this webhook
  if (processedWebhooks.has(webhookId)) {
    return res.status(200).json({ message: 'Already processed' });
  }
  
  // Process the webhook
  processVerification(req.body);
  
  // Mark as processed
  processedWebhooks.add(webhookId);
  
  res.status(200).json({ received: true });
});

Webhook Best Practices

Response Requirements

Your webhook endpoint must:

Do:

  • Respond with a 2xx status code (200, 201, 204)

  • Respond within 10 seconds

  • Handle duplicate deliveries gracefully

  • Verify webhook signatures when using secrets

Don't:

  • Return 3xx, 4xx, or 5xx status codes

  • Take longer than 10 seconds to respond

  • Process webhooks synchronously if they involve heavy operations

Error Handling and Retries

Our Retry Policy:

  • We automatically retry failed deliveries

  • Exponential backoff: 1s, 2s, 4s, 8s, 16s intervals

  • After 5 failed attempts, the webhook is marked as inactive

  • You can reactivate it once the issue is resolved

Monitoring Delivery Issues:

  1. Check webhook logs in the Partner Portal

  2. Look for patterns in failed deliveries

  3. Verify your endpoint is responding correctly

  4. Test your webhook with the built-in test feature

Performance Optimization

// Good: Process webhooks asynchronously
app.post('/webhook/cr3dentials', (req, res) => {
  // Immediately acknowledge receipt
  res.status(200).json({ received: true });
  
  // Process asynchronously
  setImmediate(() => {
    processVerificationData(req.body);
  });
});

// Or use a queue for heavy processing
app.post('/webhook/cr3dentials', (req, res) => {
  // Add to processing queue
  verificationQueue.add('process-webhook', req.body);
  
  // Immediate response
  res.status(200).json({ received: true });
});

Testing Your Webhook

Using the Test Feature

  1. Access Test Function

    • Go to your webhook in the Partner Portal

    • Click "Test Webhook"

  2. Send Test Notification

    • We'll send a sample verification payload to your endpoint

    • Check if your endpoint responds correctly

  3. Review Results

    • Success: Your endpoint is working correctly

    • Failure: Check the error message and fix your endpoint

Manual Testing

# Test your webhook endpoint manually
curl -X POST https://your-domain.com/webhook \
  -H "Content-Type: application/json" \
  -H "x-webhook-signature: test-signature" \
  -d '{
    "type": "verification.completed",
    "status": "success",
    "data": {
      "verificationId": "test_123",
      "sessionId": 123,
      "status": "VERIFIED"
    }
  }'

Troubleshooting Common Issues

Webhook Not Receiving Notifications

Check:

  • [ ] Webhook URL is correct and accessible

  • [ ] Webhook status is "Active"

  • [ ] Your server is running and responding

  • [ ] Firewall allows incoming HTTPS requests

  • [ ] SSL certificate is valid

Delivery Failures

Common Causes:

  • Endpoint returns non-2xx status codes

  • Server timeout (>10 seconds response time)

  • SSL/TLS certificate issues

  • Firewall blocking requests

Solutions:

  1. Check webhook logs for specific error messages

  2. Test your endpoint manually

  3. Verify SSL certificate validity

  4. Ensure quick response times

Security Issues

If webhook signatures don't match:

  • Verify you're using the correct secret

  • Check signature calculation algorithm

  • Ensure you're signing the exact payload we send

Last updated