Webhooks
Telephony.io uses webhooks to send real-time event notifications to your server. When an event occurs (such as a call completing or a verification code being checked), we send an HTTP POST request to the webhook URL you've configured in your dashboard.
Supported Events
You can subscribe to the following events when configuring your webhook endpoints:
call.completed
Triggered when a voice call ends. This event includes the call duration, cost, and other metadata about the completed call.
verify.checked
Triggered when a 2FA verification code is successfully validated. This event confirms that a user has completed the verification flow.
Security
All webhook requests are signed to ensure they originate from Telephony.io. We include an X-Telephony-Signature header with every webhook request.
This signature is an HMAC-SHA256 hash of the request body, computed using your endpoint's signing secret. You must verify this signature to ensure the webhook is authentic and hasn't been tampered with.
Verifying the Signature
Here's how to verify the webhook signature in Node.js:
const crypto = require('crypto');
function verifyWebhook(req, secret) {
const signature = req.headers['x-telephony-signature'];
const body = JSON.stringify(req.body);
const hash = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
if (hash === signature) {
// Signature is valid - webhook is authentic
return true;
} else {
// Invalid signature - reject this webhook
return false;
}
}Important: Always verify the signature before processing the webhook payload. Reject any requests with invalid signatures.
Payload Structure
All webhook payloads follow a consistent structure with an event field indicating the event type, a data field containing event-specific information, and metadata fields.
call.completed Payload
{
"event": "call.completed",
"data": {
"callId": "550e8400-e29b-41d4-a716-446655440000",
"duration": 30,
"cost": 0.05,
"from_number": "+61412345678",
"to_number": "+61487654321"
},
"timestamp": "2024-12-10T12:30:00.000Z",
"user_id": "user_abc123"
}verify.checked Payload
{
"event": "verify.checked",
"data": {
"phone": "+61412345678",
"status": "valid",
"code": "123456"
},
"timestamp": "2024-12-10T12:30:00.000Z",
"user_id": "user_abc123"
}Best Practices
- Always verify signatures: Never process a webhook without verifying the HMAC signature first
- Respond quickly: Return a 200 OK response as soon as you receive the webhook. Process the event asynchronously if needed
- Handle duplicates: Due to network issues, you may receive the same webhook multiple times. Use the event ID or timestamp to deduplicate
- Secure your endpoint: Use HTTPS for your webhook URL to ensure the payload is encrypted in transit
- Monitor delivery logs: Check the webhook delivery logs in your dashboard to debug any issues
Debugging
If your webhooks aren't being delivered:
- Check that your endpoint is publicly accessible and returns a 2xx response
- Verify your webhook URL is correct in the dashboard
- Review the delivery logs in the Webhooks section of your dashboard
- Ensure your server can handle the request within 10 seconds