Skip to content
TriedDocs
Webhooks

transcript_updated

Live transcript updates during an ongoing call, throttled and sent without retries.

transcript_updated streams the conversation to your server while the call is still running. Use it for live dashboards, agent assist screens or early escalation rules.

When it fires#

Tried checks ongoing calls on its platform tick, every 5 seconds by default. A call gets a transcript_updated when both are true:

  • Its transcript_with_tool_calls has more entries than at the last update (a new turn, tool call, node transition, DTMF digit or transfer event).
  • At least 3 seconds have passed since the last update for that call.

The dashboard shows this as "live, at most every 3s". In practice you receive at most one update per tick, so roughly one every 5 seconds while people are talking, and none while the call is silent.

Updates stop when the call ends. The final transcript arrives in call_ended.

Which settings enable it#

It is off by default. Turn it on per agent:

  • Dashboard: agent Webhook Settings, Events, toggle transcript_updated.
  • API: add "transcript_updated" to the agent's webhook_events with update-agent.

A URL must resolve: the agent's webhook_url, else the workspace URL.

Payload#

The full call object at the moment of the update. call_status is ongoing and the transcript fields hold everything so far.

{
  "event": "transcript_updated",
  "call": {
    "call_id": "call_3ffd3f3831b0d4e1a2c96f07",
    "call_type": "phone_call",
    "agent_id": "agent_5b0e2c7d9a1f4e3b8c6d2a10",
    "agent_version": 2,
    "agent_name": "Bondi Dental Front Desk",
    "call_status": "ongoing",
    "direction": "inbound",
    "from_number": "+61412345678",
    "to_number": "+61291234567",
    "metadata": {},
    "retell_llm_dynamic_variables": { "business_name": "Bondi Dental" },
    "collected_dynamic_variables": {},
    "start_timestamp": 1760672019481,
    "end_timestamp": null,
    "duration_ms": null,
    "transcript": "Agent: Hi, thanks for calling Bondi Dental, this is Ava. How can I help you today?\nUser: Hi, I'd like to book a check-up and clean.",
    "transcript_object": [
      { "role": "agent", "content": "Hi, thanks for calling Bondi Dental, this is Ava. How can I help you today?", "words": [] },
      { "role": "user", "content": "Hi, I'd like to book a check-up and clean.", "words": [] }
    ],
    "transcript_with_tool_calls": [
      { "role": "agent", "content": "Hi, thanks for calling Bondi Dental, this is Ava. How can I help you today?", "ts": 1760672019702 },
      { "role": "user", "content": "Hi, I'd like to book a check-up and clean.", "ts": 1760672025330 }
    ],
    "recording_url": null,
    "recording_multi_channel_url": null,
    "public_log_url": "https://api.tried.com.au/public/calls/call_3ffd3f3831b0d4e1a2c96f07/log?exp=1761276826100&sig=3c6f9b2e5a8d1c4f7b0e3a6d9c2f5b8e1a4d7c0f3b6e9a2d5c8f1b4e7a0d3c6f",
    "knowledge_base_retrieved_contents_url": "https://api.tried.com.au/public/calls/call_3ffd3f3831b0d4e1a2c96f07/kb-retrievals?exp=1761276826100&sig=6a9d2c5f8b1e4a7d0c3f6b9e2a5d8c1f4b7e0a3d6c9f2b5e8a1d4c7f0b3e6a9d",
    "transfer_destination": null,
    "llm_token_usage": { "values": [1834], "average": 1834, "num_requests": 1 },
    "disconnection_reason": null,
    "call_analysis": null,
    "latency": {
      "e2e": { "p50": 655, "p90": 655, "p95": 655, "p99": 655, "max": 655, "min": 655, "num": 1, "values": [655] }
    },
    "call_cost": null,
    "batch_call_id": null,
    "contact_id": "contact_6e2a9c1f4b7d0e3a5c8f1b24"
  }
}

Fields#

Same as the call object. The fields that matter here:

Field Type Description
call_status string ongoing
transcript string All finished turns so far, one line each
transcript_object array Finished turns with word timings
transcript_with_tool_calls array Turns plus tool calls, results and other events so far. Its length grows with each update
latency object Percentiles over the turns so far

Each update contains the whole transcript, not only the new part. To find new entries, compare transcript_with_tool_calls.length with the length you stored last time for that call_id.

Delivery#

  • Sent once. No retries: if an attempt fails, the next update carries the newer transcript anyway.
  • Timeout: the agent's webhook_timeout_ms, else the workspace timeout, else 10 s.
  • Every attempt is in the delivery log.

How to respond#

Reply 2xx fast. Keep the timeout short for this event, because a slow reply holds the platform tick that also sends updates for your other live calls.

const seen = new Map<string, number>();

if (payload.event === "transcript_updated") {
  const { call_id, transcript_with_tool_calls: items } = payload.call;
  const from = seen.get(call_id) ?? 0;
  for (const item of items.slice(from)) liveView.push(call_id, item);
  seen.set(call_id, items.length);
}

For audio-level live monitoring and whisper or take-over, use Live monitoring instead.