A call trace is the after-the-fact story of one call. It shows every stage the call moved through, who handled each stretch, and how long each stretch took. The one identifier that follows the call everywhere, the call_sid, keys all of this data. Webhooks give you the live stream of lifecycle events as they occur. A trace is the assembled view: the same events folded into a readable timeline. Pull up a trace when a call went wrong, when a customer disputes what happened, or when you audit an AI→human handoff. This page tells you how to read that timeline, its segment model, and how a transfer changes it. It also tells you how to pull a trace two ways: in the console call detail and over the control-plane API.

How a trace is assembled

The engine sends a lifecycle event for every transition that a call makes on the wire: initiated at the INVITE, delivered when the far end is alerting, established on answer, held / retrieved on hold and resume, transferred on a REFER, and cleared on the final BYE (with the Q.850 cause and the billable duration). You do not assemble anything yourself. The events pipeline collects those transitions for a call_sid and folds them into segment rows. It computes the per-stage durations (ring, queue, talk, hold, wrap-up) as it goes. A trace is that ordered set of segments plus the roll-up totals.
The trace comes from the signalling timeline: when the call rang, was answered, was held, was transferred, and cleared. For the media side of the same call (MOS, jitter, packet loss), see MOS, jitter & loss. To see where the latency went inside a turn, see latency breakdown.

Segments: one sid, one or many stretches

A simple call is a single segment: one caller, one handler, start to finish. The interesting case is a call that changed hands. A transfer or handoff opens a new segment. The call_sid never changes. It is one call, one CDR, one recording context. But the timeline splits at each hand-off. Thus you can see exactly who owned which stretch and for how long. The canonical example is a warm AI→human handoff:
Each segment has its own handler and its own stage timings. The trace’s totals sum them. Thus a transferred call reads as one continuous call in reports, not as two disconnected records.
What opens a new segment. A change of handler opens a new segment: a transferred (REFER) transfer, or a warm AI→human handoff. Holds, resumes (held / retrieved), and mid-call media renegotiation (reinvited) do not open a new segment. The trace records them inside the current segment as hold time and flags. A handler has the tag llm (an AI agent owned the stretch) or human. Thus you can split talk time by who was on the line.

What each segment tells you

Pull a trace in the console

The console call detail is the fastest way to read one call.
1

Open the calls report

In the voice console at agent.clutchcall.dev, go to Reports → All Calls. Filter to the time window. Filter to the number, agent, or direction that you want.
2

Open the call

Click the call to open Call Detail. The header shows the call_sid, the direction, the caller and callee, and the roll-up totals (total talk, hold, and duration; whether the call was transferred).
3

Read the segment timeline

The body shows the segments oldest-first, top to bottom. Each row names its handler (AI or human), its stage timings, and its disposition. A multi-segment call shows the transfer hop inline: the AI segment, then the human segment that it handed to.
4

Play the recording

When recording is on, each segment links its own recording. The caller is on the left channel and the handler is on the right channel. Thus you can listen to exactly the stretch that you audit.
In-flight calls. The system does not fold a call into segments while the call is still on the wire. Call detail shows a live view for it: the direction, the tenant, the bound agent, and the start time. Thus an active call is not a blank page. The full segment timeline appears when the call clears.

Pull a trace over the API

The same assembled trace is available as a control-plane read. The read is keyed by call_sid. Your API key scopes it to your workspace. Use it to feed a QA tool, a dispute workflow, or your own reports — anything that needs the structured timeline instead of the raw event stream.
This is a control-plane reporting read. It is different from calls.get, which returns a point-in-time Call snapshot (current status), not the historical timeline. Fetch the trace from the control-plane API host with your API key. The response is the same data that the console shows.

Response shape

string
The call_sid that this trace belongs to.
array
The ordered segments, oldest first. Each segment has segment (index), startedAt / endedAt, handlerId / handlerKind (llm | human) / handlerDisplayName, the stage timings (ringTimeSec, queueTimeSec, talkTimeSec, holdTimeSec, acwTimeSec, durationSec), the flags (transferred, held, conference), disposition, hangupReason, and recordingUrl.
object
The roll-up across all segments: segments (count), talkTimeSec, holdTimeSec, ringTimeSec, queueTimeSec, durationSec, and whether the call was transferred or conferenced anywhere.
object | null
Present only while the call is still on the wire. It shows the direction, the bound agent, and the start time for an in-flight call whose segments are not assembled yet. It is null when the call cleared and segments exist.

When a trace looks wrong

Call lifecycle

The signalling state machine that every event in a trace comes from.

Webhooks & events

The live event stream that the system assembles a trace from.

Handoffs

How a transfer or warm AI→human handoff opens a new segment.

MOS, jitter & loss

The media-quality side of the same call.

Dashboards

Fleet-wide views built from the same call data.

Calls API

Originate, get, transfer, and hang up calls. This is the live control plane.