Skip to content

spotify ​

9 endpoints at a glance
MethodPathSummary
GET/spotify/auth/callbackAuth Callback
DELETE/spotify/meUnlink Spotify
GET/spotify/meGet My Spotify Link
POST/spotify/me/auth/startStart Auth
POST/spotify/me/import-favoritesImport Liked Songs To Favorites
GET/spotify/me/playlistsList My Playlists
GET/spotify/me/playlists/{spotify_playlist_id}Get My Playlist
GET/spotify/me/playlists/{spotify_playlist_id}/plex-coverageGet Playlist Plex Coverage
POST/spotify/me/syncSync My Library

spotify​


Get My Spotify Link​

GET
/spotify/me

Return the caller's Spotify identity, or {link: null} if
not linked.

Mirrors the shape of GET /plex/me so the SPA can use the same
"is this service connected?" pattern.

Fetches fresh from Mongo rather than trusting the dependency dict
— Spotify access tokens rotate (refresh flow writes back to prefs
on every refresh), so a request-scoped snapshot can lag behind
reality. The cost is one extra single-doc read per call which is
negligible for a per-user endpoint.

Header Parameters

authorization
x-api-key

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}
Headers

Unlink Spotify​

DELETE
/spotify/me

Drop all Spotify creds + identity from the caller's prefs.

Doesn't revoke on Spotify's side — that's only possible by the
user visiting accounts.spotify.com/apps. The refresh token becomes
inert as soon as they do; until then we just stop using it.

Header Parameters

authorization
x-api-key

Successful Response

application/json
JSON
{
  
"additionalProperties": true
}
Headers

Start Auth​

POST
/spotify/me/auth/start

Begin the OAuth flow — returns the URL the SPA should redirect to.

The SPA does the actual navigation; we don't 302 directly because
that would lose the user's session cookie context (Spotify needs
to redirect back to our origin, where the same cookie is in
play).

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers

Samples​


Auth Callback​

GET
/spotify/auth/callback

OAuth callback — Spotify redirects here after the user consents.

Three possible shapes:

  • ?code=...&state=... — success path; exchange and persist.
  • ?error=... — user clicked Cancel on Spotify's consent
    screen, or Spotify rejected the request. Redirect with the
    reason so the Settings view can show a meaningful message.
  • Missing everything — someone hit the URL directly. 400.

On any failure we redirect to the SPA's Settings page with a
spotify=error&reason=... query so the user sees the failure
on the same page they started the flow.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

code
state
error

Responses​

Successful Response

application/json
JSON
[
]

Playground​

Headers
Variables
Key
Value

Samples​


Sync My Library​

POST
/spotify/me/sync

Kick off a Spotify library + playlists + recently-played sync.

Fire-and-forget: returns a task_id immediately so the SPA's
HTTP client doesn't time out while the sync walks pages of saved
tracks / albums / followed-artists / playlists. The SPA polls
GET /admin/task-history/{task_id} (or uses the
useBackgroundTask composable) to surface progress + the
final summary.

Sync time is roughly linear in (saved-tracks + Σ playlist tracks),
plus one /me/player/recently-played call. A typical user with ~1k
saved tracks + 30 playlists lands in 30–60 seconds — well past
the SPA's 15s axios timeout, hence the background-task shape.

412 if the user hasn't linked Spotify.

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers

Samples​


Get Playlist Plex Coverage​

GET
/spotify/me/playlists/{spotify_playlist_id}/plex-coverage

Report how many tracks in a Spotify playlist resolve to Plex.

Used by the SPA's "preview before sync" UI: before turning a
Spotify playlist into a Plex playlist, the user sees X of Y tracks have a Plex match; Z are Spotify-only. Doesn't touch
Plex — everything resolves from local refs.

The special id __liked_songs__ reports against the user's
Spotify Liked Songs (which lives in spotify_saved_tracks,
not spotify_playlists).

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

spotify_playlist_id*
Type
string
Required

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Variables
Key
Value

Samples​


List My Playlists​

GET
/spotify/me/playlists

List the caller's Spotify playlists from the local mirror.

owned_only=True (default) hides playlists the user follows
but didn't create — matches Settings's default. Pass
owned_only=false to include followed playlists.

Reads from spotify_playlists only; doesn't call Spotify. Run
POST /spotify/me/sync first to populate the mirror.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

owned_only
Type
boolean
Default
true

Responses​

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground​

Headers
Variables
Key
Value

Samples​


Get My Playlist​

GET
/spotify/me/playlists/{spotify_playlist_id}

Get a single Spotify playlist with its embedded items.

Items carry canonical_track_id when our sync resolved them
against an existing canonical. Resolution happens at sync time
— calling this endpoint never triggers a Spotify network call.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

spotify_playlist_id*
Type
string
Required

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Variables
Key
Value

Samples​


Import Liked Songs To Favorites​

POST
/spotify/me/import-favorites

One-shot: import the caller's Spotify Liked Songs into
canonical favorites.

Walks spotify_saved_tracks and upserts each row with a
resolved canonical onto media_favorites. Idempotent —
already-favorited tracks count separately in the summary so the
SPA can render "imported 12 new; 35 already favorited".

Prerequisite: a Spotify sync must have run already (so saved
tracks exist in the mirror with canonical_id stamped). If the
user has just linked Spotify but hasn't synced yet, they get
candidates: 0 and nothing happens — the SPA should suggest
"click Sync first".

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers

Samples​


Media — Blue Sapphire Software.