Tune by Mozaiklabs

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, or TUNE_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.

RoutePurpose
GET /api/v1/system/healthServer health: ok or degraded (HTTP 200), error (HTTP 503)
GET /api/v1/system/versionServer version
GET /api/v1/system/statsStatistics (used by the Docker image health check)
POST /api/v1/system/scan, GET /api/v1/system/scan/statusStart a scan, follow its progress
GET /api/v1/system/logs?lines=NLatest log lines (1000 by default)
GET /api/v1/system/diagnostics/bundleDiagnostics archive
GET /api/v1/zonesList of zones
GET /api/v1/zones/{id}/statusPlayback state of a zone
POST /api/v1/zones/{id}/play, /pause, /resume, /stop, /next, /previous, /seek, /volumePlayback commands
GET /api/v1/zones/{id}/queueQueue
GET /api/v1/searchSearch across the library and services
GET /api/v1/library/albums, /artists, /tracksLibrary

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.service unit running as the tune user. apt purge never removes /var/lib/tune.
  • Docker: renesenses/tune image (amd64, arm64). It runs as the non-root tune user (uid 1000), with /data and /music volumes. 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, tune service, data in /opt/tune/data, port 80 forwarded to 8888, SSH enabled (root login refused).
  • Logs: RUST_LOG allows fine-grained filtering per module.

See also