Skip to main content
The dashboard is a Next.js web console that sits on top of the VoicEra REST API. It gives you a browser interface for creating agents, wiring provider credentials, attaching phone numbers, and reviewing call history — work you would otherwise do with HTTP requests against /docs.
The dashboard container runs Next.js in development mode with the source bind-mounted. That is right for local work and wrong for anything user-facing — see Production deployment.

What it is

A single-page-feel Next.js App Router application under frontend/ — 119 files, all client-rendered behind an auth gate. It holds no state of its own: it authenticates against POST /users/login, stores the bearer token in browser localStorage (frontend/src/lib/auth-storage.ts), and every screen is a view onto an API call. Because it is a browser client, it can do one thing the API alone cannot: place a live microphone call to a websocket agent through the runtime. See Browser test calls.

Status

The API knows about the dashboard in exactly one place: FRONTEND_URL (default http://localhost:3000) is used to build password-reset links in apps/api/app/services/user_service.py. Nothing else in the core stack depends on it.
frontend/README.md is unmodified create-next-app boilerplate. Ignore it — the behaviour described on these pages comes from the source files.

The stack

All versions are from frontend/package.json. There is no state-management library, no data-fetching library, and no component framework: fetches go through a single apiFetch helper and state is plain React hooks.

What it talks to

Two services, over two protocols. Next.js serves the pages and proxies both REST (/api/v1/*API_PROXY_TARGET) and browser test-call WebSockets (/agent/...RUNTIME_PROXY_TARGET). frontend/src/lib/api/http.ts calls same-origin /api/v1, and frontend/src/lib/pipecat/createBrowserClient.ts opens a same-origin WebSocket that Next forwards to the runtime.

API surfaces it consumes

Every request is built in frontend/src/lib/api-client.ts or frontend/src/lib/api/*.ts. Paths below are relative to the API base, which defaults to http://localhost:8000/api/v1. Recordings and transcripts come back as blobs rather than JSON, because <audio src> cannot send an Authorization header — apiFetchBlob fetches them with the bearer token and the UI builds an object URL. frontend/src/lib/api-types.ts holds the TypeScript shapes for all of the above; it is the frontend’s copy of the API contract, not a generated client.

When to use it instead of the API

Treat the dashboard as a convenience layer for exploration and one-off setup. Production operations belong on the API.