Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.opendot.ai/llms.txt

Use this file to discover all available pages before exploring further.

The runtime process handles live voice sessions for the browser and Dot devices. The runtime verifies browser voice-session tokens and device credentials with the platform API before accepting /voice or /ws connections. 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:
cp .env.example .env
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=https://your-project-ref.supabase.co
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-supabase-anon-key
PLATFORM_AUTH_REQUIRED=true
OPENDOT_LOCAL_AUTH_DISABLED=true
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:
pnpm --filter ./platform run db:studio
Open https://local.drizzle.studio. The local Compose database uses:
POSTGRES_PORT=5432
POSTGRES_SSL=false
If only the database is needed, start it with:
docker compose up -d postgres migrate

Required provider keys

Set provider keys in the root .env:
DEEPGRAM_API_KEY=...
OPENAI_API_KEY=...

Frontend runtime URL

The browser test uses this WebSocket by default:
ws://localhost:8787/voice
Override it for the frontend with:
VITE_RUNTIME_WS_URL=ws://localhost:8787/voice
The Dot Device page can use an explicit HTTP base URL:
VITE_RUNTIME_HTTP_URL=http://localhost:8787
If VITE_RUNTIME_HTTP_URL is not set, the frontend derives the HTTP base from VITE_RUNTIME_WS_URL.

Runtime/API trust

The runtime calls internal platform API endpoints to verify /voice and /ws connections and to proxy firmware activation:
OPENDOT_RUNTIME_INTERNAL_SECRET=opendot-local-runtime-internal-secret-change-me
PLATFORM_API_INTERNAL_URL=http://localhost:8788/api
OPENDOT_RUNTIME_PUBLIC_HTTP_URL=http://localhost:8787
OPENDOT_RUNTIME_PUBLIC_WS_URL=ws://localhost:8787/voice
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 voice-session tokens and device OTA config point at the right host.

Turn-close defaults

These local defaults make device turns less twitchy:
DEEPGRAM_ENDPOINTING_MS=900
MIN_TRANSCRIPT_CHARS=2
CLOSE_DEVICE_AFTER_TURN=true
CLOSE_DEVICE_AFTER_TURN_DELAY_MS=300
When CLOSE_DEVICE_AFTER_TURN is enabled, the runtime closes the device audio socket shortly after a completed turn so firmware can return to idle or wake-word mode.

TTS defaults

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