Tune by Mozaiklabs

Référence de l'API

Le serveur Tune expose une API HTTP en JSON et un WebSocket d'événements. L'interface web de Tune s'en sert elle-même. Cette page en présente la structure et quelques exemples réels ; ce n'est pas une liste complète des routes.

Principes

  • Toutes les routes sont sous /api/v1, sur le port du serveur (8888 par défaut). Il n'existe pas d'autre version de l'API.
  • Les requêtes et les réponses sont en JSON. Les réponses sont compressées (gzip) quand le client l'accepte.
  • Les listes se paginent avec limit et offset, et renvoient {"items": […], "total": …, "limit": …, "offset": …}.
  • Une erreur renvoie un code HTTP (400, 401, 403, 404, 409, 500, 503) et, le plus souvent, un objet JSON qui contient un champ error.
  • Une route inconnue sous /api/v1 renvoie 404 avec {"error": "not found", "path": …}.
  • Tune ne publie pas de description OpenAPI. GET /api/v1/system/api-docs renvoie une liste de routes avec leur description, tenue à la main et non exhaustive.

Groupes de routes

PréfixeContenu
/api/v1/systemVersion, santé, statistiques, analyse de la bibliothèque, réglages, sauvegardes, base de données, journaux, diagnostics
/api/v1/libraryAlbums, artistes, pistes, pochettes, genres, historique, playlists et collections intelligentes
/api/v1/zonesZones et groupes, commandes de lecture, file d'attente, réglages audio de la zone
/api/v1/playlistsPlaylists
/api/v1/searchRecherche dans la bibliothèque, les radios et les services
/api/v1/radios, /api/v1/podcastsRadios, favoris radio, podcasts
/api/v1/streamingServices de streaming
/api/v1/devicesAppareils découverts sur le réseau
/api/v1/profilesProfils
/api/v1/eq, /api/v1/crossfeedPréréglages de l'égaliseur et du crossfeed
/api/v1/lyricsParoles
/api/v1/plugins, /api/v1/audio-pluginsExtensions : gestion des extensions WebAssembly et intégrées, extensions audio natives
/api/v1/ext/{nom}Routes ajoutées par une extension intégrée
/api/v1/authAuthentification (voir plus bas)

Hors de /api/v1, le serveur sert aussi les flux audio des appareils (/stream/{id}) et ses services UPnP (/upnp). Ces chemins sont destinés aux appareils, pas aux scripts.

Exemples

État du serveur

curl http://localhost:8888/api/v1/system/health

Renvoie status (ok ou degraded avec le code 200, error avec le code 503), ainsi que version, uptime_seconds, le nombre de pistes et d'albums, et l'état des composants. GET /api/v1/system/version renvoie {"version": …, "engine": "rust"}.

Albums de la bibliothèque

curl "http://localhost:8888/api/v1/library/albums?limit=20&offset=0&sort=added_at&order=desc"

Paramètres : limit (50 par défaut), offset, sort (dont random), order, et des filtres comme format ou quality.

Recherche

curl "http://localhost:8888/api/v1/search?q=miles&limit=10"

La réponse sépare local (artistes, albums et pistes de la bibliothèque, avec leurs totaux), radios et services.

Lecture sur une zone

# Lire un album de la bibliothèque sur la zone 1
curl -X POST http://localhost:8888/api/v1/zones/1/play \
  -H "Content-Type: application/json" -d '{"album_id": 42}'

# Volume à 35 %, ou en décibels
curl -X POST http://localhost:8888/api/v1/zones/1/volume \
  -H "Content-Type: application/json" -d '{"volume": 0.35}'
curl -X POST http://localhost:8888/api/v1/zones/1/volume \
  -H "Content-Type: application/json" -d '{"volume_db": -18}'

# Aller à 1 min 30 s
curl -X POST http://localhost:8888/api/v1/zones/1/seek \
  -H "Content-Type: application/json" -d '{"position_ms": 90000}'

Le corps de /play accepte notamment track_id, track_ids, album_id, playlist_id et start_index. Les autres commandes de la zone sont pause, resume, playpause, stop, next, previous, shuffle et repeat. La file d'attente se lit par GET /api/v1/zones/{id}/queue.

État d'une zone

curl http://localhost:8888/api/v1/zones/1/status

Renvoie notamment state (playing, paused ou stopped), now_playing, position_ms, volume, volume_db, muted, shuffle, repeat, queue_position et queue_length.

WebSocket d'événements

Le WebSocket est sur /ws (ou /api/v1/ws). Il pousse les changements d'état en temps réel : il n'est pas nécessaire d'interroger l'API en boucle.

  • À la connexion, le serveur envoie un instantané : {"type": "snapshot", "data": {"zones": […], "groups": […]}}.
  • Chaque événement a la forme {"type": "<nom>", "data": {…}}. Les événements de lecture portent le zone_id dans data.
  • Un client peut filtrer ce qu'il reçoit : {"subscribe": ["playback.*", "zone.updated"]}. Le serveur confirme par {"type": "subscribed", …}. Par défaut, le client reçoit tout. C'est le seul message que le client envoie : les commandes passent par l'API HTTP.
  • Toutes les 15 secondes, le serveur envoie {"type": "ping"}.
  • Les événements de progression (analyse, enrichissement) sont espacés pour ne pas saturer les clients.

Quelques noms d'événements :

FamilleÉvénements
Lectureplayback.started, playback.paused, playback.resumed, playback.stopped, playback.track_changed, playback.volume, playback.seek
Zones et groupeszone.created, zone.updated, zone.deleted, group.created, group.updated, group.deleted
Bibliothèquelibrary.scan.started, library.scan.progress, library.scan.completed, library.updated
Appareilsdevice.discovered, device.updated, device.lost

Les noms d'événements font partie du contrat avec les clients : Tune les garde stables.

Authentification

Elle est désactivée par défaut : l'API est alors ouverte au réseau local. Une fois activée (POST /api/v1/auth/config) :

  • POST /api/v1/auth/login avec {"username", "password"} renvoie un jeton de session valable 24 heures.
  • POST /api/v1/auth/token (administrateur) crée un jeton d'API de longue durée, pour un script ou une domotique.
  • Le jeton s'envoie dans l'en-tête Authorization: Bearer <jeton>. Une clé d'API s'envoie dans Authorization: ApiKey <clé>.
  • Pour le WebSocket, un client qui ne peut pas poser d'en-tête passe le jeton dans l'adresse : /ws?token=<jeton>.
  • Certaines routes demandent le rôle administrateur et renvoient 403 sinon.
  • /system/health et /system/version restent accessibles sans jeton.
curl -H "Authorization: Bearer <jeton>" http://localhost:8888/api/v1/zones

Voir aussi