Skip to content

Webhooks

Instead of polling GET /v1/verify/status/:jobId, you can provide a webhook_url when creating a verification request. BizVerify will POST to that URL when the job completes, fails, or is refunded.

Include webhook_url in your verification request:

Terminal window
curl -X POST https://api.bizverify.co/v1/verify \
-H "Content-Type: application/json" \
-H "X-API-Key: bv_live_abc123..." \
-d '{
"entity_name": "Acme Corporation",
"jurisdiction": "us-fl",
"webhook_url": "https://your-app.com/webhooks/bizverify"
}'

Sent when a verification job finishes successfully.

{
"event": "verification.completed",
"job_id": "job_abc123",
"jurisdiction": "us-fl",
"entity_name": "Acme Corporation",
"status": "completed",
"data": {
"entity_name": "ACME CORPORATION",
"entity_type": "corporation",
"status": "active",
"jurisdiction": "us-fl",
"formation_date": "2015-03-12",
"confidence": 95
},
"credits_charged": 1,
"credits_refunded": false,
"completed_at": "2026-04-02T12:00:00.000Z"
}

Sent when a verification job fails after all retry attempts.

{
"event": "verification.failed",
"job_id": "job_abc123",
"jurisdiction": "us-fl",
"entity_name": "Acme Corporation",
"status": "failed",
"error": "Data source timeout: the official source did not respond in time",
"credits_charged": 1,
"credits_refunded": true,
"completed_at": "2026-04-02T12:05:00.000Z"
}

Sent when an admin manually refunds credits for a job.

{
"event": "verification.refunded",
"job_id": "job_abc123",
"jurisdiction": "us-fl",
"entity_name": "Acme Corporation",
"status": "refunded",
"credits_charged": 1,
"credits_refunded": true,
"completed_at": "2026-04-02T12:10:00.000Z"
}
PropertyValue
MethodPOST
Content-Typeapplication/json
User-AgentBizVerify-Webhook/1.0
SignatureX-BizVerify-Signature header (HMAC-SHA256)
Timeout10 seconds per attempt
Retries3 retries (4 total attempts)
BackoffExponential (1s, 2s, 4s)
SuccessAny 2xx HTTP response

Every webhook delivery includes an X-BizVerify-Signature header containing an HMAC-SHA256 signature of the request body. Use this to verify that the request came from BizVerify and hasn’t been tampered with.

The header format is sha256=<hex-encoded-signature>.

import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyWebhookSignature(body, signature, secret) {
const expected = 'sha256=' + createHmac('sha256', secret)
.update(body)
.digest('hex');
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
// In your webhook handler:
app.post('/webhooks/bizverify', (req, res) => {
const signature = req.headers['x-bizverify-signature'];
if (!signature || !verifyWebhookSignature(req.rawBody, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook payload
const event = req.body;
console.log(`Received ${event.event} for job ${event.job_id}`);
res.status(200).send('OK');
});
  • Respond quickly. Return a 200 status immediately and process the payload asynchronously. If your endpoint takes longer than 10 seconds, the delivery will be marked as failed and retried.
  • Handle duplicates. In rare cases (e.g., network issues), you may receive the same event more than once. Use job_id as an idempotency key.
  • Verify the signature. Always verify the X-BizVerify-Signature header to ensure the request came from BizVerify. See Verifying signatures above.
  • Use HTTPS. Always use an https:// URL for your webhook endpoint.