One self-hosted platform to build, test, and run voice AI on your devices — from day-one simulation to a production fleet.
iotta is the server that turns an embedded device into a voice assistant — it receives audio from a device, runs it through a speech-recognition → language-model → speech-synthesis pipeline, dispatches tool calls, and streams synthesized speech back. It is also the development environment the same teams use to build that assistant: the same server runs from pre-hardware simulation, through prototype bring-up, to the production fleet. There is no separate test tool, and no re-integration between stages.
iotta contains no product-specific knowledge — any voice AI product can be built on it without modifying the platform.
See docs/product.md for the full case, the feature catalog, and a
side-by-side comparison with xiaozhi.
Every administrative operation runs in the browser, served by the platform itself — no separate install. (Screenshots show the built-in empty-state demo content.)
![]() |
![]() |
|---|---|
| Devices & fleet liveness | Tool & prompt registry |
![]() |
![]() |
|---|---|
| Firmware rollout | Session traces |
cp config.example.yaml config.yaml # edit paths/secrets as needed
cp .env.example .env # set OPENAI_API_KEY (and tokens)
docker compose up
The operator UI is then served at http://localhost:8000/ (redirects to /ui).
# System dependencies
apt install libopus-dev libportaudio2 # Linux
brew install opus portaudio # macOS
# Server
cd server
pip install uv
uv pip install -e ".[dev,audio]"
cp config.example.yaml config.yaml # fill in your API keys
IOTTA_CONFIG=config.yaml iotta # serves the API + UI on :8000
# Client (software device simulator)
cd ../client
uv pip install -e .
iotta-client --server ws://localhost:8000/session
The server package installs operator CLIs alongside the server:
| Command | Purpose |
|---|---|
iotta |
Run the session server + operator UI |
iotta-registry |
Manage tool/prompt versions and promotion |
iotta-eval |
Run scored eval suites |
iotta-devices |
Devices, agents, firmware, OTA rollout/rollback |
iotta-doctor |
Preflight: stores, disk, auth posture, provider keys |
iotta-backup / iotta-restore |
Consistent snapshot ↔ restore (one .tar.gz) |
| Variable | Purpose |
|---|---|
OPENAI_API_KEY |
ASR (Whisper), LLM, TTS via OpenAI (reference provider) |
IOTTA_CONFIG |
Path to config YAML (default: config.yaml) |
IOTTA_ADMIN_TOKEN |
Bearer token gating the /admin operator API |
IOTTA_SESSION_TOKEN |
Shared device session token (per-device tokens also supported) |
server/ # FastAPI session server + operator UI
src/iotta/ # main package
src/iotta/web/ # operator UI (static ES modules, no build step)
tests/ # pytest suite (no external deps required)
client/ # software device client (mic → Opus → speaker)
deploy/ # reverse-proxy examples (Caddy, nginx)
docs/ # design, product, protocol, subsystem references
cd server
PYTHONPATH=src python -m pytest tests/ -v
Tests run without system audio libraries (opuslib is mocked) and require no network.
| Doc | Purpose |
|---|---|
docs/product.md |
What iotta is, for whom, and how it compares |
docs/design.md |
Engineering vision and design principles |
docs/protocol-spec.md |
Wire protocol — normative message reference |
docs/protocol-design.md |
Protocol rationale + firmware port guide (from xiaozhi) |
docs/commercialization.md |
Open-core model, editions, device-cap design |
CONTRIBUTING.md |
How to contribute (incl. the changelog policy) |
CHANGELOG.md |
Release & change history |
iotta is dual-licensed open-core:
The free Community edition is the full development platform, capped at a small number of
active devices for demos, solo use, and evaluation. See
docs/commercialization.md. The core always runs with no
required cloud dependency.