ovos-opendata-server

September 3, 2026 · View on GitHub

A small FastAPI service that turns opt-in telemetry from OVOS voice devices into open, reusable datasets: wake-word audio, speech-to-text utterances, and intent matches. Point your device at it, and every sample it uploads becomes part of a growing, permissively licensed corpus that anyone can use to train and improve voice models — instead of disappearing into a single company's private servers.

Nothing is collected unless you turn it on. See privacy.md for the full policy, and docs/connecting-devices.md for exactly what each upload contains.

A public instance, run by the OVOS community, is available at https://metrics.openvoiceos.pt with a dashboard at https://metrics.openvoiceos.pt/dashboard/stats. You can also run your own — see docs/self-hosting.md.

Dashboard screenshot

See docs/dashboard.md for a full tour of the dashboard.

Quick Start

git clone https://github.com/OpenVoiceOS/ovos-opendata-server
cd ovos-opendata-server
cp .env.example .env        # fill in DATABASE_URL and Postgres credentials
docker compose up --build -d
  • API: http://localhost:8007
  • Dashboard: http://localhost:8007/

Docker image

Tagged releases (v*) are published to ghcr.io/openvoiceos/ovos-opendata-server.

Docker builds the image, starts a Postgres database, and runs pending migrations automatically before the API comes up. For the full walkthrough — including seeding demo data and making your first API call — see docs/getting-started.md.

Configuration

All configuration is via environment variables (.env.example provided):

VariableRequiredDefaultDescription
DATABASE_URLNosqlite:///./ovos_opendata.dbDatabase DSN. Defaults to a local SQLite file for easy local/dev use — production deployments should set this to a PostgreSQL DSN.
MAX_AUDIO_SIZE_MBNo10Audio upload size cap in MB
API_KEYNounsetIf set, intake endpoints also require a matching X-API-Key header
RATE_LIMITNo60/minutePer-IP rate limit applied to intake endpoints
DASHBOARD_CACHE_TTLNo60Seconds the /dashboard/stats aggregation is cached

Settings are loaded via app/config.py (pydantic-settings), which also reads a .env file if present. The app is importable and runnable without any environment variables set. Full reference, including the trust model behind these settings, is in docs/self-hosting.md.

API Overview

MethodPathAuthDescription
POST/intentsUA (+ API key)Submit an intent match
POST/wake_wordUA (+ API key)Submit a wake-word sample
POST/sttUA (+ API key)Submit an STT utterance
GET/intentsPaginated intent list
GET/wake_wordsPaginated wake-word list
GET/utterancesPaginated utterance list
GET/wake_words/{id}/audioStream wake-word audio
GET/utterances/{id}/audioStream utterance audio
GET/intents/exportCSV/JSON export
GET/wake_words/exportCSV/JSON export
GET/utterances/exportCSV/JSON export
GET/dashboard/statsAggregated stats (cached)
GET/Web dashboard
GET/statusHealth check

Auth: intake endpoints require User-Agent: ovos-metrics, and — on instances that set API_KEY — a matching X-API-Key header. See docs/api-reference.md for full details, every parameter, and error codes.

Documentation

GuideFor
docs/index.mdFront door — pick the guide that matches what you're trying to do
docs/getting-started.mdTotal beginners: run the server locally and make your first request
docs/connecting-devices.mdOVOS device owners: mycroft.conf examples, what gets uploaded, how to verify or stop it
docs/self-hosting.mdOperators: production deployment, env vars, TLS, backups, upgrades
docs/api-reference.mdEvery endpoint, parameter, and response code
docs/datasets.mdData consumers: pulling exports, column meanings, building training sets
docs/development.mdContributors: repo layout, running from source, tests, migrations, CI
docs/dashboard.mdHow the built-in web dashboard works
FAQ.mdShort answers to common questions
privacy.mdWhat is collected, why, and your choices

Development

uv pip install -e ".[dev]"
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 uv run pytest test/ -v --cov=app --cov-report=term-missing

See docs/development.md for the full contributor guide: repo layout, adding a field end-to-end, migrations, and CI.

Database migrations

Schema changes are managed with Alembic.

  • Production: run alembic upgrade head before starting the server. The Docker image does this automatically on container start.
  • Development / tests: the app still calls Base.metadata.create_all() on startup for convenience, so a fresh SQLite database works without running migrations first.

To create a new migration after changing app/models.py:

alembic revision --autogenerate -m "describe the change"

Review the generated file before committing it.

This server is one half of the OVOS open-data loop — the other half lives on the device:

  • ovos-core — the assistant runtime; its intent pipeline uploads intent matches (intent_urls) when open_data is enabled in mycroft.conf.
  • ovos-dinkum-listener — the audio pipeline; it uploads wake-word (ww_urls) and STT (stt_urls) samples.
  • ovos-config — reads and validates mycroft.conf, including the open_data block.
  • OpenVoiceOS — the organization behind the whole stack.

License

Apache License 2.0

Acknowledgements

This project was developed by TigreGotico for OpenVoiceOS under the ILENIA project.

This project was funded by the Ministerio para la Transformación Digital y de la Función Pública and Plan de Recuperación, Transformación y Resiliencia - Funded by EU – NextGenerationEU within the framework of the project ILENIA with reference 2022/TL22/00215337