Skip to content

Webhooks

Webhooks allow you to receive real-time HTTP notifications when events occur in your Biometry account. Instead of polling the API, webhooks push data to your server as soon as events happen.

Available Events

EventDescription
docauth.completedTriggered when a document authentication check completes

Webhook Management API

Create a Webhook

Configure a webhook endpoint to receive event notifications.

Authorization

This endpoint requires an API token as Bearer in the Authorization header. Go to Authorization guide for details.

Request

POST https://api.biometrysolutions.com/api-gateway/webhooks

Headers

  • Authorization* - Your API Token.

Body Parameters

ParameterTypeRequiredDescription
api_key_idstringYesThe API key ID to associate with this webhook
urlstringYesThe HTTPS endpoint URL to receive webhook events
eventsarrayYesList of events to subscribe to (e.g., ["docauth.completed"])
headersobjectNoCustom headers to include with each webhook request

Sample Request

curl --location 'https://api.biometrysolutions.com/api-gateway/webhooks' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc' \
--header 'Content-Type: application/json' \
--data '{
"api_key_id": "ak_abc123",
"url": "https://your-server.com/webhooks/biometry",
"events": ["docauth.completed"],
"headers": {
"X-Custom-Header": "my-value"
}
}'

Response

{
"data": {
"id": "wh_fe402c29-b543-4413-8624-af1a2a0b2f2c",
"api_key_id": "ak_abc123",
"project_id": "proj_xyz789",
"url": "https://your-server.com/webhooks/biometry",
"events": ["docauth.completed"],
"status": "active",
"headers": {
"X-Custom-Header": "my-value"
},
"retry_config": {
"max_retries": 5,
"initial_delay": 1000000000,
"max_delay": 300000000000,
"backoff_multiplier": 2
},
"success_count": 0,
"failure_count": 0,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"secret": "whsec_a1b2c3d4e5f6..."
},
"message": "Webhook created successfully. Save the secret - it won't be shown again."
}

List Webhooks

Get all webhook configurations for your project.

Request

GET https://api.biometrysolutions.com/api-gateway/webhooks

Headers

  • Authorization* - Your API Token.

Sample Request

curl --location 'https://api.biometrysolutions.com/api-gateway/webhooks' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc'

Response

