Appearance
radio
13 endpoints at a glance
| Method | Path | Summary |
|---|---|---|
GET | /radio/discoveries | List Discoveries |
POST | /radio/discoveries/{discovery_id}/dismiss | Dismiss Discovery |
GET | /radio/discoveries/summary | Discoveries Summary |
GET | /radio/moods | List Moods |
GET | /radio/seed-from-text | Radio Seed From Text |
POST | /radio/sessions | Start Session |
DELETE | /radio/sessions/{session_id} | End Session |
GET | /radio/sessions/{session_id} | Get Session |
POST | /radio/sessions/{session_id}/advance | Advance Session |
POST | /radio/sessions/{session_id}/feedback | Post Feedback |
POST | /radio/sessions/{session_id}/resume | Resume Session |
GET | /radio/sessions/active | Get Active Session |
GET | /radio/sessions/recent | List 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
Request Body
application/json
JSON "seed_kind": "string", "seed_id": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
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
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
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
Query Parameters
limit
Type
integer
Default
20Responses
Successful Response
application/json
JSON { "additionalProperties": "string" }
[
]
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
Query Parameters
q*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
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
Query Parameters
limit
Type
integer
Default
0Responses
Successful Response
application/json
JSON { "additionalProperties": "string" }
[
]
Get Session
End Session
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
Path Parameters
session_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
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
Path Parameters
session_id*
Type
Requiredstring
Request Body
application/json
JSON "previous_outcome": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
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
Path Parameters
session_id*
Type
Requiredstring
Request Body
application/json
JSON "canonical_track_id": "string", "signal": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Discoveries Summary
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
Query Parameters
limit
Type
integer
Default
50offset
Type
integer
Default
0Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}