chat_ended carries the finished chat with its full message history and cost. Analysis follows in chat_analyzed.
When it fires#
Once per chat, when it moves to ended:
- You call
PATCH /end-chat/:idorPOST /end-chat/:id. - A website widget visitor ends the chat (
/public/chat/:id/end). - No new message arrived for the chat agent's
end_chat_after_silence_ms(default 1 hour, between 1 minute and 24 hours). The idle check runs about once a minute, so a chat can close up to a minute after its limit. In the dashboard this is End the chat after in the chat agent's settings.
Ending a chat that has already ended does not send a second event.
Which settings enable it#
chat_endedin the chat agent'swebhook_events(on by default).- URL: the chat agent's
webhook_url, else the workspace URL. - Timeout: the workspace timeout, else 10 s.
Payload#
{
"event": "chat_ended",
"chat": {
"chat_id": "chat_2d7f1a4c8e0b3f6a9c5e1d42",
"chat_agent_id": "chat_agent_0c4f8e2a6b1d3f5a7c9e2b40",
"agent_name": "Receptionist (chat)",
"chat_type": "api_chat",
"channel": "widget",
"chat_status": "ended",
"retell_llm_dynamic_variables": {
"business_name": "Bondi Dental"
},
"metadata": {
"origin": "https://www.bondidental.com.au",
"public_key_id": "pk_4b8e1d5a9c2f6e0a3d7b1c58"
},
"start_timestamp": 1760679000210,
"end_timestamp": 1760679391020,
"transcript": "Agent: Hi, I'm Ava from Bondi Dental. How can I help?\nUser: Are you open on Saturday?\nAgent: Yes, we're open Saturday from 9am to 1pm.\nUser: Great, thanks.\nAgent: You're welcome. Anything else I can help with?",
"message_with_tool_calls": [
{ "role": "agent", "content": "Hi, I'm Ava from Bondi Dental. How can I help?", "created_timestamp": 1760679000845 },
{ "role": "user", "content": "Are you open on Saturday?", "created_timestamp": 1760679012100 },
{ "role": "agent", "content": "Yes, we're open Saturday from 9am to 1pm.", "created_timestamp": 1760679013320 },
{ "role": "user", "content": "Great, thanks.", "created_timestamp": 1760679030880 },
{ "role": "agent", "content": "You're welcome. Anything else I can help with?", "created_timestamp": 1760679031750 }
],
"chat_analysis": null,
"chat_cost": { "combined_cost": 0.01 }
}
}Fields#
The fields are the same as in chat_started. At this point:
| Field | Value |
|---|---|
chat_status |
ended |
end_timestamp |
When the chat ended, Unix ms |
transcript, message_with_tool_calls |
The complete conversation |
chat_cost.combined_cost |
Final cost in AUD |
chat_analysis |
null. It arrives in chat_analyzed |
How to respond#
Reply 2xx. The body is ignored. Retries: up to 3 (1 s, 2 s, 4 s).
Post-chat analysis starts after this delivery finishes, including retries. A slow handler here delays chat_analyzed.