Skip to content

now_playing

now playing API endpoints for external scrobbler integrations.

exposes real-time playback state for services like teal.fm/Piper.

note: these endpoints are exempt from rate limiting because they’re already throttled client-side (10-second intervals, 1-second debounce).

update_now_playing(update: NowPlayingUpdate, session: Session = Depends(require_auth)) -> StatusResponse

update now playing state (authenticated).

called by frontend to report current playback state. state expires after 5 minutes of no updates.

clear_now_playing(session: Session = Depends(require_auth)) -> StatusResponse

clear now playing state (authenticated).

called when user explicitly stops playback.

get_now_playing_by_handle(handle: str, response: Response, db: Annotated[AsyncSession, Depends(get_db)]) -> NowPlayingResponse

get now playing state by handle (public).

this is the endpoint Piper will poll to fetch current playback state. returns 204 No Content if nothing is playing.

response format matches what Piper expects from music sources:

  • track_name: track title
  • artist_name: artist display name
  • album_name: album name (optional)
  • duration_ms: total duration in milliseconds
  • progress_ms: current playback position in milliseconds
  • is_playing: whether actively playing
  • track_url: link to track on plyr.fm
  • service_base_url: “plyr.fm” for Piper to identify the source
get_now_playing_by_did(did: str, response: Response) -> NowPlayingResponse

get now playing state by DID (public).

alternative to by-handle for clients that already have the DID. returns 204 No Content if nothing is playing.

request to update now playing state.

now playing state response.

designed to be compatible with teal.fm/Piper expectations. matches the fields Piper expects from music sources like Spotify.