Tried stores every webhook attempt, including each retry. Use the log to confirm your endpoint receives events, to read the exact body that was sent and to see why a delivery failed. Beyond Retell
Recent deliveries in the dashboard#
Go to Settings, Webhooks. The Recent deliveries table lists the newest 100 attempts across every event and URL in the workspace.
| Column | Shows |
|---|---|
| Time | When the attempt was made |
| Event | The event name, for example call_analyzed or call_inbound |
| Call ID | The call the event belongs to, or n/a for chat, alert, budget, test and inbound call webhooks |
| Status | The HTTP status code, or ERR when no response came back, followed by the error text |
| Attempt | 1 for the first try, 2 to 4 for retries |
| Duration | Time from sending to the response or failure, in milliseconds |
| Endpoint | The URL the attempt went to |
Use All, Succeeded and Failed to filter, and the refresh button to reload. Pressing Test on the same page refreshes the table when the test finishes.
In the screenshot above, the endpoint was down: each call_analyzed shows attempts 1 to 4 with ERR fetch failed, spaced by the 1 s, 2 s and 4 s backoff.
Status values#
A delivery attempt is either successful or failed.
| Result | success |
status_code |
error |
|---|---|---|---|
Your server replied 2xx |
true |
200 to 299 | null |
| Your server replied with another status | false |
That status, for example 500 |
HTTP 500 |
| Timeout | false |
null |
The abort message, for example The operation was aborted due to timeout |
| Connection refused, DNS failure, TLS error | false |
null |
The network error, for example fetch failed |
| Destination blocked by the egress filter | false |
null |
Refusing to connect to <host> (<address>): private or reserved address |
A delivery as a whole succeeds when any attempt succeeds. After a success no more attempts are made.
Retry behaviour#
| Event | Attempts | Wait between attempts |
|---|---|---|
| Call, transfer, chat, alert, budget and test events | Up to 4 (1 + 3 retries) | 1 s, 2 s, 4 s |
transcript_updated |
1 | None |
call_inbound |
Up to 3 (1 + 2 retries) | 0.5 s, 1 s |
Each attempt is a new row in the log with the same request body. There is no manual retry button. To resend, fix your endpoint and use the data from the log or get-call.
List deliveries with the API#
GET /webhook-deliveries returns attempts newest first.
| Query parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 100 | 1 to 500 |
call_id |
string | none | Only attempts for this call |
event |
string | none | Only attempts for this event, for example call_ended |
curl "https://api.tried.com.au/webhook-deliveries?event=call_ended&limit=20" \
-H "Authorization: Bearer $TRIED_API_KEY"const res = await fetch("https://api.tried.com.au/webhook-deliveries?event=call_ended&limit=20", {
headers: { Authorization: `Bearer ${process.env.TRIED_API_KEY}` },
});
const deliveries = await res.json();import os, requests
r = requests.get(
"https://api.tried.com.au/webhook-deliveries",
params={"event": "call_ended", "limit": 20},
headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
)
deliveries = r.json()[
{
"delivery_id": "whd_8a4c2e6f0b1d3a5c7e9f2b14",
"call_id": "call_3ffd3f3831b0d4e1a2c96f07",
"event": "call_ended",
"url": "https://example.com/tried/webhook",
"attempt": 2,
"success": true,
"status_code": 200,
"error": null,
"duration_ms": 143,
"request_body": {
"event": "call_ended",
"call": { "call_id": "call_3ffd3f3831b0d4e1a2c96f07", "call_status": "ended", "...": "..." }
},
"response_body": "{\"ok\":true}",
"created_timestamp": 1760672115204
},
{
"delivery_id": "whd_1f3e5a7c9b2d4f6a8c0e1b37",
"call_id": "call_3ffd3f3831b0d4e1a2c96f07",
"event": "call_ended",
"url": "https://example.com/tried/webhook",
"attempt": 1,
"success": false,
"status_code": 502,
"error": "HTTP 502",
"duration_ms": 61,
"request_body": { "event": "call_ended", "call": { "...": "..." } },
"response_body": "Bad Gateway",
"created_timestamp": 1760672114140
}
]| Field | Type | Description |
|---|---|---|
delivery_id |
string | Attempt id, prefix whd_ |
call_id |
string or null | Set for call and transfer events. null for chat, alert, budget, test and call_inbound |
event |
string | Event name |
url |
string | Destination URL after any {{variable}} substitution |
attempt |
integer | 1 to 4 |
success |
boolean | true when the response was 2xx |
status_code |
integer or null | HTTP status, null when no response came back |
error |
string or null | HTTP <status> or the network error |
duration_ms |
integer | Attempt duration |
request_body |
object | The JSON body that was sent |
response_body |
string or null | Your response body, first 4,000 characters |
created_timestamp |
integer | Unix milliseconds |
The log is per workspace. Any authenticated key or dashboard user in the workspace can read it.
Debugging failed deliveries#
| Symptom | Likely cause | Fix |
|---|---|---|
ERR fetch failed |
Endpoint down, DNS name does not resolve, TLS handshake failed | Check the URL from outside your network |
| Timeout error after exactly the timeout | Handler does its work before replying | Reply 2xx first, queue the work. Or raise the timeout |
HTTP 401 or HTTP 403 |
Your signature check rejects the request | Verify against the raw body and the current webhook key |
HTTP 404 |
Path typo, or the route only accepts GET |
Accept POST on the exact path |
HTTP 413 |
Large transcripts exceed your body size limit | Raise the limit on the webhook route |
Refusing to connect ... private or reserved address |
URL points to a private network or localhost | Use a public URL or a tunnel |
| No rows at all | No URL resolves, or the event is filtered out | Check the agent's webhook_events and the URL precedence |