Session Analysis API Usage Guide
Understand the full cost and event tree for any Telnyx AI or voice session — from a single inference call to complex multi-product conversations.What is Session Analysis?
Session Analysis gives you a complete view of costs and events for any usage session on the Telnyx platform:- Full event tree — parent events, child events, and their relationships
- Rollup costs — per-event costs plus cumulative totals across the session
- Product linkages — how different Telnyx products interacted in a single session
When to Use It
Core Concepts
Record Types
A record type identifies the category of usage event for a Telnyx product. Each record type maps to a specific product and has defined relationships to other record types. Example:ai-voice-assistant is the record type for AI Voice Assistant sessions, which have inference events as children.
Sessions
A session is a tree of related usage events. The root event is the primary event you’re analyzing. Child events are related usage that occurred as part of that session. Example: An AI Voice Assistant call with a carrier leg involves acall-session root with a call-control child, which in turn has an ai-voice-assistant child with inference events underneath — each representing one LLM turn in the conversation. Assistant conversations without a carrier leg (for example realtime WebSocket conversations) are analyzed from the ai-voice-assistant root instead — see Choosing the root record type for when each root applies.
Relationships
Events are connected via relationships:
Relationships are defined via field mappings — the child’s
local_field matches the parent’s parent_field. For example, inference events link to their ai-voice-assistant parent via the conversation_id field.
Cost Rollup
Each event node includes:event_cost— Cost of this individual eventcumulative_cost— This event’s cost plus all descendant costs
cumulative_cost equals the total session cost. For AI sessions, this means the call-session cumulative cost includes everything — the AI assistant, each inference turn, STT, TTS, call control, and SIP trunking — rolled up into one number.
Endpoints
1. List All Record Types
record_types[]— Array of all record types with their parent/child relationshipsquery_parameters— Valid parameters for session analysis queriesmeta— Total count and last updated timestamp
2. Get Record Type Details
- Valid child and parent relationships
- Example query URLs
- Recommended max depth for traversal
3. Get Session Analysis
You can find event IDs in the individual webhooks or detail records for the applicable event.
Which record type should I use? It depends on what the assistant conversation is anchored to:
- For assistant calls with a carrier leg —
phone_callchannel conversations, which carrycall_session_idin their conversation metadata — start withcall-sessionand pass the carrier leg’scall_session_id(the Call Controltelnyx_session_id) as theevent_id. This gives you the carrier-leg tree — call control, SIP trunking, recording, and the AI assistant subtree with its inference events — in one query. - For assistant conversations with no carrier leg — a realtime WebSocket conversation (
websocket_callchannel), or any conversation whose metadata has nocall_session_id— the AI subtree is not reachable fromcall-session: the assistant billing row carries notelnyx_session_idto join on. Root the analysis atai-voice-assistantinstead, using theconversation_idfrom AI Conversations as theevent_id, and query the carrier leg separately when one exists. See Analyzing an assistant conversation byconversation_idbelow.
Example:
Response Structure
Top-Level Fields
Event Node Structure
Each event in the tree follows this structure:Relationship Object
For child events, therelationship field explains the connection:
Note: The
via fields vary by relationship. AI-related linkages often use conversation_id, while voice/telephony relationships typically use telnyx_session_id or call_session_id.
Example: AI Voice Assistant Session
A customer makes an inbound call to an AI Voice Assistant using the Telnyx Web Dialer. The assistant handles a multi-turn conversation over ~152 seconds. Query:
Key observations:
- The call-session root has $0.00 event cost — it’s a container for the session, not a billable event itself.
- ai-voice-assistant is the dominant cost at $0.18 (billed at $0.06/min for 3 billed minutes). Its cumulative cost of $0.1921 includes 5 inference events underneath.
- Each inference event represents a single LLM call during the conversation — one per assistant turn. The cost per turn varies based on the model and token count.
- call-control has a $0.0052 event cost but a $0.1973 cumulative cost — the difference is the ai-voice-assistant subtree rolling up underneath it.
- recording, webrtc, and sip-trunking are leaf nodes with no children, so their event cost equals their cumulative cost.
Understanding the AI Cost Structure
In an AI-powered call, costs come from multiple layers:
Session Analysis rolls all of these into one tree, so you can see exactly where cost accumulates — whether it’s the AI assistant minute rate, the number of inference turns, or the underlying voice transport.
Analyzing an assistant conversation by conversation_id
For the conversation-level cost of an AI assistant conversation — the total and per-component breakdown shown in the Mission Control Portal’s per-conversation Call Cost view — the retrieval path depends on the conversation’s channel.
Retrieving the AI subtree
For assistant calls with a carrier leg, thecall-session tree described above already contains the AI assistant subtree: GET /v2/session_analysis/call-session/{call_session_id}?max_depth=3 returns call control, SIP trunking, and the ai-voice-assistant node with one inference child per assistant turn (max_depth=3 or higher is needed — the default of 2 stops at the assistant node).
For assistant conversations without a carrier leg — a realtime WebSocket (websocket_call) conversation, or any conversation whose metadata carries no call_session_id — the assistant billing row has no telnyx_session_id to join to a call-control parent, so the AI subtree is absent from the call-session tree. Root the analysis at ai-voice-assistant with the conversation’s conversation_id as the event_id — the ai-voice-assistant record is keyed by the conversation id:
cost.total is the full cost of the assistant conversation, and the root node’s record carries the per-minute assistant billing fields (rate, rate_measured_in, duration). Each inference child record names the model and its prompt, cached, and completion token counts, with its own event_cost.
To list the billing rows directly instead of walking the tree, use the Detail Records API with filter[record_type]=ai-voice-assistant and filter[conversation_id]=<conversation_id>.
Retrieving the carrier leg separately
When a WebSocket assistant conversation was bridged to the phone network — the assistant on the WebSocket leg, the caller on a carrier leg — the carrier-leg usage (call control, SIP trunking) is billed under its own session and must be queried separately:- Find the
call_session_idof the carrier leg — for example via the assistant’s call-control webhook, or by listingcall-controldetail records for the traffic in question, whosetelnyx_session_idis the join key. - Query that session’s tree:
GET /v2/session_analysis/call-session/{call_session_id}?max_depth=3.
ai-voice-assistant node for such conversations, and the ai-voice-assistant tree contains no carrier-leg records. Adding the cost.total of the two queries gives the combined assistant and carrier-leg cost of the call — not necessarily the whole bill: a record type that joins a session tree only through a call-control parent (media-streaming, for example) can carry charges that appear in neither of these two trees. To reconcile a bill in full, also list the remaining billing rows by record type with the Detail Records API — media-streaming accepts the carrier leg’s call_session_id as a filter, not conversation_id.
Telephony-side record types (call-session, call-control) do not accept conversation_id as a Detail Records filter — filter those by telnyx_session_id instead.
Common Use Cases
Debugging High-Cost AI Sessions
- Query the session with
max_depth=5to get the full tree - Look at
meta.productsto see which products were involved - Compare
event_costacross children — ifai-voice-assistantis the driver, check how many inference turns occurred underneath - Check
recordfields for rate information (rate,rate_measured_in) and duration
Finding Related Events
- Start from any event in the tree
- Use
relationship.viato understand the field linkage - Query the parent or children directly using their
id
Exporting for Analysis
- Use
expand=noneto get just the tree structure without full records - Flatten the tree programmatically for spreadsheet import
- Or keep full records and parse specific fields (e.g.,
rate,duration_sec)
Best Practices
Performance
- Provide
date_timewhen you know it — this narrows the index search and improves response time - Use appropriate
max_depth— start with2, increase only if needed. AI sessions with inference events typically needmax_depth=4or5to reach the leaf level. - Use
expand=noneif you only need cost rollups, not full records
Querying
- Start from the event that anchors the usage — for assistant calls with a carrier leg that is the
call-sessionroot; for assistant conversations without one (for example realtime WebSocket conversations), root atai-voice-assistantand query the carrier leg separately - Check metadata first —
/metadata/{record_type}shows expected children and recommended depth - Use
links.recordsto get the underlying detail records for deeper analysis