Webhook Setup
This guide walks you through setting up webhooks to receive real-time event notifications from the Audian API.
Prerequisites​
- An Audian account with API access
- An HTTPS endpoint on your server (HTTP is not supported)
- Ability to handle POST requests
- Basic understanding of webhooks and webhooks concepts
Step 1: Create a Webhook Endpoint​
Your webhook endpoint is a URL on your server that receives POST requests from Audian. It should:
- Accept HTTP POST requests
- Verify webhook signatures (covered in Signature Verification)
- Return a 2xx status code within 30 seconds
- Handle idempotent processing (for retries)
Example Endpoint (Node.js/Express)​
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Your webhook signing secret from Audian Dashboard
const WEBHOOK_SECRET = process.env.AUDIAN_WEBHOOK_SECRET;
app.post('/webhooks', (req, res) => {
// Verify the signature
const signature = req.headers['x-audian-signature'];
const timestamp = req.headers['x-audian-timestamp'];
const body = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(`${timestamp}.${body}`)
.digest('hex');
if (signature !== expected) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook event
const event = req.body;
console.log(`Received event: ${event.event}`);
// Handle the event asynchronously
handleWebhookEvent(event).catch(err => {
console.error('Error processing webhook:', err);
});
// Return 200 immediately
res.json({ received: true });
});
async function handleWebhookEvent(event) {
// Your event processing logic here
switch (event.event) {
case 'call.completed':
await processCellCompletedEvent(event.data);
break;
case 'recording.completed':
await processRecordingCompletedEvent(event.data);
break;
// ... handle other events
}
}
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
Example Endpoint (Python/Flask)​
from flask import Flask, request, jsonify
import hmac
import hashlib
import json
import os
from datetime import datetime
app = Flask(__name__)
WEBHOOK_SECRET = os.getenv('AUDIAN_WEBHOOK_SECRET')
@app.route('/webhooks', methods=['POST'])
def handle_webhook():
signature = request.headers.get('x-audian-signature')
timestamp = request.headers.get('x-audian-timestamp')
body = request.data
# Verify signature
expected_sig = hmac.new(
WEBHOOK_SECRET.encode(),
f'{timestamp}.{body.decode()}'.encode(),
hashlib.sha256
).hexdigest()
if signature != expected_sig:
return jsonify({'error': 'Invalid signature'}), 401
# Parse event
event = request.get_json()
# Process asynchronously
process_webhook_event(event)
return jsonify({'received': True})
def process_webhook_event(event):
event_type = event.get('event')
if event_type == 'call.completed':
handle_call_completed(event['data'])
elif event_type == 'recording.completed':
handle_recording_completed(event['data'])
# ... handle other event types
if __name__ == '__main__':
app.run(port=3000, debug=False)
Step 2: Register Your Webhook Endpoint​
Once your endpoint is ready, register it with Audian using the API:
curl -X POST https://api.audian.com:8443/v2/webhooks \
-H "X-Auth-Token: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-domain.com/webhooks",
"events": ["*"],
"active": true
}'
Request Parameters​
| Parameter | Type | Description |
|---|---|---|
url | string | HTTPS endpoint URL where webhook events will be sent |
events | array | List of events to subscribe to (use ["*"] for all events) |
active | boolean | Whether this webhook is active and will receive events |
description | string | Optional description for your reference |
version | string | Webhook payload version (default: v1) |
Response​
{
"id": "wh_1234567890abcdef",
"url": "https://your-domain.com/webhooks",
"events": ["*"],
"active": true,
"created_at": "2024-01-15T10:00:00Z",
"signing_secret": "whsec_abcdef1234567890"
}
Save the signing_secret - you'll need this to verify webhook signatures.
Step 3: Test Your Webhook​
Send a Test Event​
curl -X POST https://api.audian.com:8443/v2/webhooks/{webhook_id}/test \
-H "X-Auth-Token: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event": "call.completed"
}'
This will send a test webhook to your endpoint. Check your server logs to confirm receipt.
Inspect Webhook Logs​
curl https://api.audian.com:8443/v2/webhooks/{webhook_id}/logs \
-H "X-Auth-Token: YOUR_API_KEY"
Response example:
{
"data": [
{
"id": "evt_1234567890abcdef",
"webhook_id": "wh_1234567890abcdef",
"event": "call.completed",
"timestamp": "2024-01-15T10:30:00Z",
"status": "delivered",
"response_status": 200,
"attempts": 1
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 125
}
}
Managing Webhooks​
List All Webhooks​
curl https://api.audian.com:8443/v2/webhooks \
-H "X-Auth-Token: YOUR_API_KEY"
Update a Webhook​
curl -X PATCH https://api.audian.com:8443/v2/webhooks/{webhook_id} \
-H "X-Auth-Token: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": ["call.completed", "call.failed", "recording.completed"],
"active": true
}'
Delete a Webhook​
curl -X DELETE https://api.audian.com:8443/v2/webhooks/{webhook_id} \
-H "X-Auth-Token: YOUR_API_KEY"
Rotate Signing Secret​
curl -X POST https://api.audian.com:8443/v2/webhooks/{webhook_id}/rotate-secret \
-H "X-Auth-Token: YOUR_API_KEY"
Response:
{
"id": "wh_1234567890abcdef",
"signing_secret": "whsec_newarandom1234567890"
}
Best Practices​
Security​
- Use HTTPS only - HTTP endpoints are not supported
- Verify signatures - Always verify webhook signatures before processing
- Rotate secrets - Periodically rotate your webhook signing secrets
- Secure storage - Store signing secrets in environment variables, not code
- Monitor attempts - Watch for repeated failed delivery attempts
Reliability​
- Handle duplicates - Process events idempotently (same event, same result)
- Async processing - Don't block the webhook response
- Error logging - Log all errors for debugging
- Health checks - Monitor webhook delivery success rates
- Backoff strategy - Implement exponential backoff if calling external services
Performance​
- Quick responses - Return 200 within 5 seconds
- Timeouts - Set reasonable timeouts for external calls (30+ seconds)
- Batch processing - Consider batching events if processing at scale
- Rate handling - Be prepared for bursts of events during high activity
Troubleshooting​
Webhook Not Receiving Events​
- Check that the webhook is
active: true - Verify the URL is correct and publicly accessible
- Check firewall rules and network connectivity
- Review webhook logs for delivery attempts
- Verify that events match your subscription list
Signature Verification Failing​
- Confirm you're using the correct signing secret
- Check that you're using the raw request body (not parsed JSON)
- Verify the header names are correct (case-sensitive)
- Ensure the timestamp and body are concatenated correctly with a dot separator
5xx Errors on Delivery​
- Check your endpoint logs for error messages
- Verify the endpoint can handle the POST request
- Check that response headers are valid
- Monitor server resources (CPU, memory, connections)
Events Not Being Processed​
- Verify the event type is in your subscription list
- Check that events are actually occurring in your system
- Review webhook logs to confirm delivery
- Add logging to your handler to trace execution