Attribution Data API
Get session call tree
Reconstructs one session's span call tree: one node per span with its own cost, its subtree cost (the span plus every descendant), and its nested children, so you can see which branch of a multi-agent run spent the money. Call it with a GET request to /attribution-data/sessions/{sessionId}/tree, authenticated with a restricted API key and the "costs:read" scope.
Reconstructs one session's span call tree: one node per span with its own cost, its subtree cost (the span plus every descendant), and its nested children, so you can see which branch of a multi-agent run spent the money. Roots are ordered by subtree cost descending. Unlike the other attribution endpoints, the lookup spans all time; it is not bounded by a date range. Use spans (see the tracing guide) to link calls into a tree; events that carry the session_id but no span_id are reported in the untraced bucket rather than as tree nodes. The sum of the root subtree costs plus the untraced total always equals the session's flat total from the sessions endpoints. Malformed span chains never lose cost: a span whose parent id does not exist in the session is promoted to a root and flagged orphaned; a parent-pointer cycle is broken at a deterministic entry span flagged cycle; chains deeper than 32 levels are cut at a node flagged depth_capped, which keeps the pruned descendants' cost in its subtree cost. Requests count toward your per-API-key rate limit; sustained overruns return 429 with the standard error envelope.
Authentication and scopes
Authenticate with a restricted API key in the Authorization: Bearer <key> header. This endpoint requires the costs:read scope.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionId | path | string | Yes | The session_id metadata value to look up. |
Response fields
Fields returned in the 200 response body. Nested objects are listed under their parent. A field marked optional may be absent from the body; one marked nullable is always present but its value may be null.
| Field | Type | Description |
|---|---|---|
session_id | string | The session_id value shared by this session's usage events. |
roots | object[] | Root spans of the session's call tree, ordered by subtree_cost descending. Spans whose parent id is missing from the session appear here flagged orphaned. |
span_id | string | This span's id (the span_id value on its usage events). |
parent_span_id | string nullable | The caller's span id (the tree edge); null on a true root span. |
name | string nullable | Span label from the span_name event field; null when never provided. |
kind | string nullable | Span kind from the span_kind event field (agent, tool, llm, retrieval, task); null when never provided. |
agent_id | string nullable | The agent_id attribution label on this span's events; null when absent. |
own_cost | string | Cost of this span's own events (USD, decimal string). |
subtree_cost | string | Cost of this span plus every descendant span (USD, decimal string). Includes descendants beyond the depth cap even though they are not materialized as children. |
event_count | number (double) | Number of this span's own usage events. |
depth | number (double) | Depth in the materialized tree; roots are depth 0. |
orphaned | boolean | True when this span's parent id does not exist in the session, so the span was promoted to a root instead of being dropped. |
cycle | boolean optional | Present and true when a parent-pointer cycle was detected here: either this span was promoted to a root to break the cycle, or its child edge back into the cycle was pruned. Only manual span_id misuse can produce cycles; SDK-generated span ids cannot. |
depth_capped | boolean optional | Present and true when descendants deeper than the 32-level cap were cut from this node; their cost is still included in subtree_cost. |
children | object[] | Child spans, ordered by subtree_cost descending. |
untraced | object | Cost of the session's events that carry no span_id. |
total_cost | string | Total cost of the session's span-less events (USD, decimal string). |
event_count | number (double) | Number of the session's span-less usage events. |
Error codes
Errors return the standard error envelope with a code, message, and a correlationId you can quote to support.
| Status | When it happens |
|---|---|
400 | Invalid request data. Fix the field named in error.message and retry. |
401 | Missing or invalid API key. Send your key as Authorization: Bearer YOUR_API_KEY. |
403 | API key lacks the costs:read scope. Create or update an API key with the costs:read scope, then retry. |
404 | No session with this sessionId exists for your organization. Verify the session_id value sent on your usage events. |
429 | Rate limit or plan quota exceeded. Slow down and retry after the current window resets. |
Rate limits and retries
Rate limit or plan quota exceeded. Slow down and retry after the current window resets.