{
"event": "call_ended",
"call": {
"ended_reason": "contact-ended-call",
"call_id": "b4a05730-2abc-4eb0-8066-2e4d23b53ba9",
"loop_id": "ba99c99d-19b9-4a0d-8df6-3e213088989a",
"attempt": 1,
"from_number": "+17755719467",
"direction": "outbound",
"to_number": "+14155552671",
"external_contact_id": "external-123",
"contact_id": "6bd1e7e0-6d00-4c0b-ad5b-daa72457a27d",
"contact_details": {
"company": "Art Studio Inc"
},
"contact_properties": [
{
"key": "industry",
"value": "retail",
"dataType": "string",
"label": "Industry"
}
],
"agent_id": "d8931604-92ad-45cf-9071-d9cd2afbad0c",
"triggered_at": 1731956924302,
"triggered_at_iso": "2024-11-18T15:08:44.302Z",
"started_at": 1731956932264,
"started_at_iso": "2024-11-18T15:08:52.264Z",
"ended_at": 1731957002078,
"ended_at_iso": "2024-11-18T15:10:02.078Z",
"call_length_min": 2,
"call_length_sec": 69,
"call_status": "COMPLETED",
"state": "ended",
"status": "connected",
"follow_up": null,
"transcript": "Agent: Hello...",
"transcriptObject": [
{
"role": "agent",
"content": "Hello..."
},
{
"role": "user",
"content": "Hi, I was hoping to book an appointment."
},
{
"role": "agent",
"toolActivity": "get_available_timeslots",
"type": "function_call"
},
{
"role": "agent",
"content": "I can offer you Thursday at 13:15."
}
],
"call_analysis": {
"appointment": {
"value": true,
"details": "2025-02-18T15:30:00Z"
},
"interest": {
"value": true,
"details": "The customer is interested in buying an ice cream machine"
}
},
"call_outcome": {
"custom_lost_reason": {
"value": "PRODUCT_TOO_EXPENSIVE",
"fieldSchema": {
"type": [
"string",
"null"
],
"enum": [
"CUSTOMER_NOT_INTERESTED",
"CUSTOMER_PREVIOUSLY_CONTACTED",
"PRODUCT_TOO_EXPENSIVE"
]
}
}
},
"collected_data": {
"email": {
"status": "confirmed",
"value": "frida@kahlo.com"
},
"delivery_address": {
"status": "confirmed",
"value": "Rosenthaler Straße 51, 10178 Berlin, Germany",
"latitude": 52.5253059,
"longitude": 13.4043936
}
},
"booked_slot_for": "2025-02-24T15:30:00Z",
"recording_url": "https://example.com/recording.wav",
"sip_status_code": 200,
"sip_status": "OK",
"transfer": null
},
"contact": {
"contact_id": "6bd1e7e0-6d00-4c0b-ad5b-daa72457a27d",
"external_contact_id": "external-123",
"external_url": null,
"created_at": "2024-11-18T15:00:00.000Z",
"gender": null,
"first_name": "Frida",
"last_name": "Kahlo",
"phone_number": "+14155552671",
"in_call_since": null,
"reached_at": "2024-11-18T15:08:52.264Z",
"contact_details": {
"company": "Art Studio Inc"
},
"call_attempts": 1,
"next_call_at": null,
"email": "frida@kahlo.com",
"timezone": "America/Los_Angeles",
"salutation": "Ms.",
"status": "reached",
"properties": [
{
"key": "industry",
"value": "retail",
"dataType": "string",
"label": "Industry"
}
]
}
}Events
Call ended
Payload telli sends when a call reaches a terminal state
WEBHOOK
call_ended
{
"event": "call_ended",
"call": {
"ended_reason": "contact-ended-call",
"call_id": "b4a05730-2abc-4eb0-8066-2e4d23b53ba9",
"loop_id": "ba99c99d-19b9-4a0d-8df6-3e213088989a",
"attempt": 1,
"from_number": "+17755719467",
"direction": "outbound",
"to_number": "+14155552671",
"external_contact_id": "external-123",
"contact_id": "6bd1e7e0-6d00-4c0b-ad5b-daa72457a27d",
"contact_details": {
"company": "Art Studio Inc"
},
"contact_properties": [
{
"key": "industry",
"value": "retail",
"dataType": "string",
"label": "Industry"
}
],
"agent_id": "d8931604-92ad-45cf-9071-d9cd2afbad0c",
"triggered_at": 1731956924302,
"triggered_at_iso": "2024-11-18T15:08:44.302Z",
"started_at": 1731956932264,
"started_at_iso": "2024-11-18T15:08:52.264Z",
"ended_at": 1731957002078,
"ended_at_iso": "2024-11-18T15:10:02.078Z",
"call_length_min": 2,
"call_length_sec": 69,
"call_status": "COMPLETED",
"state": "ended",
"status": "connected",
"follow_up": null,
"transcript": "Agent: Hello...",
"transcriptObject": [
{
"role": "agent",
"content": "Hello..."
},
{
"role": "user",
"content": "Hi, I was hoping to book an appointment."
},
{
"role": "agent",
"toolActivity": "get_available_timeslots",
"type": "function_call"
},
{
"role": "agent",
"content": "I can offer you Thursday at 13:15."
}
],
"call_analysis": {
"appointment": {
"value": true,
"details": "2025-02-18T15:30:00Z"
},
"interest": {
"value": true,
"details": "The customer is interested in buying an ice cream machine"
}
},
"call_outcome": {
"custom_lost_reason": {
"value": "PRODUCT_TOO_EXPENSIVE",
"fieldSchema": {
"type": [
"string",
"null"
],
"enum": [
"CUSTOMER_NOT_INTERESTED",
"CUSTOMER_PREVIOUSLY_CONTACTED",
"PRODUCT_TOO_EXPENSIVE"
]
}
}
},
"collected_data": {
"email": {
"status": "confirmed",
"value": "frida@kahlo.com"
},
"delivery_address": {
"status": "confirmed",
"value": "Rosenthaler Straße 51, 10178 Berlin, Germany",
"latitude": 52.5253059,
"longitude": 13.4043936
}
},
"booked_slot_for": "2025-02-24T15:30:00Z",
"recording_url": "https://example.com/recording.wav",
"sip_status_code": 200,
"sip_status": "OK",
"transfer": null
},
"contact": {
"contact_id": "6bd1e7e0-6d00-4c0b-ad5b-daa72457a27d",
"external_contact_id": "external-123",
"external_url": null,
"created_at": "2024-11-18T15:00:00.000Z",
"gender": null,
"first_name": "Frida",
"last_name": "Kahlo",
"phone_number": "+14155552671",
"in_call_since": null,
"reached_at": "2024-11-18T15:08:52.264Z",
"contact_details": {
"company": "Art Studio Inc"
},
"call_attempts": 1,
"next_call_at": null,
"email": "frida@kahlo.com",
"timezone": "America/Los_Angeles",
"salutation": "Ms.",
"status": "reached",
"properties": [
{
"key": "industry",
"value": "retail",
"dataType": "string",
"label": "Industry"
}
]
}
}Call outcome
Three fields describe what happened, and they are the ones to build on:state— where the call is in its lifecyclestatus— how it ended, once it has endedfollow_up— the follow-up telli scheduled, if any
call_status is deprecated and will be removed. Use state, status, and follow_up instead.call_status | state | status | follow_up |
|---|---|---|---|
INITIATED | queued | null | null |
RINGING | ringing | null | null |
IN_PROGRESS | in_progress | null | null |
IN_PROGRESS | processing | null | null |
COMPLETED | ended | connected | null |
ANSWERED | ended | connected | set |
NOT_REACHED | ended | not_connected | null |
VOICEMAIL | ended | voicemail | null |
ERROR | ended | failed | null |
call_status is lossy in both directions: IN_PROGRESS cannot tell in_progress from processing, and COMPLETED and ANSWERED differ only by whether a follow-up was scheduled.
Analysis fields
The payload carries two kinds of analysis, and their shapes differ.call_analysis holds telli’s built-in analysis. Every entry has a boolean value; entries that support supporting detail also carry details:
{
"appointment": {
"value": true,
"details": "2025-02-18T15:30:00Z"
}
}
call_outcome holds the custom analysis fields you configure in telli. Entries are keyed by field name and carry the extracted value plus the schema it was validated against:
{
"custom_lost_reason": {
"value": "PRODUCT_TOO_EXPENSIVE",
"fieldSchema": {
"type": ["string", "null"],
"enum": ["CUSTOMER_NOT_INTERESTED", "CUSTOMER_PREVIOUSLY_CONTACTED", "PRODUCT_TOO_EXPENSIVE"]
}
}
}
call_outcome entry may also include reason, explaining why the agent chose that value, and error when extraction failed.
Collected data
When the agent has Collect Data tasks,collected_data reports what was gathered and confirmed during the call:
{
"email": {
"status": "confirmed",
"value": "user@example.com"
},
"delivery_address": {
"status": "confirmed",
"value": "Rosenthaler Straße 51, 10178 Berlin, Germany",
"latitude": 52.5253059,
"longitude": 13.4043936
},
"case_number": {
"status": "declined",
"value": null
}
}
confirmed entries carry a value you should trust. Address entries also include latitude and longitude when address validation produced coordinates; other task types omit these fields. When no Collect Data tasks are configured or none were triggered, collected_data is empty or null — handle both.
Recording
recording_url links to the audio of the call, or is null when recording is disabled or unavailable. The link expires 1 hour after the webhook is sent, so download the recording right away if you need to keep it.
Retry attempts
Automatic retries within one scheduled sequence share aloop_id, and attempt counts up within it. Scheduling the same contact again starts a new loop, so use contact_id to track a contact across sequences.Body
application/json
Response
2XX
Acknowledged. Return any 2xx within 15 seconds or the message is retried.
Was this page helpful?