{
"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": "[email protected]"
},
"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",
"appointments": [
{
"id": "c3809aea-0650-461a-ba36-31da19346cd8",
"starts_at": "2025-02-24T15:30:00.000Z",
"timezone": "Europe/Berlin",
"status": "booked",
"hosts": [
{
"name": "Alex Smith",
"email": "[email protected]"
}
],
"reference": {
"provider": "bookingtime",
"booking_template_id": "template-123",
"appointment_id": "appointment-123",
"organization_id": "organization-123"
}
}
],
"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": "[email protected]",
"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": "[email protected]"
},
"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",
"appointments": [
{
"id": "c3809aea-0650-461a-ba36-31da19346cd8",
"starts_at": "2025-02-24T15:30:00.000Z",
"timezone": "Europe/Berlin",
"status": "booked",
"hosts": [
{
"name": "Alex Smith",
"email": "[email protected]"
}
],
"reference": {
"provider": "bookingtime",
"booking_template_id": "template-123",
"appointment_id": "appointment-123",
"organization_id": "organization-123"
}
}
],
"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": "[email protected]",
"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": "[email protected]"
},
"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.
Appointments
call.appointments contains bookings recorded during the call, including their start time (starts_at, in UTC), status, hosts, and provider identifiers. It is empty when none were recorded. Failed booking attempts are excluded.
booked describes booking creation, not customer confirmation. pending means booking completion or provider confirmation is still required; unknown means the integration reported no status. Later cancellations or rescheduling at the provider are not reflected.
call.booked_slot_for is deprecated and remains available for compatibility. Use call.appointments for booking details. Older calls can have call.booked_slot_for set while call.appointments is empty.
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?