Skip to main content
A trace is a single complete agent execution: input, LLM calls, tool calls, output. Every other feature (evaluation, compatibility scoring, dataset building) operates on traces. Each trace is auto-tagged with the manifest hash of the agent that produced it — that’s what makes the regression check work.

Lifecycle

Common patterns

Instrument a Python agent

Add decimalai.init(langchain=True) (or your framework’s flag). All trace ingest is then automatic via the SDK — you rarely call POST /traces directly.

Search by criteria

The GET /traces endpoint accepts filters for agent, status, manifest, eval verdict, score range, and full-text search. There’s no separate /search endpoint.

Bulk import historical data

Migrating from another tool? Use POST /traces/import-bulk (or POST /traces/import for a JSONL upload). Duplicates are silently skipped — re-running is safe.

Inspect a single trace

GET /traces/{id} returns the full span tree, LLM call messages, and tool calls. Pass include=eval_scores to fetch quality scores in the same call.

Structure

A trace contains two child types:
TypeWhat it representsExamples
SpansContainers and non-LLM operations. Nest via parent_span_id.agent_planning, tool_execution, retrieval
LLM callsIndividual model invocations at full fidelity (prompt, completion, tokens, latency). Link to a parent span via span_id.Each chat.completions.create() call
See Execution Model for the full data model.

Quick start

import decimalai
decimalai.init(api_key="dai_sk_...", openai_agents=True)

# Traces flow automatically as your agent runs.

# To search:
import httpx
resp = httpx.get(
    "https://api.decimal.ai/api/v1/traces",
    headers={"Authorization": "Bearer dai_sk_..."},
    params={"agent_name": "my-agent", "eval_verdict": "drop", "limit": 20},
)
for t in resp.json()["traces"]:
    print(t["id"], t["eval_score"])