{"openapi":"3.1.0","info":{"title":"Cassette read API","summary":"Read-only rows of one listener's library, for dashboards.","description":"Send `Authorization: Bearer <token>` with a read-only token from Settings → API tokens. Every list is paginated: follow `nextCursor` with `?cursor=` until it is null.","version":"1"},"paths":{"/api/tomoe/songs":{"get":{"tags":["tomoe"],"summary":"Tomoe Songs","description":"Every song in the library, oldest addition first, with play counts and likes.\n\n`tempoBpm`, `energy`, `danceability` and `mode` are null until the song has\nbeen analysed; `analysed` says which rows have them.","operationId":"tomoe_songs_api_tomoe_songs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Rows per page.","default":1000,"title":"Limit"},"description":"Rows per page."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip.","default":0,"title":"Offset"},"description":"Rows to skip."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The `nextCursor` of the previous page. Overrides `offset`.","title":"Cursor"},"description":"The `nextCursor` of the previous page. Overrides `offset`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TomoeSongPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tomoe/listens":{"get":{"tags":["tomoe"],"summary":"Tomoe Listens","description":"Every listen, oldest first.\n\nA listen is filed twenty seconds into a song (or halfway through a short one),\nso a track skipped straight away is not here. The log starts on the day it was\nadded to the app; listening before that is only in the songs' `playCount`.","operationId":"tomoe_listens_api_tomoe_listens_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Rows per page.","default":1000,"title":"Limit"},"description":"Rows per page."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip.","default":0,"title":"Offset"},"description":"Rows to skip."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The `nextCursor` of the previous page. Overrides `offset`.","title":"Cursor"},"description":"The `nextCursor` of the previous page. Overrides `offset`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TomoeListenPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tomoe/playlists":{"get":{"tags":["tomoe"],"summary":"Tomoe Playlists","description":"Every playlist, oldest first, with its length. \"Liked\" is not one: see `liked` on songs.","operationId":"tomoe_playlists_api_tomoe_playlists_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Rows per page.","default":1000,"title":"Limit"},"description":"Rows per page."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip.","default":0,"title":"Offset"},"description":"Rows to skip."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The `nextCursor` of the previous page. Overrides `offset`.","title":"Cursor"},"description":"The `nextCursor` of the previous page. Overrides `offset`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TomoePlaylistPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tomoe/playlist-tracks":{"get":{"tags":["tomoe"],"summary":"Tomoe Playlist Tracks","description":"Which songs are in which playlist, in playlist order.","operationId":"tomoe_playlist_tracks_api_tomoe_playlist_tracks_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Rows per page.","default":1000,"title":"Limit"},"description":"Rows per page."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip.","default":0,"title":"Offset"},"description":"Rows to skip."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The `nextCursor` of the previous page. Overrides `offset`.","title":"Cursor"},"description":"The `nextCursor` of the previous page. Overrides `offset`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TomoePlaylistTrackPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tomoe/downloads":{"get":{"tags":["tomoe"],"summary":"Tomoe Downloads","description":"Every download this listener asked for, oldest first, including failed ones.","operationId":"tomoe_downloads_api_tomoe_downloads_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Rows per page.","default":1000,"title":"Limit"},"description":"Rows per page."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip.","default":0,"title":"Offset"},"description":"Rows to skip."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The `nextCursor` of the previous page. Overrides `offset`.","title":"Cursor"},"description":"The `nextCursor` of the previous page. Overrides `offset`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TomoeDownloadPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"TomoeDownload":{"properties":{"id":{"type":"string","title":"Id"},"songId":{"type":"string","title":"Songid"},"title":{"type":"string","title":"Title"},"artist":{"type":"string","title":"Artist"},"status":{"type":"string","enum":["pending","downloading","ready","failed"],"title":"Status"},"stage":{"type":"string","title":"Stage"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"startedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Startedat"},"finishedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finishedat"}},"type":"object","required":["id","songId","title","artist","status","stage","createdAt"],"title":"TomoeDownload","description":"One request to fetch a song's audio onto the server."},"TomoeDownloadPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/TomoeDownload"},"type":"array","title":"Data"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor"}},"type":"object","required":["data"],"title":"TomoeDownloadPage"},"TomoeListen":{"properties":{"id":{"type":"integer","title":"Id"},"songId":{"type":"string","title":"Songid"},"playedAt":{"type":"string","format":"date-time","title":"Playedat"},"title":{"type":"string","title":"Title"},"artist":{"type":"string","title":"Artist"},"album":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Album"},"durationSec":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Durationsec"}},"type":"object","required":["id","songId","playedAt","title","artist"],"title":"TomoeListen","description":"One listen: a song played past the point the player counts as listened."},"TomoeListenPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/TomoeListen"},"type":"array","title":"Data"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor"}},"type":"object","required":["data"],"title":"TomoeListenPage"},"TomoePlaylist":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"source":{"type":"string","enum":["manual","dj","youtube","mashup"],"title":"Source"},"trackCount":{"type":"integer","title":"Trackcount"},"durationSec":{"type":"integer","title":"Durationsec"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"updatedAt":{"type":"string","format":"date-time","title":"Updatedat"}},"type":"object","required":["id","name","source","trackCount","durationSec","createdAt","updatedAt"],"title":"TomoePlaylist","description":"One playlist: made by hand, saved from a DJ set, imported, or filled with mashups."},"TomoePlaylistPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/TomoePlaylist"},"type":"array","title":"Data"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor"}},"type":"object","required":["data"],"title":"TomoePlaylistPage"},"TomoePlaylistTrack":{"properties":{"id":{"type":"string","title":"Id"},"playlistId":{"type":"string","title":"Playlistid"},"songId":{"type":"string","title":"Songid"},"position":{"type":"integer","title":"Position"},"addedAt":{"type":"string","format":"date-time","title":"Addedat"}},"type":"object","required":["id","playlistId","songId","position","addedAt"],"title":"TomoePlaylistTrack","description":"One song's place in one playlist."},"TomoePlaylistTrackPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/TomoePlaylistTrack"},"type":"array","title":"Data"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor"}},"type":"object","required":["data"],"title":"TomoePlaylistTrackPage"},"TomoeSong":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"artist":{"type":"string","title":"Artist"},"artistBrowseId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artistbrowseid"},"album":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Album"},"durationSec":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Durationsec"},"status":{"type":"string","enum":["pending","downloading","ready","failed"],"title":"Status"},"addedAt":{"type":"string","format":"date-time","title":"Addedat"},"liked":{"type":"boolean","title":"Liked"},"likedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Likedat"},"playCount":{"type":"integer","title":"Playcount"},"firstPlayedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Firstplayedat"},"lastPlayedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Lastplayedat"},"loudnessDb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Loudnessdb"},"lyricsSource":{"anyOf":[{"type":"string","enum":["lrclib","ytmusic","whisper","mashup","instrumental","none"]},{"type":"null"}],"title":"Lyricssource"},"hasSyncedLyrics":{"type":"boolean","title":"Hassyncedlyrics"},"analysed":{"type":"boolean","title":"Analysed"},"tempoBpm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tempobpm"},"energy":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Energy"},"danceability":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Danceability"},"mode":{"anyOf":[{"type":"string","enum":["major","minor"]},{"type":"null"}],"title":"Mode"}},"type":"object","required":["id","title","artist","status","addedAt","liked","playCount","hasSyncedLyrics","analysed"],"title":"TomoeSong","description":"One song in the listener's library."},"TomoeSongPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/TomoeSong"},"type":"array","title":"Data"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor"}},"type":"object","required":["data"],"title":"TomoeSongPage"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}