VerifyHQ Docs

Webhooks API

Register callback URLs to receive real-time notifications when verification events occur. Webhook payloads are signed with HMAC-SHA256 for security.

POST/webhooks/configure

Register a webhook callback URL. The signing secret is returned only once — store it securely.

Request Body

ParameterTypeDescription
clientIdrequiredstringYour API client ID
callbackUrlrequiredstringHTTPS URL to receive events
eventsrequiredstring[]Events to subscribe to (at least one)

Available Events

ParameterTypeDescription
document.verifiedeventDocument passed verification
document.rejectedeventDocument failed verification
liveness.passedeventLiveness check passed
liveness.failedeventLiveness check failed
identity.verifiedeventFull identity verification approved
identity.rejectedeventIdentity verification rejected
identity.manual_revieweventFlagged for manual review
curl -X POST https://api.verifyhq.com/v1/webhooks/configure \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "client_abc123",
    "callbackUrl": "https://your-app.com/webhooks/verifyhq",
    "events": ["document.verified", "identity.verified", "liveness.passed"]
  }'

Response

201 Createdjson
{
  "id": "wh_abc123",
  "callbackUrl": "https://your-app.com/webhooks/verifyhq",
  "events": ["document.verified", "identity.verified", "liveness.passed"],
  "secret": "whsec_a1b2c3d4e5f6...",
  "message": "Store the signing secret securely — it will not be shown again. Verify webhook signatures using HMAC-SHA256 with the X-Webhook-Signature header."
}
GET/webhooks/client/:clientId

List all webhook configurations for a client.

200 OKjson
[
  {
    "id": "wh_abc123",
    "callbackUrl": "https://your-app.com/webhooks/verifyhq",
    "events": ["document.verified", "identity.verified"],
    "active": true,
    "createdAt": "2025-01-15T10:00:00Z"
  }
]
DELETE/webhooks/:id

Deactivate a webhook configuration.

200 OKjson
{
  "message": "Webhook deactivated successfully."
}

Verifying Webhook Signatures

Every webhook delivery includes an X-Webhook-Signature header. Verify it using HMAC-SHA256:

import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  );
}

// In your Express handler:
app.post('/webhooks/verifyhq', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET,
  );
  if (!isValid) return res.status(401).send('Invalid signature');
  
  // Process the event
  const { event, data } = req.body;
  console.log(event, data);
  res.status(200).send('OK');
});

Webhook Payload Format

Example Payloadjson
{
  "event": "identity.verified",
  "timestamp": "2025-01-15T10:35:00Z",
  "data": {
    "verificationId": "ver_abc123",
    "userId": "user_123",
    "status": "VERIFIED",
    "tier": "ENHANCED",
    "completedAt": "2025-01-15T10:35:00Z"
  }
}
Respond quickly
Your endpoint must respond with a 2xx status within 30 seconds. Failed deliveries are retried with exponential backoff (up to 3 retries).