Skip to content

API

The API documentation is generated at /docs (Swagger UI) and /openapi.json. Its main parts:

Prefix What
/v1/library/... Libraries (with track, artist, album and genre counts), tracks, artists, albums, genres, search (GET /search?q=&library_id=: the best few of each kind, every library without library_id, and elsewhere, the other libraries with matching music when this one has none; the lists take search with sort=relevance for the rest; GET /libraries/{id}/search?q= still answers the same), track streaming, album artwork, recording a play, the folder browser, and scans (POST /libraries, POST/GET /libraries/{id}/scan)
/v1/library/artists/{id}/image…, /v1/library/albums/{id}/artwork…, …/refresh Pictures by hand: the choices the sources have, choose one, upload one (multipart), back to automatic; look details up again now
/v1/player/... The server's mpv player: state, play, queue (add, POST /queue/move, DELETE /queue/{index}), pause, resume, stop, next, previous, seek, volume, and AirPlay artwork
/v1/smart-playlists/... Smart playlists: what's available for a library (or all), and each one's songs (GET /{key}/tracks; liked is Liked Songs)
/v1/likes Liked songs, yours: GET their ids ({track_ids}, newest first), PUT/DELETE /{track_id} likes or unlikes one, POST {track_ids} likes many (the first the newest: an import), answering {added}
/v1/custom-mixes Custom mixes (saved filters): list a library's, create, rename or change the filters (PATCH), delete; their songs come from GET /v1/smart-playlists/custom-mix/tracks?param={id}
/v1/smart-playlists/ai AI playlists: GET whether they're on and which models can be picked; POST {prompt, library_id, model?} makes one (a preview, not saved)
/v1/playlists/... Playlists and their entries: create, rename, delete, add, remove and move entries; importing from other apps (POST /import/preview, POST /import)
/v1/integrations Getting music through other services: which are on; Lidarr search, an artist's albums, adding albums and artists, and its webhook (POST /lidarr/webhook?token=…)
/v1/me, /v1/profiles Who's asking (GET /me, always answered); profiles: list, pick one at home (POST /profiles/pick), sign out, sign a profile's devices out (POST /profiles/{id}/sign-out-devices), add, change and delete
/v1/library/tracks/{id}/lyrics A song's lyrics: { source, synced: [{ time, text }], plain, instrumental } (source null: none); POST …/lyrics/refresh asks LRCLIB again (admins)
/v1/stats Listening stats: range (30d, year, all), scope (mine, household), tz (the asker's time zone, for times of day); admins can ask for one profile's with profile (its id). GET /recaps lists the years with a recap, GET /recap?year= gives one (404: not enough listening)
/v1/settings The server settings the app can show (GET: sections, values, where each comes from; keys masked) and, with ALLOW_REMOTE_SETTINGS=true, change (PATCH {id: value})
/health, /version, /system-info Status and server information (/version's android_app: where to download the Android app, when the server has it)
/v1/apps/android The Android app built with this release, as an APK (404 when the image has none)
/v1/apps/web-files The web app's files (path, size, sha256) and a digest of them all, for an app to keep a copy of: the iOS app opens it when the server can't be reached
/v1/events Live updates (Server-Sent Events): ready on connecting, then library ({library_id}: its songs or counts changed), scan (a scan's status, as GET /v1/library/libraries/{id}/scan), player (the server's player changed: ask GET /v1/player), notice ({id, text, variant, kind, created_at}: a notification for this person, shown as a toast and added to the bell), likes (this person's liked songs changed: ask GET /v1/likes), and resync (events were lost: ask again). Events say what changed; the app asks the API for what it is. Without them, the app asks every second as before
/v1/notifications The bell: the latest 50 notifications from the last 30 days that were sent to you, newest first, as {items: [{id, text, variant, kind, created_at}], seen, unread} (seen and unread are null with profiles off). POST /v1/notifications/seen with {up_to} marks them read up to that id, and POST /v1/notifications/clear with {up_to} clears yours up to that id
/v1/apps/car What the apps show in a car (Android Auto, CarPlay): GET /browse?id= (the branches, what's under one, the songs in something), GET /tracks?id= ({ start, tracks } to play), GET /search?q= (songs, artists, albums and playlists, best match first; "liked songs" finds Liked Songs)

With profiles off the API has no authentication: run it on a network you trust, or switch profiles on (see Profiles and sign-in).