call_analyzed is the last call event. It carries the whole call again, now with call_analysis filled in: the summary, sentiment, whether the call succeeded, voicemail detection and every Post-Call Extraction field you defined.
When it fires#
- The call ends and
call_endedis sent. - Post-call analysis runs in parallel with that delivery, using the agent's
post_call_analysis_model(defaultgpt-5.6-terra). - Once the analysis is stored and the
call_endeddelivery has finished (including retries),call_analyzedis sent.
It also fires again when you re-run analysis on one call, from the call drawer's Rerun button or POST /rerun-call-analysis/:call_id.
It does not fire for a bulk Backfill (/backfill-call-analysis). Backfills update stored calls silently.
It fires for not_connected calls too. Their analysis is based on an empty transcript.
Which settings enable it#
call_analyzedin the agent'swebhook_events(on by default).- A URL: the agent's
webhook_url, else the workspace URL. - The fields come from the agent's Post-Call Extraction settings (
post_call_analysis_data) and the preset promptsanalysis_summary_prompt,analysis_successful_promptandanalysis_user_sentiment_prompt. See Define post-call extraction.
Payload#
{
"event": "call_analyzed",
"call": {
"call_id": "call_3ffd3f3831b0d4e1a2c96f07",
"call_type": "phone_call",
"agent_id": "agent_5b0e2c7d9a1f4e3b8c6d2a10",
"agent_version": 2,
"agent_name": "Bondi Dental Front Desk",
"call_status": "ended",
"direction": "inbound",
"from_number": "+61412345678",
"to_number": "+61291234567",
"metadata": {
"sip_headers": { "x-clinic-id": "bondi-01" }
},
"retell_llm_dynamic_variables": {
"x-clinic-id": "bondi-01",
"business_name": "Bondi Dental"
},
"collected_dynamic_variables": {
"patient_name": "Mia Chen"
},
"start_timestamp": 1760672019481,
"end_timestamp": 1760672113681,
"duration_ms": 94200,
"transcript": "Agent: Hi, thanks for calling Bondi Dental, this is Ava. How can I help you today?\nUser: Hi, I'd like to book a check-up and clean.\nAgent: Sure. Can I get your name, please?\nUser: Mia Chen.\nAgent: Thanks Mia. I have Tuesday at 9am or Wednesday at 2pm. Which suits you?\nUser: Tuesday at 9 works.\nAgent: You're booked for Tuesday at 9am. See you then.",
"transcript_object": [
{ "role": "agent", "content": "Hi, thanks for calling Bondi Dental, this is Ava. How can I help you today?", "words": [] },
{ "role": "user", "content": "Hi, I'd like to book a check-up and clean.", "words": [] },
{ "role": "agent", "content": "Sure. Can I get your name, please?", "words": [] },
{ "role": "user", "content": "Mia Chen.", "words": [] },
{ "role": "agent", "content": "Thanks Mia. I have Tuesday at 9am or Wednesday at 2pm. Which suits you?", "words": [] },
{ "role": "user", "content": "Tuesday at 9 works.", "words": [] },
{ "role": "agent", "content": "You're booked for Tuesday at 9am. See you then.", "words": [] }
],
"transcript_with_tool_calls": [
{ "role": "agent", "content": "Hi, thanks for calling Bondi Dental, this is Ava. How can I help you today?", "ts": 1760672019702 },
{ "role": "user", "content": "Hi, I'd like to book a check-up and clean.", "ts": 1760672025330 },
{ "role": "agent", "content": "Sure. Can I get your name, please?", "ts": 1760672027010 },
{ "role": "user", "content": "Mia Chen.", "ts": 1760672031480 },
{ "role": "agent", "content": "Thanks Mia. I have Tuesday at 9am or Wednesday at 2pm. Which suits you?", "ts": 1760672033400 },
{ "role": "user", "content": "Tuesday at 9 works.", "ts": 1760672040910 },
{ "role": "agent", "content": "You're booked for Tuesday at 9am. See you then.", "ts": 1760672044020 }
],
"recording_url": "https://tried-recordings.s3.ap-southeast-2.amazonaws.com/ws_7d1c0a9e4b2f6a8c3e5d1b90/call_3ffd3f3831b0d4e1a2c96f07/mixed.ogg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=86400&X-Amz-Signature=4b1d...",
"recording_multi_channel_url": null,
"public_log_url": "https://api.tried.com.au/public/calls/call_3ffd3f3831b0d4e1a2c96f07/log?exp=1761276921300&sig=5d8a1c4f7b0e3a6d9c2f5b8e1a4d7c0f3b6e9a2d5c8f1b4e7a0d3c6f9b2e5a8d",
"knowledge_base_retrieved_contents_url": "https://api.tried.com.au/public/calls/call_3ffd3f3831b0d4e1a2c96f07/kb-retrievals?exp=1761276921300&sig=8b1e4a7d0c3f6b9e2a5d8c1f4b7e0a3d6c9f2b5e8a1d4c7f0b3e6a9d2c5f8b1e",
"stir_shaken_attestation": "A",
"transfer_destination": null,
"llm_token_usage": { "values": [1834, 1902, 2210, 2265], "average": 2053, "num_requests": 4 },
"disconnection_reason": "user_hangup",
"call_analysis": {
"call_summary": "Mia Chen called to book a check-up and clean. The agent offered Tuesday 9am or Wednesday 2pm and booked Tuesday at 9am.",
"in_voicemail": false,
"user_sentiment": "Positive",
"call_successful": true,
"custom_analysis_data": {
"appointment_booked": true,
"appointment_type": "check-up and clean",
"preferred_day": "Tuesday",
"new_patient": false
}
},
"latency": {
"e2e": { "p50": 742, "p90": 911, "p95": 911, "p99": 911, "max": 911, "min": 655, "num": 4, "values": [655, 742, 801, 911] }
},
"call_cost": {
"product_costs": [
{ "product": "voice_infra", "unit_price": 0.08, "cost": 0.126667 },
{ "product": "gpt-5.6-terra", "unit_price": 0.1, "cost": 0.158333 },
{ "product": "voice_standard", "unit_price": 0.06, "cost": 0.095 }
],
"total_duration_seconds": 95,
"combined_cost": 0.38
},
"batch_call_id": null,
"contact_id": "contact_6e2a9c1f4b7d0e3a5c8f1b24"
}
}Fields#
The call fields are the same as in call_ended and are documented on Call object. This event adds call_analysis:
| Field | Type | Description |
|---|---|---|
call_analysis.call_summary |
string | Short summary of the call |
call_analysis.in_voicemail |
boolean | Whether the call reached voicemail |
call_analysis.user_sentiment |
string | Positive, Negative, Neutral or Unknown |
call_analysis.call_successful |
boolean | Whether the call met its goal, judged with analysis_successful_prompt when set |
call_analysis.custom_analysis_data |
object | One key per Post-Call Extraction field, typed as configured (string, enum, boolean, number). Fields the model could not fill (null) are left out |
If the analysis model fails twice, the call still gets call_analyzed with a fallback analysis: call_summary "Post-call analysis could not be generated because the AI request failed.", user_sentiment Unknown, call_successful false, an empty custom_analysis_data, and in_voicemail set from the disconnection reason.
In keyless local mode the analysis is produced by a mock model, so the values are placeholders. Real summaries and extraction need an OpenAI key. Needs keys
What else runs after analysis#
At the same moment the webhook is sent, Tried also:
- Scores the call for AI Quality Assurance.
- Runs post-call workflows.
- Applies contact field mappings, updates contact memory and pushes to connected CRMs. See CRM sync.
These do not depend on your webhook reply.
How to respond#
Reply 2xx. The body is ignored. Failed attempts are retried up to 3 times (1 s, 2 s, 4 s).
call_analyzed contains everything in call_ended plus the analysis, so many integrations only subscribe to this event. If you need both, de-duplicate on call_id plus event: a re-run analysis sends a second call_analyzed for the same call with the new values.
if (payload.event === "call_analyzed") {
const { call_id, call_analysis, from_number } = payload.call;
if (call_analysis?.custom_analysis_data?.appointment_booked) {
await crm.logBooking({ call_id, phone: from_number, summary: call_analysis.call_summary });
}
}