Read the trace of a finalized Call
GET /v1/calls/{call_id}/trace
| Property | Value |
|---|---|
| Operation | get_call_trace |
| Group | Call trace and analytics |
| Scope | calls:read |
Scopes of include values | model_io needs model_io:read; tool_payloads needs tool_payloads:read; transcripts needs transcripts:read |
| Route class | read |
| Idempotency | No Idempotency-Key |
| Audit | An audited content read trace.read, when the request names an include value |
| Released in | 1.3.0 |
| Phase 0 host | Served (the hosted api pins 1.65.0) |
The segments of the Call's trace with their marks, stages, Providers, quality flags and per-Turn cost, and the content classes include names (ADR 0058). From 1.57.0 (workspace ADR 0048 decision 6) include=tool_payloads adds the Tool payloads with tool_payloads:read; turns limits the segments to a range of Turns; and the answer carries the recording alignment, the basis of the per-Turn cost, the post-call analyses and, for a Member, the reveal grant that let it include a class. With an API key each class needs its scope; a Member reads a class its role's visibility cell allows, or one an active reveal grant covers for the Call, and is refused otherwise with 403 forbidden naming the missing permission in details. Naming any class makes the read an audited content read, whose Audit event carries the reveal_grant_id when a grant was used. The segments' cost needs usage:read (1.29.0).
Request
Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the calls:read scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.
curl "$VOCAL_API/v1/calls/call_.../trace" \
-H "Authorization: Bearer $VOCAL_API_KEY"const response = await fetch(`${process.env.VOCAL_API}/v1/calls/call_.../trace`, {
headers: {
Authorization: `Bearer ${process.env.VOCAL_API_KEY}`,
},
});
console.log(response.status, await response.text());import os
import requests
response = requests.get(
f"{os.environ['VOCAL_API']}/v1/calls/call_.../trace",
headers={
"Authorization": f"Bearer {os.environ['VOCAL_API_KEY']}",
},
)
print(response.status_code, response.text)Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
call_id | path | CallId | yes | The id of a Call: call_ and the row's UUIDv7 in 26 Crockford base32 characters. Opaque and safe to log. |
include | query | array of TraceInclude | no | Content classes to add, comma-separated. Each needs its own scope beside calls:read (transcripts:read, model_io:read and, from 1.57.0, tool_payloads:read), and naming any makes the read an audited content read. From 1.57.0 a Member reads a class its role's cell of the Compliance profile's content_visibility allows, or one an active reveal grant covers for the Call, whose id the read's Audit event carries. |
turns | query | string | no | Only the turn segments whose Turn seq is in this range, both ends inclusive, as 3-7 or 4 (1.57.0); the setup and end segments, the envelopes and the content classes are limited to the same Turns. Absent: the whole trace. |
Responses
| Status | Content type | Shape | Error codes |
|---|---|---|---|
200 | application/json | CallTrace | |
400 | application/json | ErrorEnvelope | invalid_request |
401 | application/json | ErrorEnvelope | unauthenticated |
403 | application/json | ErrorEnvelope | forbidden |
404 | application/json | ErrorEnvelope | not_found |
429 | application/json | ErrorEnvelope | rate_limited |
500 | application/json | ErrorEnvelope | internal_error |
Fields of the 200 answer
The shape is CallTrace.
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | AgentId | yes | |
agent_version | integer | yes | |
analyses | array of TraceAnalysisRef | no | The post-call analyses of the Call, beside the end segment (1.57.0). Absent from an api older than 1.57.0; a reader treats its absence as none. |
call_id | CallId | yes | |
capture | TraceCapture | yes | |
cost_basis | TraceCostBasis | no | Where the segments' cost comes from (1.57.0). Absent from an api older than 1.57.0, whose cost is the estimate. |
envelopes | array of TraceEnvelope | yes | The audio envelope of each lane the worker sent, at most one per lane; always present and empty when the worker sent none (the flag diagnostics.audio_envelope was off, or the Call predates 1.13.0). Not a content class: a loudness series is a measurement (workspace ADR 0068), so no include is needed. |
epoch_at | Timestamp | yes | The wall-clock instant of the trace epoch; for display and api marks only. |
model_io | array of ModelIoItem | no | The captured model messages, empty when the capture was standard; present only with include=model_io. |
model_io_dropped | integer | no | Messages the worker dropped at its capture bound; present with model_io. |
object | "call_trace" | yes | |
recording_offset_ms | integer or null | no | The trace-epoch offset of the recording's first sample (1.57.0), so replay aligns audio and marks; null when the Call has no recording. Absent from an api older than 1.57.0; a reader treats its absence as null. |
reveal_grant_id | RevealGrantId or null | no | The reveal grant that let this read include a class the reader's role has as reveal (1.57.0); null when no grant was used. Absent from an api older than 1.57.0. |
segments | array of TraceSegment | yes | |
tool_payloads | array of TracePayloadItem | no | The Tool payloads in order; present only with include=tool_payloads (1.57.0). |
tool_payloads_outside_turns | integer | no | The Tool invocations outside every Turn, in the setup or end segment, whose payloads no item answers (1.59.0); present with include=tool_payloads, and a reader treats its absence as 0. |
transcripts | array of TranscriptTurn | no | The text of each Turn; present only with include=transcripts. |