A webhook is an HTTP POST that Tried sends to a URL you own when something happens: a call starts, a call ends, post-call analysis finishes, a transfer connects, a chat closes, an alert fires. Your server receives a JSON body, does its work (update a CRM, start a follow-up, page someone) and replies with any 2xx status.
Webhooks are the push side of the platform. Use them instead of polling get-call or list-calls.
Where events are sent#
Tried looks up the destination URL in this order. The first one that is set wins.
| Event family | First choice | Fallback |
|---|---|---|
Call events (call_*, transcript_updated) |
The agent's webhook_url |
The workspace webhook URL |
Transfer events (transfer_*) |
The agent's webhook_url |
The workspace webhook URL |
Chat events (chat_*) |
The chat agent's webhook_url |
The workspace webhook URL |
Alert events (alert_*) |
The alert rule's webhook_url |
The workspace webhook URL |
Budget events (budget_*) |
The workspace webhook URL | None |
Test event (test) |
The URL you pass to the test endpoint | The workspace webhook URL |
Inbound call webhook (call_inbound) |
The phone number's inbound_webhook_url |
None |
If no URL resolves, the event is not sent and nothing is logged.
- Account level: one URL for the whole workspace, set on Settings, Webhooks. See Register a webhook.
- Agent level: a URL on one agent that overrides the workspace URL for that agent's calls. Set it in the agent's Webhook Settings panel. See Register a webhook.
Event filter#
Each agent has a webhook_events list. Call and transfer events that are not in the list are not sent for that agent's calls.
- Default:
["call_started", "call_ended", "call_analyzed"]. - Opt in:
transcript_updated,transfer_started,transfer_bridged,transfer_cancelled,transfer_ended.
Chat agents have their own webhook_events list with chat_started, chat_ended and chat_analyzed, all on by default. Alert, budget, test and inbound call webhooks have no filter.
Delivery semantics#
| Behaviour | Value |
|---|---|
| Method and body | POST, Content-Type: application/json |
| User agent | Tried-Webhooks/1.0 |
| Signature headers | x-tried-signature and x-retell-signature (same value). See Secure webhooks |
| Success | Any 2xx status. The response body is ignored (except for the inbound call webhook) |
| Timeout per attempt | 10 seconds by default. Configurable per agent (webhook_timeout_ms, 1,000 to 60,000 ms) and per workspace |
| Retries | Up to 3 retries after the first attempt (4 attempts in total) |
| Backoff | 1 s, then 2 s, then 4 s between attempts |
| Redirects | Followed, up to 5 hops. Every hop is checked by the egress filter |
| Logging | Every attempt is stored and visible in the delivery log |
Exceptions to the retry rule:
transcript_updatedis sent once with no retries. A newer update follows within seconds.- The inbound call webhook uses a fixed 10 second timeout and 2 retries. See Inbound call webhook.
Timeout precedence#
| Event | Timeout used |
|---|---|
call_started, call_ended, call_analyzed, transcript_updated |
Agent webhook_timeout_ms, else workspace timeout, else 10 s |
transfer_*, chat_*, alert_*, budget_*, test |
Workspace timeout, else 10 s |
call_inbound |
10 s, fixed |
Non-blocking delivery#
Webhooks are sent in the background. A slow or failing endpoint never delays the call, the transfer, the analysis or the next chat message. Post-call analysis starts as soon as the call ends, in parallel with the call_ended delivery.
The inbound call webhook is the one exception: Tried waits for your response before it picks the agent, so it adds latency to call setup.
Ordering#
call_analyzedis sent only after thecall_endeddelivery has finished (including its retries). Your server always seescall_endedbeforecall_analyzedfor the same call.chat_analyzedis sent after thechat_endeddelivery has finished.- Other events are independent. A
transfer_bridgedcan arrive before or aftercall_ended. Use thetimestampfields to order them.
Duplicates#
A retry resends the exact same body after a timeout or error. If your server processed the first attempt but replied too slowly, you receive the event again. Make handlers idempotent: key on call_id (or chat_id, alert_id) plus event.
Re-running analysis on a call from the dashboard or with rerun-call-analysis sends a second call_analyzed for that call with the new analysis.
Every event#
| Event | Fires when | Default | Page |
|---|---|---|---|
call_started |
A call connects and the conversation begins | On | call_started |
call_ended |
A call ends, or a dial attempt fails without connecting | On | call_ended |
call_analyzed |
Post-call analysis is stored | On | call_analyzed |
transcript_updated |
An ongoing call's transcript grows | Off | transcript_updated |
transfer_started |
The agent starts a transfer on a phone call | Off | transfer_started |
transfer_bridged |
The transfer target is connected to the caller | Off | transfer_bridged |
transfer_cancelled |
A transfer fails or is cancelled | Off | transfer_cancelled |
transfer_ended |
The bridged transfer legs hang up | Off | transfer_ended |
chat_started |
A chat session is created | On | chat_started |
chat_ended |
A chat is ended by API, by the widget or by the idle timer | On | chat_ended |
chat_analyzed |
Post-chat analysis is stored | On | chat_analyzed |
alert_triggered |
An alert rule crosses its threshold | Always | alert_triggered |
alert_resolved |
A triggered alert rule is back within its threshold | Always | alert_resolved |
alert_test |
You press Test on an alert rule | Always | alert_test |
budget_alert |
Spend reaches 80% of the monthly budget | Always | budget_alert |
budget_reached |
Spend reaches 100% of the monthly budget | Always | budget_reached |
test |
You press Test on the Webhooks page or call the test endpoint | Always | test |
call_inbound |
An inbound call arrives on a number with an inbound webhook | Per number | Inbound call webhook |
All payloads share one envelope: an event string and one object named after the resource (call, chat, alert, billing). Transfer events add a transfer object next to call.
{
"event": "call_ended",
"call": { "call_id": "call_3ffd3f3831b0d4e1a2c96f07", "...": "..." }
}The call object in call and transfer events is the same object that get-call returns. Every field is documented in Call object.
What is not a webhook#
Other outbound requests use the same signing key and egress path but are not events:
- Custom function calls the agent makes during a conversation. See Tools.
- HTTP steps in pre-call and post-call workflows.
- CRM sync and integration app requests. See Integrations.
Inbound SMS messages are answered by the number's agent and do not send a webhook.