Webhook Troubleshooting
This guide helps you diagnose and fix common webhook issues.
Common Issues
Not Receiving Events
Symptoms: No webhook deliveries appearing
Checklist:
- Verify webhook is enabled
- Check the correct events are subscribed
- Confirm URL is correct
- Ensure endpoint is publicly accessible
- Check firewall rules
Quick Test:
bash
# Test your endpoint externally
curl -X POST https://your-url.com/webhook \
-H "Content-Type: application/json" \
-d '{"test": true}'"Connection Refused"
Cause: Server not running or not accessible
Solutions:
- Verify server is running
- Check the port is correct
- Ensure cloud firewall allows incoming connections
- Verify HTTPS certificate is valid
"Timeout" Errors
Cause: Endpoint takes too long to respond
Solutions:
javascript
// Bad - Processing before responding
app.post('/webhook', async (req, res) => {
await processEvent(req.body); // Takes 45 seconds
res.send('OK'); // Too late!
});
// Good - Respond immediately, process async
app.post('/webhook', (req, res) => {
res.send('OK'); // Respond first
processEventAsync(req.body); // Process later
});Signature Verification Fails
Causes:
- Wrong webhook secret
- Body modified before verification (e.g., by JSON middleware)
- Using incorrect header names
Debug Steps:
javascript
// Log received values
console.log('Signature:', req.headers['x-webhook-signature']);
console.log('Timestamp:', req.headers['x-webhook-timestamp']);
console.log('Body:', JSON.stringify(req.body));
console.log('Secret:', webhookSecret.substring(0, 5) + '...');Raw Body
Verify using the raw request body, not a re-serialized version. Some frameworks (e.g., Express with express.json()) may alter whitespace. Read the raw bytes before parsing.
Duplicate Events
Cause: Your endpoint returning errors causes Voxifi to retry
Solution: Use the event_id field for idempotency
javascript
const processedEvents = new Set();
app.post('/webhook', (req, res) => {
const eventId = req.body.event_id;
if (processedEvents.has(eventId)) {
return res.send('Already processed');
}
processedEvents.add(eventId);
// Process event...
res.send('OK');
});Events in Wrong Order
Cause: Network latency or parallel delivery
Solution: Use timestamps from the payload
javascript
app.post('/webhook', (req, res) => {
const eventTime = new Date(req.body.timestamp);
const lastProcessed = getLastProcessedTime(req.body.data.call_id);
if (eventTime < lastProcessed) {
return res.send('Out of order, skipping');
}
// Process event...
});Debugging Tools
Test Event Sender
- Go to Integrations > Webhooks
- Click on your endpoint
- Click Send Test Event
- View response in real-time
Delivery Log
- Check the Delivery Log for errors
- View full request/response details
- Identify patterns in failures
Local Testing
Use ngrok for local development:
bash
# Start your server
node server.js
# Expose locally
ngrok http 3000
# Use the ngrok URL in Voxifi
# https://abc123.ngrok.io/webhookStatus Codes
Expected Responses
| Code | Meaning | Voxifi Behavior |
|---|---|---|
| 200 | Success | Marked as delivered |
| 201 | Created | Marked as delivered |
| 202 | Accepted | Marked as delivered |
| 429 | Too Many Requests | Retry with backoff |
| 4xx | Client Error | Dead-lettered (no retry) |
| 5xx | Server Error | Retry with backoff |
Error Response Format
Return helpful error messages:
javascript
app.post('/webhook', (req, res) => {
if (!verifySignature(req)) {
return res.status(401).json({
error: 'Invalid signature',
hint: 'Check webhook secret configuration'
});
}
// ...
});Getting Help
If issues persist:
- Collect delivery log entries
- Note error messages
- Include your endpoint code (remove secrets)
- Contact [email protected]