{
"data": [
{
"id": "wh_fe402c29-b543-4413-8624-af1a2a0b2f2c",
"api_key_id": "ak_abc123",
"project_id": "proj_xyz789",
"url": "https://your-server.com/webhooks/biometry",
"events": ["docauth.completed"],
"status": "active",
"success_count": 142,
"failure_count": 3,
"last_delivered_at": "2024-01-15T14:22:00Z",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"message": "Webhooks retrieved successfully"
}

Get Webhook

Retrieve a specific webhook configuration.

Request

GET https://api.biometrysolutions.com/api-gateway/webhooks/{id}

Path Parameters

ParameterTypeDescription
idstringThe webhook configuration ID

Headers

  • Authorization* - Your API Token.

Sample Request

curl --location 'https://api.biometrysolutions.com/api-gateway/webhooks/wh_fe402c29-b543-4413-8624-af1a2a0b2f2c' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc'

Update Webhook

Update a webhook configuration.

Request

PATCH https://api.biometrysolutions.com/api-gateway/webhooks/{id}

Path Parameters

ParameterTypeDescription
idstringThe webhook configuration ID

Headers

  • Authorization* - Your API Token.

Body Parameters

ParameterTypeDescription
urlstringNew endpoint URL
eventsarrayUpdated list of events to subscribe to
statusstringWebhook status: active or disabled
headersobjectCustom headers to include

Sample Request

curl --location --request PATCH 'https://api.biometrysolutions.com/api-gateway/webhooks/wh_fe402c29-b543-4413-8624-af1a2a0b2f2c' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc' \
--header 'Content-Type: application/json' \
--data '{
"status": "disabled"
}'

Delete Webhook

Delete a webhook configuration.

Request

DELETE https://api.biometrysolutions.com/api-gateway/webhooks/{id}

Path Parameters

ParameterTypeDescription
idstringThe webhook configuration ID

Headers

  • Authorization* - Your API Token.

Sample Request

curl --location --request DELETE 'https://api.biometrysolutions.com/api-gateway/webhooks/wh_fe402c29-b543-4413-8624-af1a2a0b2f2c' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc'

Response

Returns 204 No Content on success.


Rotate Secret

Generate a new HMAC secret for a webhook. Use this if your secret is compromised.

Request

POST https://api.biometrysolutions.com/api-gateway/webhooks/{id}/rotate-secret

Path Parameters

ParameterTypeDescription
idstringThe webhook configuration ID

Headers

  • Authorization* - Your API Token.

Sample Request

curl --location --request POST 'https://api.biometrysolutions.com/api-gateway/webhooks/wh_fe402c29-b543-4413-8624-af1a2a0b2f2c/rotate-secret' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc'

Response

{
"data": {
"secret": "whsec_new_secret_value..."
},
"message": "Secret rotated successfully. Save the new secret - it won't be shown again."
}

Get Delivery History

View the delivery history for a webhook.

Request

GET https://api.biometrysolutions.com/api-gateway/webhooks/{id}/deliveries

Path Parameters

ParameterTypeDescription
idstringThe webhook configuration ID

Headers

  • Authorization* - Your API Token.

Sample Request

curl --location 'https://api.biometrysolutions.com/api-gateway/webhooks/wh_fe402c29-b543-4413-8624-af1a2a0b2f2c/deliveries' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc'

Response

{
"data": [
{
"id": "del_abc123",
"webhook_config_id": "wh_fe402c29-b543-4413-8624-af1a2a0b2f2c",
"event": "docauth.completed",
"status": "delivered",
"attempt_count": 1,
"created_at": "2024-01-15T14:22:00Z",
"delivered_at": "2024-01-15T14:22:01Z"
},
{
"id": "del_xyz789",
"webhook_config_id": "wh_fe402c29-b543-4413-8624-af1a2a0b2f2c",
"event": "docauth.completed",
"status": "failed",
"attempt_count": 3,
"last_error": "HTTP 500",
"last_status_code": 500,
"next_retry_at": "2024-01-15T14:30:00Z",
"created_at": "2024-01-15T14:20:00Z"
}
],
"message": "Deliveries retrieved successfully"
}

Delivery Statuses

StatusDescription
pendingDelivery is queued and waiting to be sent
processingDelivery is currently being sent
deliveredSuccessfully delivered (received 2xx response)
failedDelivery failed, will retry according to retry config
dead_letterAll retry attempts exhausted

Retry Delivery

Manually retry a failed or dead-lettered delivery.

Request

POST https://api.biometrysolutions.com/api-gateway/webhooks/{id}/deliveries/{delivery_id}/retry

Path Parameters

ParameterTypeDescription
idstringThe webhook configuration ID
delivery_idstringThe delivery ID to retry

Headers

  • Authorization* - Your API Token.

Sample Request

curl --location --request POST 'https://api.biometrysolutions.com/api-gateway/webhooks/wh_fe402c29-b543-4413-8624-af1a2a0b2f2c/deliveries/del_xyz789/retry' \
--header 'Authorization: Bearer eyJhbGciO...ANYea8r2xOG-Urc'

Response

Returns 202 Accepted with message “Delivery queued for retry”.


Webhook Payload

When an event occurs, we send an HTTP POST request to your configured URL with the following payload:

Headers

HeaderDescription
Content-TypeAlways application/json
X-Biometry-SignatureHMAC-SHA256 signature for verification
X-Biometry-TimestampUnix timestamp when the webhook was sent
X-Biometry-Delivery-IDUnique identifier for this delivery attempt
X-Biometry-EventThe event type (e.g., docauth.completed)

Payload Structure

{
"id": "del_abc123",
"event": "docauth.completed",
"timestamp": "2024-01-15T14:22:00Z",
"api_version": "v1",
"data": {
"request_id": "fc5605c5-1234-5678-87cc-979cd72564d4",
"session_id": "sess_fe402c29-b543-4413-8624-af1a2a0b2f2c",
"result": "pass",
"docauth_info": {
"document_type": "National Identification Card",
"country_code": "KGZ",
"nationality_code": "KGZ",
"nationality_name": "KYRGYZSTANI",
"sex": "MALE",
"first_name": "JOHN",
"father_name": "CERA",
"last_name": "DOE",
"expiry_date": "2028-08-03",
"document_number": "ID0833333",
"birth_date": "2002-04-01",
"current_result": "Passed"
},
"processed_at": "2024-01-15T14:21:59Z",
"scores_applied": false
}
}

Payload Fields

FieldTypeDescription
idstringUnique delivery ID
eventstringEvent type that triggered this webhook
timestampstringISO 8601 timestamp when the event occurred
api_versionstringAPI version (currently v1)
data.request_idstringOriginal DocAuth request ID
data.session_idstringSession ID if provided in the original request
data.resultstringOverall result: pass or fail
data.docauth_infoobjectDocument authentication details (same as DocAuth API response)
data.processed_atstringWhen the document was processed
data.scores_appliedbooleanWhether scoring rules were applied

Signature Verification

To ensure webhook requests are genuinely from Biometry, verify the signature included in the X-Biometry-Signature header.

How Signatures Work

  1. We create a signed message: {timestamp}.{payload}
  2. We compute HMAC-SHA256 using your webhook secret
  3. The signature is sent as: v1={hex_signature}

Verification Steps

  1. Extract the timestamp from X-Biometry-Timestamp header
  2. Concatenate: {timestamp}.{raw_request_body}
  3. Compute HMAC-SHA256 with your webhook secret
  4. Compare with the signature in X-Biometry-Signature header

Node.js Example

const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, timestamp, secret) {
// Create the signed message
const message = `${timestamp}.${payload}`;
// Compute expected signature
const expectedSignature = 'v1=' + crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
// Use timing-safe comparison
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express.js example
app.post('/webhooks/biometry', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-biometry-signature'];
const timestamp = req.headers['x-biometry-timestamp'];
const payload = req.body.toString();
if (!verifyWebhookSignature(payload, signature, timestamp, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
const event = JSON.parse(payload);
console.log('Received event:', event.event);
res.status(200).send('OK');
});

Retry Behavior

If your endpoint returns a non-2xx status code or times out, we automatically retry delivery with exponential backoff:

AttemptDelay
1Immediate
21 second
32 seconds
44 seconds
58 seconds (max 5 minutes)

After 5 failed attempts, the delivery is moved to the dead letter queue. You can manually retry dead-lettered deliveries via the API.

Timeout

Your endpoint must respond within 30 seconds. Requests that exceed this timeout are treated as failures and will be retried.


Best Practices

  1. Respond quickly - Return a 2xx status immediately, then process the webhook asynchronously. Long-running processing should happen in a background job.

  2. Handle duplicates - In rare cases, you may receive the same webhook more than once. Use the id field to deduplicate.

  3. Verify signatures - Always validate the X-Biometry-Signature header to ensure requests are from Biometry.

  4. Use HTTPS - Webhook URLs must use HTTPS to ensure data is encrypted in transit.

  5. Monitor deliveries - Check the delivery history regularly to catch and address any failures.

  6. Rotate secrets periodically - Use the rotate-secret endpoint to generate new secrets as part of your security practices.