Webhook Lifecycle Events
Webhooks allow external systems to enrich calls with dynamic data at call start and receive call details when calls end.
Webhook Events
| Event | Trigger |
|---|---|
new_outbound_call | Outbound call starts |
new_inbound_call | Inbound call starts |
call_ended | Call ends |
Call Start Webhook
When a call starts, a POST request is sent to the configured webhook URL.
Request Format (JSON-RPC 2.0)
{
"id": "uuid",
"jsonrpc": "2.0",
"method": "webhook/lifecycle",
"metadata": {},
"params": {
"event": "new_outbound_call",
"timestamp": "2024-01-15T10:30:00.000Z",
"metadata": {},
"agent": {
"id": "agent-uuid",
"timezone": "America/New_York"
},
"call": {
"id": "call-uuid",
"status": "initializing",
"direction": "outbound",
"channel": "phone",
"caller": "+1234567890",
"callee": "+0987654321",
"userPhoneNumber": "+0987654321",
"personalization": {}
}
}
}Request Fields
| Field | Type | Description |
|---|---|---|
params.event | string | new_outbound_call or new_inbound_call |
params.agent.id | string | Agent UUID |
params.call.id | string | Call UUID |
params.call.direction | string | inbound or outbound |
params.call.channel | string | web, phone, or whatsapp |
params.call.userPhoneNumber | string | User's phone number |
Expected Response
The webhook should return a JSON response with a result object.
Response Format
{
"result": {
"dynamic_data": {
"customer_name": "John Doe",
"account_balance": 150.50,
"is_premium": true
},
"personalization": {
"language": "en"
},
"additional_context": "Customer has an open support ticket #1234",
"metadata": {
"crm_id": "CRM-12345",
"segment": "enterprise"
}
}
}Response Fields
| Field | Type | Description |
|---|---|---|
dynamic_data | object | Key-value pairs for variable substitution |
personalization.language | string | ISO 639-1 language code (e.g., en, es, he) |
additional_context | string | Additional context injected into agent prompt |
metadata | object | Pass-through metadata sent back at call end |
Call End Webhook
When a call ends, the same webhook receives a call_ended event with full call details.
Request Format
{
"id": "uuid",
"jsonrpc": "2.0",
"method": "webhook/lifecycle",
"metadata": {},
"params": {
"event": "call_ended",
"timestamp": "2024-01-15T10:35:00.000Z",
"metadata": {
"crm_id": "CRM-12345",
"segment": "enterprise"
},
"agent": {
"id": "agent-uuid",
"timezone": "America/New_York"
},
"call": {
"id": "call-uuid",
"status": "ended",
"direction": "outbound",
"channel": "phone",
"caller": "+1234567890",
"callee": "+0987654321",
"userPhoneNumber": "+0987654321",
"personalization": { "language": "en" },
"ended_at": "2024-01-15T10:35:00.000Z",
"ended_by": "user",
"duration": 300,
"transcript": [
{ "role": "assistant", "text": "Hello, how can I help you today?" },
{ "role": "user", "text": "I have a question about my account." }
],
"summary": "Customer inquired about account balance.",
"recording_url": "https://storage.example.com/recordings/call.wav",
"objective_met": true,
"extraction_data": {
"customer_sentiment": "positive",
"issue_category": "billing"
}
}
}
}Additional Call End Fields
| Field | Type | Description |
|---|---|---|
call.ended_at | string | ISO 8601 timestamp when call ended |
call.ended_by | string | user, agent, or system |
call.duration | number | Call duration in seconds |
call.transcript | array | Array of { role, text } objects |
call.summary | string | AI-generated call summary |
call.recording_url | string | URL to call recording (if enabled) |
call.objective_met | boolean | Whether the call objective was achieved |
call.extraction_data | object | Custom extracted fields (configured per agent) |
Error Handling
- Webhook failures do not stop the call
- If webhook times out or returns invalid JSON, the call continues without enrichment
- Errors are logged but not exposed to end users
- Default timeout: 5000ms (5 seconds), configurable per agent
