Skip to main content
Find a request with GET /v1/traces, then use its trace_id to read calls and values. Search by an identifier you already have, such as a tag value, before widening to a service and time window.

Route index

All routes below use the server’s base URL. The versioned API prefix is /v1. The relay uses POST /v1/records and POST /v1/heartbeat with ingest credentials. Use the Python SDK to record application execution and the configuration commands to update capture policy through PUT /v1/policy.

Authentication and common conventions

In bearer-token mode, read routes require Authorization: Bearer followed by a read token. GET /v1/whoami accepts either token role and reports its identity and scope. GET /v1/capabilities needs no token. The web UI’s /config.json is also unauthenticated. List routes accept limit and cursor. The default list limit is 50, the maximum 500. Responses contain items, the applied limit, and next_cursor: a string for another page, null when the page ends the walk. Treat the cursor as opaque. limit must be a positive integer; values above the maximum are clamped. The response reports the applied bound. Team-scoped listings accept team to narrow the token’s team set. Requested teams outside that set yield no matching rows. environment accepts comma-separated names; use environment_unset=true for recordings with no environment. Setting both produces 400 conflicting_filters. Omitting both applies no environment filter. The tags route accepts environment but ignores environment_unset. Instants use RFC 3339 UTC with millisecond precision. Trace-level durations use integer milliseconds; call and attempt timings use microseconds. IDs and cursors are opaque.

Capabilities and identity

GET /v1/capabilities returns server_version, api_version, features, auth_mode and limits. auth_mode is bearer, header_trust or none. Current feature in_flight_attempts means a trace can contain attempts with no duration or slots yet. Limits report search/step page sizes, values-path bounds, accepted record formats and rate limits. This bootstrap response contains no team or environment data. GET /v1/whoami returns role, team_ids, service_scope and environment_scope. Unpinned scopes are null. Use it to confirm the credential actually presented by the client.

Find requests

GET /v1/traces Time filtering uses the server’s first_seen_at, not the SDK’s started_at. A recording delivered after an outage therefore falls within its arrival window even when execution began earlier. trace_id ignores the other search filters. Token team scope still applies, and the response has no next page. Ordinary results sort by last_seen_at descending. A value-only tag search also returns matched_tag_keys so you can see which keys matched. error_step_count counts calls with any failed attempt. A call that fails and then succeeds still counts once. has_error=true can therefore find a recovered failure whose root_status is ok. Rows include trace_id, service, team, instance_id, tags, started_at, step_count, error_step_count and recording-loss fields. root_function is omitted until known; root_status and duration_ms are omitted until the root completes. environment is omitted when it was not recorded.

Find functions and observed dependencies

name is an exact equality filter. The server applies it after pagination, so an empty filtered page can still have next_cursor. Continue until that cursor is null before concluding that the catalog has no match. Function rows report observed_count, error_count, first_seen_at, last_seen_at and is_entry_point. observed_count counts calls once each; error_count counts errored attempts. These counters accumulate while each relationship remains in the index; they are not rolling 90-day counts. Inactive relationships expire 90 days after their last observation. team appears only when the effective query covers one team, including a multi-team token narrowed to one team. The catalog’s is_entry_point currently requires a service filter and is computed across that service’s environments. Without service, catalog rows report false; with an environment filter, that flag can reflect another environment. Use function detail with the required service/name and intended environment to verify entry-point observations in scope. A never-observed (service, name) returns 200 from the detail route with observed_count: 0, empty caller/callee lists and omitted first_seen_at / last_seen_at. A null caller name means the function was observed as an entry point or without its parent. Observed callers are evidence from recorded execution, not a list of every possible dependency. Examples return previews by default; include=values adds full stored values. The endpoint returns at most five retained examples, without pagination. The store retains examples per caller/callee edge and pools them for this response. Environment filtering and expired source traces can reduce the result, including to an empty list. These examples are not a full execution history. Each function example identifies trace_id, path, attempt, started_at and status, with input and output capture metadata when those slots were reported. An unreported slot is omitted, rather than returned with an empty state. include=values adds readable bytes under value within those objects. A zero-length payload omits value and bytes_count while retaining encoding and truncated. Unlike the trace-values route, retained examples identify the attempt whose inputs and outputs are read. They do not provide arbitrary trace/attempt selection.

Discover tags and check recording health

All three require a read token and accept scope filters. health is not an unauthenticated liveness endpoint. The relay’s own /healthz and /metrics live on its health listener, configured separately with -health-addr. GET /v1/tags returns paginated items containing key, services and distinct_value_count, sorted by key. It lists keys and counts rather than full tag values. GET /v1/coverage is not paginated. Its services rows contain service, optional environment, traces_24h, marked_functions_seen, records_lost_24h, records_shed_24h and last_seen_at. The marked-function count describes observed functions, not uninstrumented code. Activity/loss fields and the observed-function index have different lifetimes. GET /v1/health returns status, mode, shape_store, value_store, stubs_swept_24h and services. shape_store contains disk_used_bytes and effective_retention_days. value_store contains bytes_used, byte_budget and effective_retention_estimate_hours. Service rows report recorded loss, shedding and last activity. Healthy responses use HTTP 200; degraded responses use 503. A storage estimate is not guaranteed value availability for an individual trace.

Errors

The rate-limited read surface reports X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. On 429, honor Retry-After before retrying; it is an integer number of seconds capped at 60. Bootstrap capabilities are excluded from per-token rate limiting. Errors use an error object containing code and message, with optional machine-readable details. Invalid query syntax uses 400 invalid_request; exceeding the by-ID search bound uses 422 too_many_trace_ids. Missing name on function detail/examples uses 400 invalid_request. For 404 on a named trace, “not visible to this token” and “absent” have the same response. Do not infer that the request never ran. For missing data, follow the recording path.