Traces
Cross-layer correlation with trace IDs and combined funnels
The trace ID is the correlation key that stitches server-side and widget-side events into a single end-to-end journey. This cross-layer visibility is what makes Yavio unique — you can follow a user's journey from the initial tool call on the server through to the final conversion in the widget UI.
Trace Lifecycle
Here's what happens when a user interacts with your MCP app:
- User sends a prompt to the AI platform (ChatGPT, Claude, Cursor, etc.)
- The AI platform invokes an MCP tool —
withYavio()intercepts the call - The proxy generates a
trace_id(e.g.,tr_+ a random ID) and inherits thesession_idfrom the current MCP connection - The tool handler executes — any
yavio.step()calls inherit the trace ID - If the tool returns a widget response, the proxy mints a short-lived widget JWT
- The proxy injects
window.__YAVIO__with the trace ID, session ID, widget JWT, and endpoint - The widget renders and initializes
useYavio(), which reads the injected config - Widget events are sent directly to the ingestion API with the same trace ID
- In the dashboard, the trace ID ties the tool call to the widget it rendered; a funnel follows the whole conversation (the session ID), across its traces
Combined Funnel Example
A single trace might contain events from both server and widget:
| Step | Source | Event Type | Data |
|---|---|---|---|
| 1 | Server (auto) | tool_call | tool: "search_rooms", latency: 234ms |
| 2 | Server (explicit) | step | name: "rooms_found", count: 12 |
| 3 | Server (auto) | widget_response | widget token minted |
| 4 | Widget (auto) | widget_render | viewport: 400x600 |
| 5 | Widget (explicit) | step | name: "room_selected" |
| 6 | Widget (explicit) | step | name: "details_completed" |
| 7 | Widget (explicit) | conversion | name: "booking_completed", value: 567 EUR |
Session vs Trace Hierarchy
Sessions and traces have a one-to-many relationship. A single conversation (session) typically holds multiple tool invocations, each with its own trace:
Session (ses_xxx) ← one conversation
├── Trace 1 (tr_aaa) ← tool_call "search_rooms"
│ ├── step: "rooms_found" (server)
│ ├── widget_render (widget)
│ ├── step: "room_selected" (widget)
│ └── conversion: "booking_completed" (widget)
├── Trace 2 (tr_bbb) ← tool_call "check_availability"
│ └── step: "availability_checked" (server)
└── Trace 3 (tr_ccc) ← tool_call "cancel_booking"Both server and widget events share the same session_id. The trace_id provides the finer-grained correlation between a specific tool call and the widget it spawned.
Step Sequencing
When you call yavio.step() or useYavio().step(), the step gets a step_sequence number. On the server it is a counter per session in each server process, starting at 1: it starts again on every instance of a stateless fleet that serves the conversation, and after the SDK's session cache evicts it. The widget keeps its own counter per widget load, starting at 1; it does not continue from the server.
The dashboard's funnels therefore number a conversation's steps by time: steps are ordered by their timestamp, and step_sequence only breaks a tie between steps in the same millisecond. One conversation is one attempt however many instances served it; widget steps are placed among the server's by the browser's clock.
Funnel Analytics (Coming Soon)
The dashboard's funnel view will use sessions and trace IDs to:
- Visualize step progression — see how conversations move through your defined funnel steps
- Calculate drop-off rates — identify where users abandon the journey
- Inspect individual traces — drill into a specific trace to see every event that occurred
- Compare funnels across platforms — see if ChatGPT users convert differently than Claude users
The Funnels and Paths dashboard views are coming soon. Event data is already being collected — once the views launch, you'll have full historical visibility.