-
Notifications
You must be signed in to change notification settings - Fork 0
api reference
All endpoints are served by the Fastify backend on port 8085 (proxied through port 8006 in the default Docker setup). Unless stated otherwise, endpoints that modify data require authentication.
Authentication: Include Authorization: Bearer {token} on every authenticated request. For WebSocket upgrades, use ?token={token} as a query parameter.
POST /api/auth/login
{ "profileName": "Alice", "pin": "1234" }Response 200
{
"token": "uuid",
"expiresAt": 1748563200000,
"profile": { "id": 1, "name": "Alice", "avatarId": 0 }
}Response 401 — wrong PIN or account locked.
POST /api/auth/logout — Auth required
Invalidates the current token. Returns 204 No Content.
GET /api/auth/session — Auth required
{
"session": { "token": "...", "profileId": 1, "expiresAt": 1748563200000 },
"profile": { "id": 1, "name": "Alice" }
}POST /api/auth/recover
{ "name": "Alice", "recoveryPhrase": "blue sky 42", "newPin": "5678" }Returns the updated profile on success, 401 if phrase is wrong.
GET /api/profiles — No auth
Returns all profiles (safe fields only — no PIN data).
GET /api/profiles/:id — No auth
POST /api/profiles — Requires ADMIN
{
"name": "Bob",
"pin": "0000",
"recoveryPhrase": "my phrase",
"recoveryPhraseHint": "favourite colour + number",
"avatarId": 2
}PATCH /api/profiles/:id — Requires ADMIN
Partial update — send only the fields to change.
DELETE /api/profiles/:id — Requires ADMIN
Deletes the profile and invalidates all its sessions. Returns 204.
GET /api/library
| Parameter | Type | Description |
|---|---|---|
q |
string | Full-text search (artist, title, album) |
page |
int | Page (0-indexed, default 0) |
size |
int | Per page (max 200, default 50) |
sort |
string |
artist | artist-desc | title | title-desc | recent | tuning | year | year-desc
|
format |
string |
psarc | sloppak | loose
|
arrangements_has |
string[] | Must include these parts (Lead, Rhythm, Bass, Combo) |
arrangements_lacks |
string[] | Must not include these parts |
stems_has |
string[] | Must include these stems (guitar, bass, drums, vocals) |
stems_lacks |
string[] | Must not include these stems |
has_lyrics |
bool | Only songs with lyrics |
tunings |
string[] | Filter by tuning names |
favorites |
bool | Only favourites for the current profile |
Response
{ "songs": [ SongMeta ], "total": 452, "page": 0, "size": 50 }GET /api/library/artists
Returns songs grouped by first letter then artist name.
GET /api/library/stats
{ "totalSongs": 452, "totalArtists": 87, "letters": { "A": 34, "B": 21 } }GET /api/library/tuning-names
[{ "name": "E Standard", "count": 312 }, ...]POST /api/rescan — Auth required
Starts an incremental scan (skips unchanged files). Returns 202 Accepted.
POST /api/rescan/full — Auth required
Re-processes all files. Returns 202 Accepted.
GET /api/scan-status
{
"status": "scanning",
"stage": "importing",
"current": "Artist - Title.psarc",
"done": 42,
"total": 150
}POST /api/library/cleanup-orphans — Auth required
Removes Song records with no corresponding Track. Returns 204.
GET /api/tracks/:trackId
Returns full Track record.
GET /api/tracks/:trackId/data
Returns TrackData (arrangement list, storage IDs).
GET /api/tracks/:trackId/cover
Returns PNG image. 404 if no cover is stored.
GET /api/tracks/:trackId/audio
Returns OGG audio with full HTTP range support (206 Partial Content). Suitable for <audio> element seeking.
GET /api/tracks/:trackId/stems/:stemIndex/audio
Returns OGG for the specified stem index (0-based).
GET /api/tracks/:trackId/stems
{ "stems": [ StemData ] }POST /api/tracks/:trackId — Requires EDIT_TRACKS
Multipart or JSON body. Editable fields: title, artist, album, year, coverImage (file).
DELETE /api/tracks/:trackId — Requires DELETE_TRACKS
Cascades to TrackData, Stems, StemData, Favorites, Loops, Scores, and MinIO objects.
GET /api/tracks/:trackId/highway?arrangement=N
Returns the full HighwayResponse for arrangement index N. See Player & Highway for the complete shape.
GET /api/covers?count=30
Returns an array of trackId strings for tracks that have cover images. Used for the library grid background.
POST /api/tracks/:trackId/score
{ "profileId": 2, "score": 87 }Stores best score (never decrements), increments play count.
POST /api/scores/batch
{ "profileId": 2, "trackIds": ["abc", "def"] }{
"abc": { "bestScore": 95, "playCount": 4, "lastPlayedAt": "..." },
"def": { "bestScore": 72, "playCount": 1, "lastPlayedAt": "..." }
}GET /api/tracks/:trackId/loops?profileId=N
[ { "id": 1, "name": "Chorus", "startTime": 45.0, "endTime": 78.3 } ]POST /api/tracks/:trackId/loops — Auth required
{ "name": "Verse 2", "start_time": 90.0, "end_time": 120.5 }DELETE /api/loops/:id — Auth required
Returns 204.
POST /api/favorites/toggle — Auth required
{ "trackId": "abc123", "profileId": 2 }{ "favorite": true }GET /api/settings
{
"dlcDir": "/data/dlc",
"psarcPlatform": "pc",
"defaultArrangement": "Lead",
"avOffsetMs": -50,
"demucsServerUrl": "http://demucs:8080"
}All fields are optional; missing keys use built-in defaults.
POST /api/settings — Requires MANAGE_SETTINGS
Partial update — send only the fields to change.
GET /api/settings/export — Auth required
Downloads a ZIP archive containing config.json and any plugin configs.
POST /api/settings/import — Requires MANAGE_SETTINGS
Multipart form upload of a settings ZIP bundle.
POST /api/diagnostics/export — Auth required
Returns a diagnostics.zip containing:
- Server logs
- Hardware info
- Plugin inventory
- WebGL capabilities
- Browser console transcript (submitted by frontend)
GET /api/plugins
[ { "id": "themes", "name": "Themes", "state": "active", "bundled": true } ]GET /api/plugins/:id
POST /api/plugins/:id/enable — Auth required
POST /api/plugins/:id/disable — Auth required
Takes effect on next server restart.
POST /api/plugins/:id/purge — Requires ADMIN
Deletes all PluginData rows for this plugin.
GET /api/plugins/:id/file/*path
No auth. Used by the frontend to load plugin scripts and Vue components.
GET /api/plugins/:id/settings
Returns raw HTML defined in the plugin manifest's settings field.
GET /api/plugins/providers
{
"storage": [ { "name": "local", "pluginId": "built-in", "active": true } ],
"metadata": [ { "name": "musicbrainz", "pluginId": "mb", "active": true } ]
}PUT /api/plugins/providers/:type/active — Requires MANAGE_SETTINGS
{ "name": "s3" }GET /api/plugins/permissions/available
Returns combined list of built-in and plugin-defined permissions.
GET /api/version
{ "version": "1.4.0", "gitSha": "abc1234", "buildDate": "2026-05-01" }GET /api/setup/status
{ "configured": false, "profiles": 0 }POST /api/setup/init
Only available when configured: false. Creates the first admin profile.
{ "name": "Admin", "pin": "1234", "recoveryPhrase": "my phrase" }GET /api/admin/permission-groups — Requires MANAGE_PERMISSIONS
POST /api/admin/permission-groups — Requires MANAGE_PERMISSIONS
{ "name": "Editors", "profileIds": [2, 3], "permissions": ["EDIT_TRACKS"] }PATCH /api/admin/permission-groups/:id — Requires MANAGE_PERMISSIONS
DELETE /api/admin/permission-groups/:id — Requires MANAGE_PERMISSIONS