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

# Dashboard

> Embedded web dashboard for real-time call monitoring, latency, and cost analytics.

# Dashboard

Patter ships a built-in web dashboard for monitoring calls in real time. It runs alongside your agent server and gives you a visual interface for live call tracking, latency analysis, cost breakdowns, and historical data export.

<Note>
  The dashboard was rewritten as a Vite + React single-page app in the latest release. The user-facing experience is unchanged — `phone.serve()` still serves the UI from `http://127.0.0.1:8000/`, with no extra build step, no CDN dependency, and identical routes. Only the visuals and internal organisation have changed.
</Note>

## Enabling the dashboard

The dashboard is enabled by default whenever you start a server in local mode:

```python theme={null}
await phone.serve(
    agent,
    port=8000,
    dashboard=True,             # Enable dashboard (default: True)
    dashboard_token="secret",   # Optional: protect with a token
)
```

Once running, open your browser at `http://127.0.0.1:8000/`.

<Tip>
  When `dashboard=True` and no `dashboard_token` is set, the SDK logs a warning at startup. For anything beyond local development, always set a token — the dashboard surfaces transcripts and customer phone numbers.
</Tip>

## Authentication

Protect the dashboard with a token:

```python theme={null}
await phone.serve(
    agent,
    port=8000,
    dashboard_token="my-secret-token",
)
```

Access via:

* **Browser**: `http://127.0.0.1:8000/?token=my-secret-token`
* **API**: `Authorization: Bearer my-secret-token` header

When no token is set, the dashboard is accessible without authentication (intended for `127.0.0.1` development only).

## What you see

The dashboard is a single-page app that consumes the SDK's existing `/api/dashboard/*` endpoints and pushes live updates over Server-Sent Events.

### Top metrics row

Aggregate counters across the in-memory ring buffer (last 500 calls):

* **Total Calls** — completed + active
* **Total Cost** — summed across STT, LLM, TTS, and telephony
* **Avg Duration** — mean call length
* **Avg Latency** — end-to-end response latency

Numerics use JetBrains Mono so columns line up at a glance.

### Call table

All completed calls with cost, duration, turn count, latency, provider, and voice mode. Click any row to open the detail panel.

### Live-call right rail

When a call is active, the right rail shows it in real time:

* Caller / callee numbers (last-4 redacted in logs, full in UI)
* Live duration counter
* Streaming transcript with speaker labels
* **Per-call latency waterfall** — STT, LLM first-token, TTS first-byte, total turn latency
* **Cost breakdown** — running totals per component as the call progresses

When the call ends, it moves into the call table and the right rail clears.

### Call detail

Click any historical call to see the full transcript, the same latency waterfall (averaged + P95), and the same cost breakdown for that single call.

### Real-time updates

All views subscribe to `GET /api/dashboard/events` (SSE). New calls, transcript turns, and metric updates appear without polling or refresh.

## Data export

Export the call ring buffer in CSV or JSON:

| Format | Endpoint                                      | Shape                                       |
| ------ | --------------------------------------------- | ------------------------------------------- |
| CSV    | `GET /api/dashboard/export/calls?format=csv`  | One row per call, flat columns              |
| JSON   | `GET /api/dashboard/export/calls?format=json` | Full nested data including per-turn metrics |

## API endpoints

The dashboard UI is a thin client over a stable REST + SSE API. Use these directly to integrate with your own tooling.

| Endpoint                             | Description                                         |
| ------------------------------------ | --------------------------------------------------- |
| `GET /`                              | Dashboard web UI (single self-contained HTML file). |
| `GET /api/dashboard/calls`           | Paginated call history.                             |
| `GET /api/dashboard/calls/{call_id}` | Single call detail with full transcript.            |
| `GET /api/dashboard/active`          | Currently active calls.                             |
| `GET /api/dashboard/aggregates`      | Aggregate statistics.                               |
| `GET /api/dashboard/events`          | SSE event stream for live updates.                  |
| `GET /api/dashboard/export/calls`    | Export calls as CSV (`?format=csv`) or JSON.        |

### Example: fetch call history

```python theme={null}
import httpx

resp = httpx.get(
    "http://127.0.0.1:8000/api/dashboard/calls",
    headers={"Authorization": "Bearer my-secret-token"},
    params={"limit": 10, "offset": 0},
)
calls = resp.json()
```

### Example: subscribe to live events

```python theme={null}
import httpx

with httpx.stream(
    "GET",
    "http://127.0.0.1:8000/api/dashboard/events",
    headers={"Authorization": "Bearer my-secret-token"},
) as response:
    for line in response.iter_lines():
        if line.startswith("data:"):
            print(line)
```

<Note>
  The dashboard stores metrics in an in-memory 500-call ring buffer. Data persists across restarts via the on-disk hydration layer (see `dashboard/persistence.py`), but for long-term analytics use the `on_call_end` callback to write metrics to your own database.
</Note>
