Skip to main content
The runtime process handles live Sandwich voice sessions for the browser and Dot devices, browser Speech-to-speech client-secret exchange, and the Speech-to-speech Dot device bridge. The runtime verifies browser voice-session tokens, realtime browser-session tokens, and device credentials with the platform API before accepting /voice, /realtime/client-secret, or /ws traffic. Keep the runtime service behind normal deployment protections and use provider-key quotas for public previews. The platform API stores the OSS OpenDot control plane in PostgreSQL: app users, local auth credentials, user preferences, SDK API keys, versioned agents and pipelines, devices, device activation requests, device credentials, runtime session tokens, device state, and deployments. Create the root environment file once:
For local pnpm runs, leave POSTGRES_URI empty and the API/Drizzle commands use localhost:${POSTGRES_PORT:-5432} with the configured POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD. For Supabase, set POSTGRES_URI to the Supabase Postgres connection string and use POSTGRES_SSL=true. To verify Supabase Auth tokens at the OpenDot API boundary, set:
SUPABASE_URL enables JWKS verification for current Supabase signing keys. Set SUPABASE_JWT_SECRET only if the project still uses legacy HS256 JWT signing. When a Bearer token is provided, the API maps the Supabase JWT sub to app_users.id. The OSS core is intentionally single-workspace and does not rely on Supabase user_metadata for authorization-critical product state. For local Compose without Supabase, leave OPENDOT_LOCAL_AUTH_DISABLED=false and use the OpenDot auth page.

Database inspection

Use Drizzle Studio to inspect the current schema and persisted platform data:
Open https://local.drizzle.studio. The local Compose database uses:
If only the database is needed, start it with:

Required provider keys

Set provider keys in the root .env:
OPENAI_BASE_URL is optional. Leave it blank for OpenAI, or set it to the base of an OpenAI-compatible API such as https://example.com/v1. Agent-level LLM settings can also override the base URL and API key environment variable name from the Configuration page. Sandwich Browser Test and Sandwich Dot sessions need DEEPGRAM_API_KEY plus the configured LLM key. Speech-to-speech Browser Test and Speech-to-speech Dot sessions use OPENAI_API_KEY inside the runtime; Deepgram is not required for those Realtime sessions. The platform API mints a one-use realtime browser-session token at POST /api/runtime/realtime-browser-sessions, the runtime exchanges it for an OpenAI Realtime client secret at /realtime/client-secret, and the browser uses that short-lived client secret for the WebRTC call. Dot devices never receive an OpenAI key or client secret; the runtime opens the server-side OpenAI Realtime WebSocket on their behalf. The selected LLM Provider API controls which path the runtime calls: Responses appends /responses, while Chat Completions appends /chat/completions.

Frontend runtime URL

The browser test uses this WebSocket by default:
Override it for the frontend with:
The Dot Device page can use an explicit HTTP base URL:
If VITE_RUNTIME_HTTP_URL is not set, the frontend derives the HTTP base from VITE_RUNTIME_WS_URL. Speech-to-speech Browser Test gets its runtime HTTP URL from the platform API response, which is built from OPENDOT_RUNTIME_PUBLIC_HTTP_URL.

Runtime/API trust

The runtime calls internal platform API endpoints to verify /voice, /realtime/client-secret, and /ws flows and to proxy firmware activation:
Use the same OPENDOT_RUNTIME_INTERNAL_SECRET on the platform API and runtime services. In hosted deployments, set the public runtime URLs to the externally reachable runtime service so browser session tokens, realtime client-secret exchange, and device OTA config point at the right host.

Turn-close defaults

These local defaults keep device turns balanced while reducing wait time:
When CLOSE_DEVICE_AFTER_TURN is enabled, the runtime closes the device audio socket shortly after a completed Sandwich or Speech-to-speech turn so firmware can return to idle or wake-word mode.

TTS defaults

The runtime TTS sample rate defaults to:
For browser playback experiments, tune the TTS stage in Configuration:
  • Encoding
  • Sample rate
  • Browser delivery
  • Chunk style