Skip to main content

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
This is especially valuable for AI-powered sessions, where a single call can involve multiple Telnyx products — AI Voice Assistant, inference, speech-to-text, text-to-speech, call control, SIP trunking, and more — all layered into one conversation.

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 a call-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 event
  • cumulative_cost — This event’s cost plus all descendant costs
The root event’s 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

Returns all available record types, their relationships, and query parameter options. Response includes:
  • record_types[] — Array of all record types with their parent/child relationships
  • query_parameters — Valid parameters for session analysis queries
  • meta — Total count and last updated timestamp
Example:

2. Get Record Type Details

Returns metadata for a specific record type with additional details:
  • Valid child and parent relationships
  • Example query URLs
  • Recommended max depth for traversal
Example:

3. Get Session Analysis

Retrieves the full session analysis tree for a specific event. Path Parameters: 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_call channel conversations, which carry call_session_id in their conversation metadata — start with call-session and pass the carrier leg’s call_session_id (the Call Control telnyx_session_id) as the event_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_call channel), or any conversation whose metadata has no call_session_id — the AI subtree is not reachable from call-session: the assistant billing row carries no telnyx_session_id to join on. Root the analysis at ai-voice-assistant instead, using the conversation_id from AI Conversations as the event_id, and query the carrier leg separately when one exists. See Analyzing an assistant conversation by conversation_id below.
Use the metadata endpoint to explore other starting points for different products. Query Parameters: Example:

Response Structure

Top-Level Fields

Event Node Structure

Each event in the tree follows this structure:

Relationship Object

For child events, the relationship 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:
Session tree:
Summary: 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, the call-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:
The response’s 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:
  1. Find the call_session_id of the carrier leg — for example via the assistant’s call-control webhook, or by listing call-control detail records for the traffic in question, whose telnyx_session_id is the join key.
  2. Query that session’s tree: GET /v2/session_analysis/call-session/{call_session_id}?max_depth=3.
The two queries do not overlap: the carrier-leg tree contains no 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

  1. Query the session with max_depth=5 to get the full tree
  2. Look at meta.products to see which products were involved
  3. Compare event_cost across children — if ai-voice-assistant is the driver, check how many inference turns occurred underneath
  4. Check record fields for rate information (rate, rate_measured_in) and duration
  1. Start from any event in the tree
  2. Use relationship.via to understand the field linkage
  3. Query the parent or children directly using their id

Exporting for Analysis

  1. Use expand=none to get just the tree structure without full records
  2. Flatten the tree programmatically for spreadsheet import
  3. Or keep full records and parse specific fields (e.g., rate, duration_sec)

Best Practices

Performance

  • Provide date_time when you know it — this narrows the index search and improves response time
  • Use appropriate max_depth — start with 2, increase only if needed. AI sessions with inference events typically need max_depth=4 or 5 to reach the leaf level.
  • Use expand=none if 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-session root; for assistant conversations without one (for example realtime WebSocket conversations), root at ai-voice-assistant and query the carrier leg separately
  • Check metadata first — /metadata/{record_type} shows expected children and recommended depth
  • Use links.records to get the underlying detail records for deeper analysis

Error Handling


Record Types Reference

AI & Voice Intelligence

Voice & Telephony

Media & Storage

Conferencing

Messaging

Video

Other Products