You can receive webhooks at one workspace URL, at a URL per agent, or both. Agent URLs override the workspace URL for that agent's calls and transfers. This page covers each setting and its API field.
Account level URL#
The workspace URL receives every event that has no more specific URL: calls on agents without their own URL, chat events, alert events without a rule URL, budget events and the test event.
Open the Webhooks page#
In the dashboard, go to Settings, then Webhooks.
Enter the URL#
Type your endpoint into URL, for example https://example.com/tried/webhook. The field accepts http:// and https:// URLs.
Send a test event#
Press Test. Tried sends a signed test event to the URL in the field (saved or not) and shows whether your endpoint replied with a 2xx. See Test webhooks.
Save#
Press Save. Clearing the field and saving removes the workspace URL.
Only workspace admins can change the workspace URL.
Set it with the API#
PATCH /workspace with webhook_url. Pass null to remove it.
curl -X PATCH https://api.tried.com.au/workspace \
-H "Authorization: Bearer $TRIED_API_KEY" \
-H "Content-Type: application/json" \
-d '{"webhook_url": "https://example.com/tried/webhook"}'const res = await fetch("https://api.tried.com.au/workspace", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ webhook_url: "https://example.com/tried/webhook" }),
});
console.log(await res.json());import os, requests
r = requests.patch(
"https://api.tried.com.au/workspace",
headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
json={"webhook_url": "https://example.com/tried/webhook"},
)
print(r.json()){
"workspace_id": "ws_7d1c0a9e4b2f6a8c3e5d1b90",
"name": "Tried Demo",
"webhook_url": "https://example.com/tried/webhook",
"concurrency_limit": 20,
"created_timestamp": 1760668500000
}Agent level URL#
An agent URL receives that agent's call_*, transcript_updated and transfer_* events instead of the workspace URL.
Open the agent#
Go to Agents and open the agent.
Open Webhook Settings#
In the settings panel on the right, expand Webhook Settings.
Set the URL#
Enter Agent Level Webhook URL. The value is saved when the field loses focus. Leave it empty to use the workspace URL.
Choose events#
Toggle the events under Events. See Event filter.
Set the timeout#
Drag Webhook timeout (1 to 60 seconds, default 10 s).
Publish#
Webhook settings are part of the agent version. Publish the agent so live numbers pick up the change.
The Test button next to the agent URL sends an unsigned sample body straight from your browser ({"event": "test", "call": {"call_id": "call_test", "agent_id": "..."}}). The browser cannot read the reply, so it only tells you the request left. For a signed test with a logged result, use the Webhooks page or the test endpoint with the agent URL.
Dynamic variables in the agent URL#
The agent URL can contain {{variable}} placeholders. For call events they are filled from the call's dynamic variables, its collected variables, call_id and agent_id. Placeholders with no value are removed.
https://hooks.example.com/{{tenant_id}}/tried?agent={{agent_id}}Transfer events use the agent URL as stored, without filling placeholders.
Set it with the API#
Send webhook_url, webhook_events and webhook_timeout_ms to update-agent.
curl -X PATCH https://api.tried.com.au/update-agent/agent_5b0e2c7d9a1f4e3b8c6d2a10 \
-H "Authorization: Bearer $TRIED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://example.com/hooks/front-desk",
"webhook_events": ["call_started", "call_ended", "call_analyzed", "transfer_bridged"],
"webhook_timeout_ms": 5000
}'await fetch("https://api.tried.com.au/update-agent/agent_5b0e2c7d9a1f4e3b8c6d2a10", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
webhook_url: "https://example.com/hooks/front-desk",
webhook_events: ["call_started", "call_ended", "call_analyzed", "transfer_bridged"],
webhook_timeout_ms: 5000,
}),
});import os, requests
requests.patch(
"https://api.tried.com.au/update-agent/agent_5b0e2c7d9a1f4e3b8c6d2a10",
headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
json={
"webhook_url": "https://example.com/hooks/front-desk",
"webhook_events": ["call_started", "call_ended", "call_analyzed", "transfer_bridged"],
"webhook_timeout_ms": 5000,
},
)| Field | Type | Default | Description |
|---|---|---|---|
webhook_url |
string or null | null |
Agent URL. null falls back to the workspace URL |
webhook_events |
string[] | ["call_started", "call_ended", "call_analyzed"] |
Events sent for this agent's calls. Allowed values below |
webhook_timeout_ms |
integer | not set | Per-attempt timeout, 1,000 to 60,000. Not set means the workspace timeout, else 10,000 |
Event filter#
webhook_events accepts these values:
| Value | Notes |
|---|---|
call_started |
On by default |
call_ended |
On by default |
call_analyzed |
On by default |
transcript_updated |
Opt in. Shown in the dashboard as "live, at most every 3s" |
transfer_started |
Opt in. Phone calls only |
transfer_bridged |
Opt in. Phone calls only |
transfer_cancelled |
Opt in. Phone calls only |
transfer_ended |
Opt in. Phone calls only |
Sending an empty list turns off every call and transfer event for the agent.
Chat agent URL and events#
Chat agents have their own Webhook URL and Events in the chat agent's Settings dialog. Leave the URL empty to use the workspace webhook. The Webhook column on the Chat Agents list shows "Workspace webhook" when the agent has no URL of its own.
With the API, send webhook_url and webhook_events to update-chat-agent:
curl -X PATCH https://api.tried.com.au/update-chat-agent/chat_agent_0c4f8e2a6b1d3f5a7c9e2b40 \
-H "Authorization: Bearer $TRIED_API_KEY" \
-H "Content-Type: application/json" \
-d '{"webhook_url": "https://example.com/hooks/chat", "webhook_events": ["chat_ended", "chat_analyzed"]}'| Field | Type | Default | Description |
|---|---|---|---|
webhook_url |
string or null | null |
Chat agent URL. null falls back to the workspace URL |
webhook_events |
string[] | ["chat_started", "chat_ended", "chat_analyzed"] |
Chat events to send |
Chat agents have no timeout field. Chat events use the workspace timeout.
Alert rule URL#
Each alert rule has an optional Webhook URL in the Create alert dialog ("Receives signed alert_triggered and alert_resolved events. Falls back to the workspace webhook when empty."). With the API it is the rule's webhook_url. See alert_triggered.
Inbound webhook URL#
The inbound call webhook is set per phone number, not per agent. On Phone Numbers, tick Add an inbound webhook under Inbound Call Agent and save the URL. With the API it is inbound_webhook_url on create-phone-number, import-phone-number and update-phone-number. See Inbound call webhook.
Workspace timeout#
The Timeout selector on the Webhooks page sets the per-attempt timeout for every webhook that has no agent timeout. Options: 10s (default), 1s, 2s, 3s, 5s, 15s, 20s, 30s, 45s, 60s. The "3 retries" label next to it is fixed.
With the API, PATCH /workspace/settings (admin only):
curl -X PATCH https://api.tried.com.au/workspace/settings \
-H "Authorization: Bearer $TRIED_API_KEY" \
-H "Content-Type: application/json" \
-d '{"webhook_timeout_ms": 5000}'| Field | Type | Description |
|---|---|---|
webhook_timeout_ms |
integer or null | 1,000 to 60,000. null restores the 10 s default |
Choosing a timeout#
A short timeout makes Tried retry sooner when your server hangs. A long one gives slow handlers time to finish. The usual pattern is to reply 200 at once and do the work in a queue, which keeps any timeout safe.
Retries wait 1, 2 and 4 seconds, so the worst case for one event is 4 timeouts plus 7 seconds of backoff. With the 10 s default that is 47 seconds before the last attempt fails.