Webhooks

Receive real-time notifications when API-triggered calls complete. Webhooks eliminate the need for polling and enable event-driven architectures.

Overview

When you trigger a call with a callbackUrl, a webhook is delivered to that URL when the call ends (either completed or failed). This is the recommended approach for production integrations.

Webhooks are delivered per-call, not per-campaign. Each call with a callbackUrl will receive its own webhook delivery.

Webhook Payload

When a call completes, a POST request is sent to your callbackUrl with the following JSON payload:

{
"event": "call.completed",
"callId": "8f14e45f-ceea-467f-a830-cf60f5e5a214",
"campaignId": "357b188c-c618-4f95-84b1-cbe26b8ce3e0",
"phoneNumber": "+14155551234",
"status": "completed",
"duration": 127,
"endReason": "agent_hangup",
"analysis": {
"sentiment": {
"overall": "positive",
"score": 0.85,
"confidence": 0.92
},
"humanContact": {
"reached": true,
"type": "human",
"confidence": 0.95
},
"objectives": [
{
"id": "1",
"name": "Confirm order",
"achieved": true,
"confidence": 0.88
}
]
},
"metadata": {
"orderId": "123",
"source": "shopify"
},
"completedAt": "2024-01-15T14:32:07Z"
}

Event Types

EventDescription
call.completedCall finished successfully (human or agent hangup)
call.failedCall failed (timeout, connection error, or no answer)

Payload Fields

FieldTypeDescription
eventstringEvent type (call.completed or call.failed)
callIdstringUnique identifier for the call
campaignIdstringThe API campaign the call was triggered from
phoneNumberstringThe phone number that was called
statusstringFinal call status
durationnumberCall duration in seconds (null for failed calls)
endReasonstringWhy the call ended (hangup, agent_hangup, timeout, etc.)
analysisobjectAI-powered call analysis (may be null if analysis is still processing)
metadataobjectThe custom metadata you passed when triggering the call
completedAtstringISO 8601 timestamp of when the call ended

Retry Behavior

If your endpoint returns an error or times out, the webhook will be retried with exponential backoff:

AttemptDelay
1st retry1 second
2nd retry5 seconds
3rd retry15 seconds
Your endpoint should return a 2xx status code within 10 seconds to be considered successful. Webhook delivery is fire-and-forget — failures do not affect call processing.

Requirements

  • The callbackUrl must use HTTPS
  • Your endpoint must respond within 10 seconds
  • Return any 2xx status code to acknowledge receipt
  • Webhooks may be delivered more than once — design your handler to be idempotent

Example Webhook Handler

// Express.js example
app.post('/webhooks/call-complete', (req, res) => {
const { event, callId, status, analysis, metadata } = req.body;
console.log(`Call ${callId} ${event}: ${status}`);
if (event === 'call.completed' && analysis) {
// Process call results
const sentiment = analysis.sentiment?.overall;
const objectivesAchieved = analysis.objectives
?.filter(o => o.achieved)
.map(o => o.name);
// Update your records using the metadata
updateOrder(metadata.orderId, {
callCompleted: true,
sentiment,
objectivesAchieved,
});
}
// Acknowledge receipt
res.status(200).json({ received: true });
});