Skip to content
TriedDocs
Webhooks

Register a webhook

Set the workspace webhook URL, per-agent URLs, the event filter and the delivery timeout from the dashboard or the API.

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.

The URL field, Test and Save buttons, and the Timeout selector on the Webhooks page

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 agent's Webhook Settings section with the agent level URL, event toggles and webhook timeout

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.