Verify webhook signatures (HMAC-SHA256)
Cryptographically verify that an incoming webhook came from VoxReach.
01
Set a signing secret
- At /integrations/webhooks → click your webhook → Secret field.
- Generate a random 32-char string. Save it on both sides — VoxReach signs with it, you verify with it.
02
Headers we send
- X-VoxReach-Event: call.ended
- X-VoxReach-Signature: sha256=
- Content-Type: application/json
03
Verify in Node.js
- const crypto = require('node:crypto');
- const expected = crypto.createHmac('sha256', process.env.WEBHOOK_SECRET).update(rawBody).digest('hex');
- const received = req.headers['x-voxreach-signature'].replace('sha256=', '');
- if (crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) { /* valid */ }
04
Verify in PHP
- $expected = hash_hmac('sha256', $rawBody, $secret);
- $received = str_replace('sha256=', '', $_SERVER['HTTP_X_VOXREACH_SIGNATURE']);
- if (hash_equals($expected, $received)) { /* valid */ }
05
Verify in Python
- import hmac, hashlib
- expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
- received = request.headers['X-VoxReach-Signature'].replace('sha256=','')
- if hmac.compare_digest(expected, received): pass
06
Replay attack prevention
- VoxReach also sends X-VoxReach-Timestamp.
- Reject any webhook older than 5 minutes — replays a malicious actor would attempt.
Related articles
Tenant API access
Per-tenant API key. Push leads, fetch transcripts, query usage. Rate-limited 120 req/min.
Webhook subscriptions
Subscribe to events: call.ended, call.interested, call.opt_out, sms.received, lead.imported.
Trigger an outbound call via API (for IT teams)
POST a call from your stack — webhook + SDK + curl examples.
API rate limits + retry behaviour
What our limits are, how you'll know when you hit them, how to back off properly.
Still stuck?
Email hello@voxreach.com.au — we reply within 2 business hours during AEST hours.
Open a ticket