Webhooks
Custom integrations via HTTP callbacks
Build custom integrations by receiving real-time HTTP notifications when events occur in 24CallDesk.
For no-code integrations, consider Zapier which connects 24CallDesk to 8,000+ apps without writing code.
What Are Webhooks?
Webhooks are HTTP callbacks:
- You provide a URL on your server
- When something happens in 24CallDesk, we send a POST request to that URL
- Your server processes the event
No polling required - get notified instantly.
Available Events
Events you can subscribe to:
| Event | Description |
|---|---|
new_call | Inbound or outbound call begins |
call_completed | Call ends with full details and transcript |
contact_replied | Contact responds via SMS or returns call |
new_appointment | New booking made through calendar |
contact_created | New contact added |
contact_updated | Contact information updated |
workflow_step_executed | Workflow step executes for a contact |
workflow_contact_completed | Contact completes all workflow steps |
Setup
1. Create a Webhook Endpoint
Your endpoint must:
- Accept HTTP POST requests
- Return 2xx status within 30 seconds
- Handle JSON payloads
Example endpoint (Node.js/Express):
app.post('/webhooks/24calldesk', (req, res) => {
const event = req.body;
// Process the event
console.log('Event type:', event.type);
console.log('Event data:', event.data);
// Acknowledge receipt
res.status(200).json({ received: true });
});2. Register the Webhook
- Go to Inbound > Team & Settings
- Click the Integrations button
- Select the Webhooks tab
- Click Add Webhook
- Select an event type and enter your endpoint URL
- Click Create Webhook
Payload Format
All webhooks follow this structure:
{
"id": "evt_abc123",
"type": "call_completed",
"created": "2024-01-15T14:30:00Z",
"data": {
// Event-specific data
}
}Example: call_completed
{
"id": "evt_abc123",
"type": "call_completed",
"created": "2024-01-15T14:30:00Z",
"data": {
"call_id": "call_xyz789",
"direction": "inbound",
"from": "+15551234567",
"to": "+15559876543",
"started_at": "2024-01-15T14:25:00Z",
"ended_at": "2024-01-15T14:30:00Z",
"duration_seconds": 300,
"outcome": "appointment_booked",
"recording_url": "https://...",
"transcript": "Customer called to schedule...",
"summary": "Booked plumbing appointment for Friday 2pm",
"contact": {
"id": "contact_456",
"name": "John Smith",
"phone": "+15551234567"
}
}
}Example: contact_replied
{
"id": "evt_def456",
"type": "contact_replied",
"created": "2024-01-15T15:00:00Z",
"data": {
"message_id": "msg_abc123",
"from": "+15551234567",
"to": "+15559876543",
"body": "Can I reschedule my appointment?",
"contact": {
"id": "contact_456",
"name": "John Smith"
}
}
}Security
Signature Verification
Every webhook includes a signature header:
X-24CallDesk-Signature: sha256=abc123...Verify it to ensure the webhook is authentic:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expected}` === signature;
}
app.post('/webhooks/24calldesk', (req, res) => {
const signature = req.headers['x-24calldesk-signature'];
const isValid = verifySignature(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process event...
});Your webhook secret is generated when you create a webhook and can be viewed in the webhook details.
IP Allowlisting
For additional security, allowlist our IPs:
34.102.136.180
34.102.136.181
34.102.136.182IP addresses may change. Subscribe to our status page for updates.
Retry Policy
Failed webhook deliveries are retried:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
After 5 failures, the event is marked as failed and logged.
Best Practices
Respond Quickly
Return 2xx within 30 seconds. For long processing:
- Acknowledge receipt immediately
- Process asynchronously
- Queue for background processing
app.post('/webhooks/24calldesk', async (req, res) => {
// Acknowledge immediately
res.status(200).json({ received: true });
// Process asynchronously
processEventAsync(req.body);
});Handle Duplicates
Webhooks may be delivered more than once. Use the event ID to deduplicate:
const processedEvents = new Set();
function handleEvent(event) {
if (processedEvents.has(event.id)) {
return; // Already processed
}
processedEvents.add(event.id);
// Process event...
}Log Everything
Keep logs for debugging:
app.post('/webhooks/24calldesk', (req, res) => {
console.log('Webhook received:', {
type: req.body.type,
id: req.body.id,
timestamp: new Date().toISOString()
});
// Process...
});Testing
Test Endpoint
Use a tool like webhook.site to inspect payloads during development.
Send Test Events
To test your webhook:
- Go to Inbound > Team & Settings > Integrations > Webhooks
- Your registered webhooks will be listed
- Trigger a real event (e.g., make a test call) to see your webhook in action
Local Development
Use ngrok to expose your local server:
ngrok http 3000Then use the ngrok URL as your webhook endpoint.
Monitoring
Track webhook health in the dashboard:
- Delivery success rate
- Average response time
- Recent failures and errors
- Event volume
Set up alerts for:
- Failed deliveries
- Slow responses
- Endpoint downtime
