Copied to clipboard

Inspect

Query the API server to explore captured conversations. The /v1/* read surface follows the derived model: sessions (one row per agent run, UUID-keyed) contain traces (user-visible turns), which contain spans (the llm calls, tools, subagents, and injected context within a turn). The flow is lazy: list sessions, fetch a session's trace summaries, then drill into a single trace and its span payloads.

System

GET /ping Health check endpoint
GET /metrics Prometheus RED metrics (unauthenticated)
GET /v1/stats Aggregate counts, tokens, cost, duration, tool calls

Sessions

The product session view, backed by the sessions table the deriver populates.

GET /v1/sessions One agent session per row, cursor-paginated (?limit, ?cursor). Server-side sorting via ?sort (last_active, started_at, turn_count, total_cost_usd, total_tokens, duration_ns, derived_status, auth_subject) and ?direction (asc|desc; default last_active desc). Supports ?since/?until and ?auth_subject. Each row carries folded model, token, cost, turn-count, and per-model usage rollups
GET /v1/sessions/:id A single session record with its folded rollups
DELETE /v1/sessions/:id Permanently delete a session and its subtree — subagent child sessions and their derived traces/spans cascade with it. The immutable raw_turns capture log is left intact, and a re-derive cannot resurrect a deleted session
GET /v1/sessions/:id/raw_turns The operator wire log: the raw captured turns for the session, before derivation

Export

HTTP mirrors of tapes export's JSONL grain — both surfaces render from the same code path.

GET /v1/sessions/:id/export One session as a downloadable JSONL attachment: the session object with its traces, each carrying its full spans — the same grain as tapes export (pass ?detail=traces for turn headers only)
GET /v1/sessions/export Bulk JSONL export of every session in a time window (?since/?until, default trailing 30 days; ?detail=spans|traces), streamed newest-first and not bounded by the list cap

Traces & spans

The conversation content. Traces are a session's user-visible turns; spans are the nested operations within a turn. Fetch summaries first, then drill into one trace, then into one span's full payloads.

GET /v1/sessions/:id/traces The session's turns as traces with nested spans (llm, tool, agent, event) and dataflow links
GET /v1/traces Lazy trace summaries for a session (turn headers, no span payloads) — pass ?session_id
GET /v1/traces/:trace_id One trace with its spans (nested by parent_span_id) and links (?payload=full|preview)
GET /v1/traces/:trace_id/spans/:span_id The payload drill-in: one span's complete input/output content
GET /v1/search/spans Semantic search over the span projection; each hit carries span, trace, and session context (requires embeddings)
ALL /v1/mcp MCP server for agent integration (requires embeddings)

API server runs on port 8081 by default when using tapes serve. The /metrics endpoint is intentionally unauthenticated so an in-cluster Prometheus can scrape it — see tapes serve metrics. For MCP endpoint details, see MCP API Reference.

OpenAPI Spec

The API server ships its own generated reference. With tapes serve running:

GET /swagger Interactive Scalar UI rendered from the OpenAPI spec
GET /swagger/doc.json Swagger 2.0 spec (JSON) — feed it to your client codegen of choice

Open http://localhost:8081/swagger in a browser for the live reference.

Browser web UI

The API server ships an optional minimal browser UI for stepping through recent sessions and their turns. It is off by default; enable it explicitly so an unintentionally exposed API server doesn't serve a UI.

# Standalone API server
tapes serve api --web-ui --postgres "$DSN"

# All-in-one
tapes serve --api-web-ui --postgres "$DSN"

With the flag set, the API server serves the UI at /. It reads the same /v1/sessions and /v1/sessions/:id/traces endpoints documented above, so you can build your own front end against them.

Last updated: