Skip to main content
Read the call tree before fetching arguments. GET /v1/traces/{id} shows which instrumented functions ran, their attempts and timing, and their reported capture metadata. Use GET /v1/traces/{id}/values to check whether their bytes are available now. In bearer-token mode, both routes require a read token. A recorded calculate_total helper received [12, 8] and returned 20. Its output read was:
The value field contains the JSON text 20. The response reports stored because the bytes are readable.

Read one request

GET /v1/traces/{id} The response returns one page of steps, the applied limit, and next_cursor. It also includes request identity (trace_id, service, team, instance_id, sdk_version), tags, format_version, timestamps, request result, recording completeness and loss information. environment is omitted when it was not recorded. There is no include=values option here; fetch full values through the values route.

Calls and attempts

A step is a recorded function call. Its path identifies its position within this request. An attempt is one execution of that call; a retry can give one step several attempts. Rebuild the tree from path and parent_path; do not decode the path. A parent missing from one page does not prove the function ran without a parent. An in_flight attempt carries only attempt, started_us and status. Its absent slots key does not mean not_captured; no completed capture was reported. Treat an unrecognized status as having no reported completion, rather than assuming success. duration_desc sorts steps by the sum of completed attempt durations. A step with no completed attempts goes last. A step with both completed and open attempts has a duration that is a lower bound. An open attempt is not proof of a live function: a lost completion record leaves the same evidence. attempt_grouping: single means no attempt declared retries or was observed retrying. declared means the marker declared retries. observed_retry means the SDK inferred a retry without a declaration.

Walk every page

  1. Read the first page without a cursor and collect its distinct path values.
  2. Follow next_cursor until it is null.
  3. Compare the number of collected paths with the newest step_count seen.
  4. Restart without a cursor while those counts differ.
A cursor resumes a position, not a snapshot. Records can arrive behind it. This walk proves coverage only for a trace that has stopped receiving records; an active trace is still changing. Never infer the number of unfinished calls from the steps absent on one page.

Separate request failure from missing records

root_status answers whether the root call returned successfully: ok or error. It is absent until the root completes. completeness answers whether the recording arrived. A failed request can have a complete recording. Completeness is derived at read time. An abandoned trace returns to running if another record arrives. Complete does not mean every possible function or path was instrumented. The coverage object contains records_lost, records_shed, truncated, instance_mismatch, and, when present, service_loss_24h. Read these alongside an open attempt before diagnosing a hang. On a version-1 trace, absence of open attempts tells you nothing about hangs: that emitter format had no step-open record.

Fetch arguments, results, errors or logs

GET /v1/traces/{id}/values Omit slot to retrieve all present slots at the named paths. More than eight distinct paths returns 422 too_many_paths. The response has values and unknown_paths. Each entry identifies its path, slot and state. Readable nonempty payloads also carry encoding and recorded bytes under value. That field is a string even when encoding is json: decode it as JSON if you need the captured object. A known path with only open attempts produces no value entries and does not appear in unknown_paths. A readable zero-length payload omits both value and bytes_count. Its encoding and truncated fields remain present. An empty text return value therefore differs from an unresolved value, which carries only path, slot and state. The values route has no attempt selector. It can return several entries with the same path and slot from different attempts, without an attempt number in each entry. Do not assume a repeated pair identifies the latest attempt.

Read capture metadata

Trace detail carries a description for each reported slot. It resolves pending to stored when the bytes are readable. Other emitted states are preserved; fetch the value to check whether bytes from a previously stored capture remain available. sampled_out and dropped describe the producer’s capture decision. A read can still return bytes for those slots when the content is available. Check whether value is present rather than inferring byte availability from the state alone. A stored logs handle with no entries has no payload to fetch. Its stored state describes log capture being enabled without any captured entries, rather than a missing log value.

When the bytes are unavailable

A pending capture becomes stored when its bytes are readable. A later read can therefore return stored for a slot that previously returned pending. If it remains pending, the response does not identify why the bytes are unavailable or whether they will become readable. expired means bytes are unavailable now. They were either reclaimed or have not arrived. The server cannot distinguish those causes from its stored history. An expired value therefore does not prove a previous successful capture reached the server. See data retention. GET /v1/traces/{id}/related finds traces sharing recorded tags with this request. It stays within the request’s team. window defaults to 24h and is bounded at 7d; limit and cursor use the list pagination controls. The response names the relation as shares_tag and reports searched_tag_keys even when no matches appear. Shared identifiers relate requests; they do not establish that one service called another.