Traces — the why, not just the what.
Reasoning provenance. Each trace records a decision, the reasoning behind it, the context it was made in, and an optional ed25519 signature. Linked into chains for multi-step decisions. Searchable by Postgres full-text.
Memory records what was experienced. Traces record why a decision was made. The two are different organs.
Anatomy of a trace
| Field | Type | Description |
|---|---|---|
| decision_type | string | What kind of decision — tool_choice, refusal, strategy_switch, freeform. |
| decision_summary | string | One-line summary of what was decided. |
| reasoning | string | The argument — what was weighed, what was ruled out, what tipped it. |
| context | object | The state at decision time — input, observed values, relevant memories. |
| conclusion | string | The action taken (or refused). |
| confidence | float (0.0–1.0) | How sure the agent was. Crucial for downstream auditing. |
| parent_trace_id | uuid | Optional — links this trace to its predecessor for chain reconstruction. |
| signature | base64 | Optional ed25519 signature for verifiable provenance. |
Endpoints
Record a reasoning trace. The body shape mirrors the table above.
curl -X POST https://api.agenttool.dev/v1/traces \
-H "Authorization: Bearer $AT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"decision_type": "tool_choice",
"decision_summary": "Pick scrape over browse for static page",
"reasoning": "Page returns 200 with full HTML; no JS-rendered content needed. Scrape is 30x cheaper.",
"context": { "url": "https://example.com/article", "headers": {...} },
"conclusion": "called /v1/scrape",
"confidence": 0.92
}'
Fetch a single trace by ID.
List recent traces. Filterable by decision_type and min_confidence.
Permanent. Traces are usually kept — they're the record of why.
Full-text search
Postgres tsvector full-text search over decision_summary, reasoning, and conclusion. No LLM compute on our side — pure FTS. Pair with /v1/memories/search for vector recall when you need it.
curl -X POST https://api.agenttool.dev/v1/traces/search \
-H "Authorization: Bearer $AT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "refusal AND fabrication", "limit": 10}'
Reasoning chains
Traces with parent_trace_id form trees. The chain endpoint walks ancestors and descendants via a Postgres recursive CTE.
Returns the full lineage — ancestors (parents up to the root) and descendants (children downward). Useful when you ask "how did we get here?"
{
"target": { "trace_id": "...", ... },
"ancestors": [/* parent → grandparent → root */],
"descendants": [/* children → grandchildren → leaves */]
}
Verifiable traces
Sign the canonical trace payload with the agent's ed25519 key. The signature anchors authorship — another agent can verify the trace really came from this DID.
Canonical payload: SHA-256(decision_type || \0 || decision_summary || \0 || reasoning || \0 || conclusion || \0 || canonical_json(context)).
Sign client-side. Send signature with the POST. We verify against the agent's active key before accepting.