Skip to content

radio ​

13 endpoints at a glance
MethodPathSummary
GET/radio/discoveriesList Discoveries
POST/radio/discoveries/{discovery_id}/dismissDismiss Discovery
GET/radio/discoveries/summaryDiscoveries Summary
GET/radio/moodsList Moods
GET/radio/seed-from-textRadio Seed From Text
POST/radio/sessionsStart Session
DELETE/radio/sessions/{session_id}End Session
GET/radio/sessions/{session_id}Get Session
POST/radio/sessions/{session_id}/advanceAdvance Session
POST/radio/sessions/{session_id}/feedbackPost Feedback
POST/radio/sessions/{session_id}/resumeResume Session
GET/radio/sessions/activeGet Active Session
GET/radio/sessions/recentList Recent Sessions

radio​


Start Session​

POST
/radio/sessions

Start a radio session seeded by a canonical artist or album.

Picks the first track immediately so the SPA can press play
without a second round-trip. Refuses with 422 when the seed's
candidate pool is too thin to make the radio worthwhile
(cold-start: small library, no scrobble history yet, etc.).

Parameters​

Header Parameters

authorization
x-api-key

Request Body​

application/json
JSON
{
  
"seed_kind": "string",
  
"seed_id": "string"
}

Responses​

Successful Response

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

Playground​

Headers
Body

Samples​


Get Active Session​

GET
/radio/sessions/active

Current user's active session (or null when none).

Powers app-boot session restoration — the SPA hits this after
login to decide whether to drop the user back into a radio they
were already running.

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

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

Playground​

Headers

Samples​


List Recent Sessions​

GET
/radio/sessions/recent

The user's recent radio sessions (active + ended), newest first.

Powers the "Recent stations" list on the idle Radio page: each row
can be resumed (continue where it left off) or restarted (a
fresh station from the same seed). Declared before
/sessions/{session_id} so the literal path wins the match.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

limit
Type
integer
Default
20

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


Radio Seed From Text​

GET
/radio/seed-from-text

Interpret a plain-English listening request into a radio seed.

e.g. "something mellow for a rainy Sunday" → {seed_kind: "mood", seed_id: "melancholy"}, ready to POST to /radio/sessions.

Grounded: mood/genre come from this library's actual values and
artist names are resolved against our own canonicals — the model picks
intent, never ids. The engine still does all pool building + scoring.

Always 200 with a state (ok / not_configured / failed)
so the SPA falls back to the manual seed pickers.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

q*
Type
string
Required

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


List Moods​

GET
/radio/moods

Distinct moods present in the playable library, with track counts.

Powers the mood-mix pickers (the idle Radio page + the /moods
browse page). Scoped to Plex-playable, non-tombstoned tracks so every
mood listed actually yields a startable pool — same source filter the
engine's _pool_for_mood_seed applies. Sorted by count desc (mood
name as the tie-break). limit 0 = all.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

limit
Type
integer
Default
0

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


Get Session​

GET
/radio/sessions/{session_id}

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

session_id*
Type
string
Required

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


End Session​

DELETE
/radio/sessions/{session_id}

Discard / end a session. Idempotent — ending an already-ended
session is not an error.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

session_id*
Type
string
Required

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


Resume Session​

POST
/radio/sessions/{session_id}/resume

Re-open a saved session and continue from where it left off.

Closes any currently-open session (one active per user), clears this
session's ended_at so it becomes the active one, and returns it
shaped exactly like the active GET. The session's cached candidate
pool is reused, so advancing continues the same station rather than
re-running the engine (use a fresh POST /sessions with the same
seed for that — the SPA's "Restart" action).

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

session_id*
Type
string
Required

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


Advance Session​

POST
/radio/sessions/{session_id}/advance

Pick the next track. The SPA calls this on track-end / user-skip.

Logs the previous track's outcome both onto the session (for
sequencing) and into radio_feedback (for cross-session
learning) when the outcome is a negative signal.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

session_id*
Type
string
Required

Request Body​

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

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value
Body

Samples​


Post Feedback​

POST
/radio/sessions/{session_id}/feedback

Log a thumb up/down for a track — a radio taste signal only.

Thumb-up / thumb-down feed the engine's scoring (loved bonus /
penalty) and persist in radio_feedback for cross-session bias.
They do NOT touch the favorites collection: favoriting a track is a
deliberate, separate action (POST /me/favorites/tracks) that the
player exposes as its own button and which has no effect on radio.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

session_id*
Type
string
Required

Request Body​

application/json
JSON
{
  
"canonical_track_id": "string",
  
"signal": "string"
}

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value
Body

Samples​


Discoveries Summary​

GET
/radio/discoveries/summary

Lightweight count for the radio-page "N recommendations" chip.

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

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

Playground​

Headers

Samples​


List Discoveries​

GET
/radio/discoveries

The user's accumulated "couldn't play these" recommendations.

Ranked by how often the radio wanted to play them (then similarity).
Rows that have since entered the library are flagged in_library
(and linked to) rather than dropped, so an add is visibly reflected.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

limit
Type
integer
Default
50
offset
Type
integer
Default
0

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


Dismiss Discovery​

POST
/radio/discoveries/{discovery_id}/dismiss

Hide one discovery. Ownership-guarded; idempotent.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

discovery_id*
Type
string
Required

Responses​

Successful Response

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

Playground​

Headers
Variables
Key
Value

Samples​


Media — Blue Sapphire Software.