Technical Guide
This page is for advanced users and integrators: how Tune is built, its API and operational details. For everyday settings, see Configuration.
Architecture
- Server: a single program,
tune-server, written in Rust. It indexes the library, decodes audio, drives devices and serves the web interface, the API and the audio streams, all on one port (8888 by default). - Web interface: a Svelte application served by the server (the
web/folder next to the program, orTUNE_WEB_DIR). - Database: SQLite by default, PostgreSQL as an option (see Configuration). Migrations run at startup.
- Decoding: built-in decoders (Symphonia, plus Tune's own WavPack and APE decoders, and libopus). Resampling uses sinc interpolation (rubato). Playback does not go through ffmpeg; a minimal ffmpeg ships with the published builds, only for the converter's AAC encoding.
- Discovery: SSDP for DLNA/UPnP, mDNS for AirPlay and Chromecast, Squeezebox discovery on UDP 3483.
- Tune also presents itself on the network as a UPnP media server (its library is visible to DLNA control apps) and, zone by zone, as a UPnP renderer.
HTTP API
All routes live under /api/v1. A JSON list of routes is served at GET /api/v1/system/api-docs (the API Documentation link in Settings › System › About). Tune does not provide an OpenAPI description.
| Route | Purpose |
|---|---|
GET /api/v1/system/health | Server health: ok or degraded (HTTP 200), error (HTTP 503) |
GET /api/v1/system/version | Server version |
GET /api/v1/system/stats | Statistics (used by the Docker image health check) |
POST /api/v1/system/scan, GET /api/v1/system/scan/status | Start a scan, follow its progress |
GET /api/v1/system/logs?lines=N | Latest log lines (1000 by default) |
GET /api/v1/system/diagnostics/bundle | Diagnostics archive |
GET /api/v1/zones | List of zones |
GET /api/v1/zones/{id}/status | Playback state of a zone |
POST /api/v1/zones/{id}/play, /pause, /resume, /stop, /next, /previous, /seek, /volume | Playback commands |
GET /api/v1/zones/{id}/queue | Queue |
GET /api/v1/search | Search across the library and services |
GET /api/v1/library/albums, /artists, /tracks | Library |
Real-time events (playback, queue, scan…) go through a WebSocket at /ws (or /api/v1/ws). The old /api/scan routes without v1 no longer exist.
Authentication
Authentication is off by default, which leaves the API open to the whole local network. It is turned on through the API (/api/v1/auth/config). Accounts are Tune profiles, passwords are hashed with Argon2, and sessions are 24-hour JWTs. A long-lived API token is issued by POST /api/v1/auth/token. Accepted headers: Authorization: Bearer <token> and Authorization: ApiKey <key>. Even with authentication on, /system/health and /system/version stay public. Tune does not serve HTTPS: put a reverse proxy in front of it if you need it.
Squeezebox / LMS compatibility
- Built-in SlimProto server on port 3483 (TCP and UDP, configurable with
TUNE_SLIMPROTO_PORT), for Squeezelite and Squeezebox players. - LMS-compatible text command port on 9090 (
TUNE_CLI_PORT), which moves to the next free port if 9090 is taken.
Operations
- .deb package: program in
/opt/tune/, data in/var/lib/tune/, configuration in/etc/default/tune-server(kept across upgrades),tune-server.serviceunit running as thetuneuser.apt purgenever removes/var/lib/tune. - Docker:
renesenses/tuneimage (amd64, arm64). It runs as the non-roottuneuser (uid 1000), with/dataand/musicvolumes. It includes neither local audio outputs nor PostgreSQL. On arm64, AirPlay 2 is not available and Tune uses AirPlay 1. - Tune OS: Fedora-based. Program in
/opt/tune,tuneservice, data in/opt/tune/data, port 80 forwarded to 8888, SSH enabled (root login refused). - Logs:
RUST_LOGallows fine-grained filtering per module.
See also
- Configuration: variables, ports, locations
- OAAT: Tune's protocol
- Keyboard Shortcuts