> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vexlo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP traces and values

> Interpret one request, walk its call pages and retrieve selected recorded values.

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:

```json theme={"system"}
{"values":[{"path":"AAAA","slot":"output","state":"stored","encoding":"json","value":"20","bytes_count":2,"truncated":false}],"unknown_paths":[]}
```

The `value` field contains the JSON text `20`. The response reports `stored` because the
bytes are readable.

## Read one request

`GET /v1/traces/{id}`

| Query parameter | Values | Default |
| - | - | - |
| `steps_sort` | `path` or `duration_desc` | `path`, depth-first |
| `limit` | Up to `500` steps | `500` |
| `cursor` | Opaque cursor from previous page | First page |

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.

| Step field | Meaning |
| - | - |
| `path` | Opaque identifier; use it unchanged when fetching values |
| `parent_path` | Parent's path; `null` for the root |
| `depth` | Depth in the call tree |
| `name` | Function's recorded name |
| `parent_name` | Recorded parent function name; `null` when absent |
| `attempt_grouping` | `single`, `declared` or `observed_retry`; see below |
| `duration_us` | Sum of completed attempt durations; absent when none completed |
| `attempts` | Recorded executions of this call |

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.

| Attempt field | Meaning |
| - | - |
| `attempt` | Attempt number |
| `started_us` | Start offset from the trace's zero, in microseconds |
| `status` | `ok`, `error`, or read-derived `in_flight` |
| `duration_us` | Completed attempt's duration, in microseconds |
| `error_class` | Error class when reported |
| `slots` | Available argument/result/error/log descriptions, keyed by slot name |

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` | What the server has received |
| - | - |
| `running` | No root completion; at least one record within the last 15 minutes |
| `abandoned` | No root completion; no record for over 15 minutes |
| `complete` | Root completion, no reported loss, shedding, truncation or instance mismatch |
| `partial` | Root completion plus at least one of those conditions |

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`

| Query parameter | Meaning |
| - | - |
| `path` | Repeat for up to 8 distinct step paths |
| `slot` | Optional; repeat to select `input`, `output`, `error` or `logs` |

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.

| Field | Meaning |
| - | - |
| `state` | Capture decision, with read-time resolution where applicable |
| `bytes_count` | Captured byte count, when byte metadata exists |
| `truncated` | Whether capture cut the value to fit its bound |
| `encoding` | `json`, `text` or `base64` |
| `preview` | Display fragment; not guaranteed to be a complete value |

| Common state | Meaning |
| - | - |
| `stored` | Capture reported stored data, or a pending capture resolved to readable bytes; trace detail does not recheck every stored handle |
| `pending` | Capture was reported before the trace sampling decision, and its bytes are not readable now |
| `sampled_out` | Root value excluded by the trace sampling decision |
| `dropped` | Held bytes evicted before the capture record was built |
| `too_large` | Size prevented the normal truncate-and-keep path |
| `not_captured` | Capture did not attempt to represent this value |
| `expired` | Bytes unavailable now; this also covers values that have not arrived |

`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](https://docs.vexlo.ai/deployment/retention.md).

## Find related requests

`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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.