> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Voice Agent Quality Index (VAQI)

> Per-session latency, turn-turning, and barge-in metrics for voice AI agents — what VAQI measures, the session payload it records, the rollup it returns, and the dashboard page that renders it.

# Voice Agent Quality Index (VAQI)

A voice AI agent lives or dies on conversational feel — how fast it answers, how smoothly the turn passes between caller and agent, and whether the caller can interrupt it and be heard. The Voice Agent Quality Index (VAQI) measures exactly those three axes per session and rolls them up over a day window, so you can grade an agent's real-time behavior instead of inferring it from call counts.

VAQI is read-only analytics. It records metrics for sessions your voice AI agents handle (an active voice agent is required) and never touches the outbound call path.

## What VAQI measures

Every completed voice-agent session contributes one metrics record with three families of numbers:

* **Latency.** Time-to-first-byte (TTFB) per turn — the gap from the caller finishing their utterance to the agent's audio starting — plus the cumulative time the pipeline spent in speech-to-text (STT), language-model (LLM), and text-to-speech (TTS) stages.
* **Turn-taking.** How long the session lasted, how many caller↔agent turns it contained, and the per-turn gap statistics (average, minimum, and maximum) that tell you whether the agent consistently answers briskly or occasionally stalls.
* **Barge-in.** How often the caller talked over the agent, and how often that interruption actually succeeded — the caller's speech was captured and the agent yielded. A high barge-in count with a low success rate means the agent is steamrolling callers instead of listening.

## The session payload

Each session writes one JSON record with these fields:

| Field                                            | Meaning                                                                      |
| ------------------------------------------------ | ---------------------------------------------------------------------------- |
| `duration_ms`                                    | Total session length                                                         |
| `turns`                                          | Number of caller↔agent turns                                                 |
| `avg_turn_gap_ms`                                | Mean silence between the caller ending and the agent starting                |
| `min_turn_gap_ms` / `max_turn_gap_ms`            | Best and worst single-turn gap in the session                                |
| `avg_ttfb_ms`                                    | Mean time-to-first-byte across the session's turns                           |
| `barge_in_count`                                 | Times the caller spoke while the agent was speaking                          |
| `barge_in_success_count`                         | Of those, the times the agent actually yielded and captured the interruption |
| `total_stt_ms` / `total_llm_ms` / `total_tts_ms` | Cumulative time the session spent in each pipeline stage                     |

Records are kept per day per tenant, so the dashboard can window a rollup over recent days without scanning unrelated history. Sessions missing any of the numeric fields above (or carrying a non-finite value) are dropped from rollups rather than polluting the averages.

## The rollup

`GET /api/v1/voice/vaqi` reads up to `days` days of session records and reduces them to a dashboard-shaped aggregate. `days` is an integer between 1 and 30 (default 7).

| Response field                             | Aggregate                                                                                    |
| ------------------------------------------ | -------------------------------------------------------------------------------------------- |
| `days`                                     | The window that was queried                                                                  |
| `sessions`                                 | Number of sessions included                                                                  |
| `avg_session_duration_ms`                  | Mean session length                                                                          |
| `avg_turns_per_session`                    | Mean turns per session (one decimal)                                                         |
| `avg_turn_gap_ms` / `p95_turn_gap_ms`      | Mean and P95 per-session turn gap (zero-valued gaps excluded)                                |
| `avg_ttfb_ms` / `p95_ttfb_ms`              | Mean and P95 per-session TTFB (zero-valued values excluded)                                  |
| `avg_stt_ms` / `avg_llm_ms` / `avg_tts_ms` | Mean per-session cumulative STT / LLM / TTS time                                             |
| `barge_in_rate`                            | Barge-ins per 100 turns, expressed as a percentage (one decimal)                             |
| `barge_in_success_rate`                    | Percentage of barge-ins that succeeded (one decimal)                                         |
| `daily`                                    | Per-day series: `date`, `sessions`, `avg_turn_gap_ms`, `avg_ttfb_ms` — ordered oldest→newest |

The P95 figures matter more than the averages here: the percentile is computed on the sorted per-session values at the true 95% rank, so a small number of very slow turns shows up as a long P95 tail instead of being masked by a hard worst-case ceiling. If the metrics store is unreachable, the endpoint returns a zero-valued rollup (with an empty daily series) rather than an error, so the dashboard renders an empty state you can retry.

## The dashboard page

Open **Voice → VAQI** in the dashboard (visible to `owner`, `admin`, and `developer` roles). The page offers a 24 h / 7 d / 30 d window picker, shows the aggregates above as stat cards, and renders the daily series so you can spot a regression day rather than a slow-moving drift. The window selection is carried in the URL, so you can deep-link a teammate to a specific window.

## Reading the numbers

* **`avg_ttfb_ms` rising, `avg_stt_ms` flat:** the slowdown is downstream of transcription — check the LLM or TTS stage rather than telephony.
* **`max_turn_gap_ms` ≫ average with low P95:** a few stray turns are stalling, not the whole session — look for a specific phrasing or tool call that triggers it.
* **`barge_in_rate` high, `barge_in_success_rate` low:** callers are interrupting because the agent won't yield. Tighten the agent's barge-in settings rather than retraining the model.
* **Sessions = 0 on a day that had traffic:** metrics never landed (an empty window the collector didn't reach) — the daily series distinguishes that from a day of genuinely zero sessions because its per-day counts fall back to zero while other days still report.

## See also

* [Voice API](/api-reference/voice) — the full voice surface, including the per-call intelligence endpoints VAQI aggregates complement
* [Quality Management API](/api-reference/quality) — *human-agent* scorecards and calibration, which is a separate program from AI-agent VAQI
* [Voice call lifecycle](/concepts/voice-call-lifecycle) — the session lifecycle these metrics instrument
* [Operational sentinels](/concepts/operational-sentinels) — alerting on quality regressions once you've read the rollups
