Files
MusicPlayer/server/openapi.json
T
Sansan 240c331ab2
Build / test (push) Successful in 53s
Build / build (push) Successful in 1m13s
Cache character pictures and songs on disk
Character pictures are kept in characters/ next to the settings, with an
index.json of when the server last changed each one and when it was
downloaded. Only new or changed pictures are downloaded, using the server's new
/character/details. Older servers fall back to the name list, and pictures are
downloaded again after 7 days.

Downloaded songs are written to songs/ and only their paths are kept in memory.
The folder is emptied when the game starts and when the playlist resets.
2026-10-07 21:57:27 +02:00

3694 lines
97 KiB
JSON

{
"components": {
"schemas": {
"APIError": {
"additionalProperties": false,
"properties": {
"error": {
"description": "What went wrong",
"examples": [
"Not Found"
],
"type": "string"
}
},
"required": [
"error"
],
"type": "object"
},
"CharacterDetails": {
"additionalProperties": false,
"properties": {
"modified": {
"description": "When the image was last changed, in Unix seconds",
"format": "int64",
"type": "integer"
},
"name": {
"description": "File name of the character image",
"type": "string"
}
},
"required": [
"name",
"modified"
],
"type": "object"
},
"ProgressResponse": {
"additionalProperties": false,
"properties": {
"progress": {
"type": "string"
},
"time_spent": {
"type": "string"
}
},
"required": [
"progress",
"time_spent"
],
"type": "object"
},
"Song": {
"additionalProperties": false,
"properties": {
"file_name": {
"type": "string"
},
"name": {
"type": "string"
},
"soundtrack_name": {
"type": "string"
},
"soundtrack_uuid": {
"type": "string"
},
"times_played": {
"format": "int32",
"type": "integer"
},
"uuid": {
"type": "string"
}
},
"required": [
"uuid",
"name",
"times_played",
"soundtrack_uuid",
"soundtrack_name"
],
"type": "object"
},
"SongInfo": {
"additionalProperties": false,
"properties": {
"CurrentlyPlaying": {
"type": "boolean"
},
"Song": {
"type": "string"
},
"SongNo": {
"format": "int64",
"type": "integer"
},
"SongPlayed": {
"format": "int32",
"type": "integer"
},
"SongUuid": {
"type": "string"
},
"Soundtrack": {
"type": "string"
},
"SoundtrackPlayed": {
"format": "int32",
"type": "integer"
},
"SoundtrackUuid": {
"type": "string"
}
},
"required": [
"SoundtrackUuid",
"Soundtrack",
"SoundtrackPlayed",
"SongUuid",
"Song",
"SongPlayed",
"CurrentlyPlaying",
"SongNo"
],
"type": "object"
},
"SongInfoForStats": {
"additionalProperties": false,
"properties": {
"file_name": {
"type": "string"
},
"path": {
"type": "string"
},
"song_name": {
"type": "string"
},
"song_uuid": {
"type": "string"
},
"soundtrack_id": {
"format": "int32",
"type": "integer"
},
"soundtrack_name": {
"type": "string"
},
"soundtrack_uuid": {
"type": "string"
},
"times_played": {
"format": "int32",
"type": "integer"
}
},
"required": [
"soundtrack_id",
"soundtrack_uuid",
"song_uuid",
"soundtrack_name",
"song_name",
"path",
"times_played"
],
"type": "object"
},
"Soundtrack": {
"additionalProperties": false,
"properties": {
"added": {
"format": "date-time",
"type": "string"
},
"last_played": {
"format": "date-time",
"type": "string"
},
"name": {
"type": "string"
},
"times_played": {
"format": "int32",
"type": "integer"
},
"uuid": {
"type": "string"
}
},
"required": [
"uuid",
"name",
"times_played",
"added"
],
"type": "object"
},
"SoundtrackWithSongList": {
"additionalProperties": false,
"properties": {
"added": {
"format": "date-time",
"type": "string"
},
"last_played": {
"format": "date-time",
"type": "string"
},
"name": {
"type": "string"
},
"songs": {
"items": {
"$ref": "#/components/schemas/Song"
},
"type": "array"
},
"times_played": {
"format": "int32",
"type": "integer"
},
"uuid": {
"type": "string"
}
},
"required": [
"songs",
"uuid",
"name",
"times_played",
"added"
],
"type": "object"
},
"SoundtrackWithSongs": {
"additionalProperties": false,
"properties": {
"songs": {
"items": {
"$ref": "#/components/schemas/SongInfoForStats"
},
"type": "array"
},
"soundtrack_id": {
"format": "int32",
"type": "integer"
},
"soundtrack_last_played": {
"format": "date-time",
"type": "string"
},
"soundtrack_name": {
"type": "string"
},
"soundtrack_played": {
"format": "int32",
"type": "integer"
},
"soundtrack_uuid": {
"type": "string"
}
},
"required": [
"soundtrack_id",
"soundtrack_uuid",
"soundtrack_name",
"soundtrack_played",
"songs"
],
"type": "object"
},
"StatisticsSummary": {
"additionalProperties": false,
"properties": {
"avg_soundtrack_plays": {
"format": "double",
"type": "number"
},
"max_soundtrack_plays": {
"format": "int64",
"type": "integer"
},
"min_soundtrack_plays": {
"format": "int64",
"type": "integer"
},
"never_played_soundtracks": {
"format": "int64",
"type": "integer"
},
"played_soundtracks": {
"format": "int64",
"type": "integer"
},
"total_soundtrack_plays": {
"format": "int64",
"type": "integer"
},
"total_soundtracks": {
"format": "int64",
"type": "integer"
}
},
"required": [
"total_soundtracks",
"played_soundtracks",
"never_played_soundtracks",
"total_soundtrack_plays",
"avg_soundtrack_plays",
"max_soundtrack_plays",
"min_soundtrack_plays"
],
"type": "object"
},
"StatusMessage": {
"additionalProperties": false,
"properties": {
"status": {
"type": "string"
}
},
"required": [
"status"
],
"type": "object"
},
"SyncResponse": {
"additionalProperties": false,
"properties": {
"catched_errors": {
"items": {
"type": "string"
},
"type": "array"
},
"soundtracks_added": {
"items": {
"type": "string"
},
"type": "array"
},
"soundtracks_changed_content": {
"items": {
"type": "string"
},
"type": "array"
},
"soundtracks_changed_title": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"soundtracks_re_added": {
"items": {
"type": "string"
},
"type": "array"
},
"soundtracks_removed": {
"items": {
"type": "string"
},
"type": "array"
},
"total_time": {
"type": "string"
}
},
"required": [
"soundtracks_added",
"soundtracks_re_added",
"soundtracks_changed_title",
"soundtracks_changed_content",
"soundtracks_removed",
"catched_errors",
"total_time"
],
"type": "object"
},
"TokenRequest": {
"additionalProperties": false,
"properties": {
"client_type": {
"default": "web",
"description": "Kind of client, for example web, godot or api",
"type": "string"
},
"password": {
"description": "API password, required when the server has one configured",
"type": "string"
}
},
"type": "object"
},
"TokenResponse": {
"additionalProperties": false,
"properties": {
"client_type": {
"type": "string"
},
"expires_at": {
"format": "date-time",
"type": "string"
},
"token": {
"description": "Send as Authorization: Bearer <token>",
"type": "string"
}
},
"required": [
"token",
"expires_at",
"client_type"
],
"type": "object"
},
"VersionData": {
"additionalProperties": false,
"properties": {
"changelog": {
"examples": [
[
"Initial release",
"Bug fixes"
]
],
"items": {
"type": "string"
},
"type": "array"
},
"version": {
"examples": [
"1.0.0"
],
"type": "string"
}
},
"required": [
"version",
"changelog"
],
"type": "object"
}
},
"securitySchemes": {
"bearer": {
"description": "Token from POST /api/v1/token",
"scheme": "bearer",
"type": "http"
}
}
},
"info": {
"description": "API for the MusicServer application.\n\nGet a token with `POST /api/v1/token` and send it as `Authorization: Bearer <token>`.\n\nEvery client has its own play queue. The music endpoints return its ID in the `X-Queue-Id` header; send it back in the same header to keep using that queue. Without it, or when the queue has ended (after a reset or a sync), a new queue is started.",
"title": "MusicServer API",
"version": "5.0.0"
},
"openapi": "3.1.0",
"paths": {
"/api/v1/character": {
"get": {
"description": "Returns a character image.",
"operationId": "get-character",
"parameters": [
{
"description": "File name of the character image, from the character list",
"explode": false,
"in": "query",
"name": "name",
"required": true,
"schema": {
"description": "File name of the character image, from the character list",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"image/jpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
},
"image/png": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The image"
},
"206": {
"content": {
"image/jpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
},
"image/png": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Bad Request"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Character image",
"tags": [
"characters"
]
}
},
"/api/v1/character/details": {
"get": {
"description": "Returns every character image with the time it was last changed, so clients can cache images and download only the changed ones.",
"operationId": "list-character-details",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/CharacterDetails"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "List characters with change times",
"tags": [
"characters"
]
}
},
"/api/v1/character/list": {
"get": {
"description": "Returns the file names of all character images.",
"operationId": "list-characters",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "List characters",
"tags": [
"characters"
]
}
},
"/api/v1/download": {
"get": {
"description": "Returns the name of the latest MusicPlayer release.",
"operationId": "get-latest-client-version",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
},
"502": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Bad Gateway"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Latest client version",
"tags": [
"download"
]
}
},
"/api/v1/download/linux": {
"get": {
"description": "Redirects to the download URL of the latest MusicPlayer release for Linux.",
"operationId": "download-client-linux",
"responses": {
"302": {
"description": "Found",
"headers": {
"Location": {
"schema": {
"description": "Download URL of the asset",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
},
"502": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Bad Gateway"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Download the latest client for Linux",
"tags": [
"download"
]
}
},
"/api/v1/download/list": {
"get": {
"description": "Returns the file names of the latest MusicPlayer release.",
"operationId": "list-client-assets",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
},
"502": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Bad Gateway"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Latest client assets",
"tags": [
"download"
]
}
},
"/api/v1/download/windows": {
"get": {
"description": "Redirects to the download URL of the latest MusicPlayer release for Windows.",
"operationId": "download-client-windows",
"responses": {
"302": {
"description": "Found",
"headers": {
"Location": {
"schema": {
"description": "Download URL of the asset",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
},
"502": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Bad Gateway"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Download the latest client for Windows",
"tags": [
"download"
]
}
},
"/api/v1/health": {
"get": {
"description": "Returns {\"status\": \"up\"} when the server and database work, otherwise status \"down\" and an error.",
"operationId": "get-health",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
}
},
"description": "OK"
},
"default": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Error"
}
},
"summary": "Health check",
"tags": [
"server"
]
}
},
"/api/v1/music": {
"get": {
"description": "Jumps to the song at the given queue position (clamped to the queue) and returns it.",
"operationId": "get-queue-song",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
},
{
"description": "Position of the song in the queue (SongNo)",
"explode": false,
"in": "query",
"name": "song",
"required": true,
"schema": {
"description": "Position of the song in the queue (SongNo)",
"format": "int64",
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Play a song from the queue",
"tags": [
"music"
]
}
},
"/api/v1/music/addPlayed": {
"get": {
"description": "Increments the play counters of the current song and its soundtrack.",
"operationId": "mark-current-played",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Mark the current song as played",
"tags": [
"music"
]
}
},
"/api/v1/music/addQue": {
"get": {
"description": "Adds the song returned by the last random song request to the end of the queue.",
"operationId": "add-latest-to-queue",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Add the last random song to the queue",
"tags": [
"music"
]
}
},
"/api/v1/music/all": {
"get": {
"description": "Returns the names of all soundtracks in random order.",
"operationId": "get-soundtrack-names-random",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Soundtrack names, random order",
"tags": [
"music"
]
}
},
"/api/v1/music/all/order": {
"get": {
"description": "Returns the names of all soundtracks in alphabetical order.",
"operationId": "get-soundtrack-names",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Soundtrack names, sorted",
"tags": [
"music"
]
}
},
"/api/v1/music/all/random": {
"get": {
"description": "Same as /music/all.",
"operationId": "get-soundtrack-names-random-alias",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"type": "string"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Soundtrack names, random order",
"tags": [
"music"
]
}
},
"/api/v1/music/info": {
"get": {
"description": "Returns the current song in the queue.",
"operationId": "get-song-info",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SongInfo"
}
}
},
"description": "OK",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Current song",
"tags": [
"music"
]
}
},
"/api/v1/music/list": {
"get": {
"description": "Returns all songs in the queue.",
"operationId": "get-played-songs",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SongInfo"
},
"type": "array"
}
}
},
"description": "OK",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Queue",
"tags": [
"music"
]
}
},
"/api/v1/music/next": {
"get": {
"description": "Moves to the next song in the queue and returns it. Stays on the last song at the end.",
"operationId": "get-next-song",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Next song in the queue",
"tags": [
"music"
]
}
},
"/api/v1/music/played": {
"put": {
"description": "Increments the play counters of the song at the given queue position. Positions outside the queue are ignored.",
"operationId": "mark-song-played",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
},
{
"description": "Position of the song in the queue (SongNo)",
"explode": false,
"in": "query",
"name": "song",
"required": true,
"schema": {
"description": "Position of the song in the queue (SongNo)",
"format": "int64",
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "OK",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Mark a queued song as played",
"tags": [
"music"
]
}
},
"/api/v1/music/previous": {
"get": {
"description": "Moves to the previous song in the queue and returns it. Stays on the first song at the start.",
"operationId": "get-previous-song",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Previous song in the queue",
"tags": [
"music"
]
}
},
"/api/v1/music/rand": {
"get": {
"description": "Picks a random song from a random soundtrack. Add it to the queue with /music/addQue.",
"operationId": "get-random-song",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Random song",
"tags": [
"music"
]
}
},
"/api/v1/music/rand/classic": {
"get": {
"description": "Picks a random song where every song has the same chance, regardless of soundtrack.",
"operationId": "get-random-song-classic",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Random song, every song equal",
"tags": [
"music"
]
}
},
"/api/v1/music/rand/low": {
"get": {
"description": "Picks a random song, favouring soundtracks that have been played less than average.",
"operationId": "get-random-song-low-chance",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request",
"headers": {
"X-Queue-Id": {
"description": "ID of the client's play queue. Send it with the following requests.",
"schema": {
"format": "uuid",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Random song, favouring rarely played",
"tags": [
"music"
]
}
},
"/api/v1/music/reset": {
"get": {
"description": "Ends the queue, starts a new one and reloads the soundtrack list. The new queue's ID is returned in the X-Queue-Id header; send it with the following requests.",
"operationId": "reset-queue",
"parameters": [
{
"description": "ID of the client's play queue, from an earlier response. Omit it to start a new queue.",
"in": "header",
"name": "X-Queue-Id",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"headers": {
"X-Queue-Id": {
"schema": {
"description": "ID of the new queue",
"type": "string"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Reset the queue",
"tags": [
"music"
]
}
},
"/api/v1/music/soundTest": {
"get": {
"description": "Returns a random song for checking the volume.",
"operationId": "get-sound-test-song",
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)"
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Sound check song",
"tags": [
"music"
]
}
},
"/api/v1/songs/{uuid}": {
"get": {
"description": "Returns information about a song.",
"operationId": "get-song",
"parameters": [
{
"description": "UUID of the soundtrack or song",
"in": "path",
"name": "uuid",
"required": true,
"schema": {
"description": "UUID of the soundtrack or song",
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Song"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Get song",
"tags": [
"library"
]
}
},
"/api/v1/songs/{uuid}/file": {
"get": {
"description": "Returns the audio file of a song.",
"operationId": "get-song-file",
"parameters": [
{
"description": "UUID of the soundtrack or song",
"in": "path",
"name": "uuid",
"required": true,
"schema": {
"description": "UUID of the soundtrack or song",
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "The song (MP3)"
},
"206": {
"content": {
"audio/mpeg": {
"schema": {
"contentMediaType": "application/octet-stream",
"format": "binary",
"type": "string"
}
}
},
"description": "Part of the file, for a Range request"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Stream song",
"tags": [
"library"
]
}
},
"/api/v1/soundtracks": {
"get": {
"description": "Returns all soundtracks, sorted by name.",
"operationId": "list-soundtracks",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/Soundtrack"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "List soundtracks",
"tags": [
"library"
]
}
},
"/api/v1/soundtracks/{uuid}": {
"get": {
"description": "Returns a soundtrack with its songs, sorted by name.",
"operationId": "get-soundtrack",
"parameters": [
{
"description": "UUID of the soundtrack or song",
"in": "path",
"name": "uuid",
"required": true,
"schema": {
"description": "UUID of the soundtrack or song",
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SoundtrackWithSongList"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Get soundtrack",
"tags": [
"library"
]
}
},
"/api/v1/statistics/songs/least-played": {
"get": {
"description": "Returns the least played songs with their soundtrack.",
"operationId": "get-least-played-songs",
"parameters": [
{
"description": "Number of results. Values above 100 are capped to 100.",
"explode": false,
"in": "query",
"name": "limit",
"schema": {
"default": 10,
"description": "Number of results. Values above 100 are capped to 100.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SongInfoForStats"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Least played songs",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/songs/most-played": {
"get": {
"description": "Returns the most played songs with their soundtrack.",
"operationId": "get-most-played-songs",
"parameters": [
{
"description": "Number of results. Values above 100 are capped to 100.",
"explode": false,
"in": "query",
"name": "limit",
"schema": {
"default": 10,
"description": "Number of results. Values above 100 are capped to 100.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SongInfoForStats"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Most played songs",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/soundtracks": {
"get": {
"description": "Returns every soundtrack with its songs and play counts, sorted by name.",
"operationId": "get-all-soundtrack-statistics",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SoundtrackWithSongs"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "All soundtracks with statistics",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/soundtracks/last-played": {
"get": {
"description": "Returns the most recently played soundtracks with their songs.",
"operationId": "get-last-played-soundtracks",
"parameters": [
{
"description": "Number of results. Values above 100 are capped to 100.",
"explode": false,
"in": "query",
"name": "limit",
"schema": {
"default": 10,
"description": "Number of results. Values above 100 are capped to 100.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SoundtrackWithSongs"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Recently played soundtracks",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/soundtracks/least-played": {
"get": {
"description": "Returns the least played soundtracks with their songs.",
"operationId": "get-least-played-soundtracks",
"parameters": [
{
"description": "Number of results. Values above 100 are capped to 100.",
"explode": false,
"in": "query",
"name": "limit",
"schema": {
"default": 10,
"description": "Number of results. Values above 100 are capped to 100.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SoundtrackWithSongs"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Least played soundtracks",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/soundtracks/most-played": {
"get": {
"description": "Returns the most played soundtracks with their songs.",
"operationId": "get-most-played-soundtracks",
"parameters": [
{
"description": "Number of results. Values above 100 are capped to 100.",
"explode": false,
"in": "query",
"name": "limit",
"schema": {
"default": 10,
"description": "Number of results. Values above 100 are capped to 100.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SoundtrackWithSongs"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Most played soundtracks",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/soundtracks/never-played": {
"get": {
"description": "Returns all soundtracks that have never been played, with their songs.",
"operationId": "get-never-played-soundtracks",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SoundtrackWithSongs"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Never played soundtracks",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/soundtracks/oldest-played": {
"get": {
"description": "Returns the soundtracks played longest ago (played at least once) with their songs.",
"operationId": "get-oldest-played-soundtracks",
"parameters": [
{
"description": "Number of results. Values above 100 are capped to 100.",
"explode": false,
"in": "query",
"name": "limit",
"schema": {
"default": 10,
"description": "Number of results. Values above 100 are capped to 100.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SoundtrackWithSongs"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Least recently played soundtracks",
"tags": [
"statistics"
]
}
},
"/api/v1/statistics/summary": {
"get": {
"description": "Returns overall play statistics.",
"operationId": "get-statistics-summary",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StatisticsSummary"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Statistics summary",
"tags": [
"statistics"
]
}
},
"/api/v1/sync": {
"post": {
"description": "Starts syncing the music folder in the background, skipping soundtracks that have not changed. Poll /sync/progress for the result.",
"operationId": "start-sync",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Sync changed soundtracks",
"tags": [
"sync"
]
}
},
"/api/v1/sync/full": {
"post": {
"description": "Starts a full sync in the background that re-reads every soundtrack and removes songs whose files are gone. Poll /sync/progress for the result.",
"operationId": "start-full-sync",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"423": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Locked"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Sync all soundtracks",
"tags": [
"sync"
]
}
},
"/api/v1/sync/progress": {
"get": {
"description": "While a sync is running, returns its progress. Otherwise returns the result of the last sync.",
"operationId": "get-sync-progress",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/ProgressResponse"
},
{
"$ref": "#/components/schemas/SyncResponse"
}
]
}
}
},
"description": "Progress of the running sync, or the result of the last sync"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Sync progress or result",
"tags": [
"sync"
]
}
},
"/api/v1/token": {
"delete": {
"description": "Deletes the token used for this request.",
"operationId": "delete-token",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StatusMessage"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Invalidate session token",
"tags": [
"auth"
]
},
"post": {
"description": "Returns a token for the other /api/v1 endpoints, valid for 24 hours. Requires the API password when the server has one. Limited to 10 requests per minute per client.",
"operationId": "create-token",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenResponse"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unprocessable Entity"
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Too Many Requests"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"summary": "Create session token",
"tags": [
"auth"
]
}
},
"/api/v1/token/cleanup": {
"post": {
"description": "Deletes all expired session tokens.",
"operationId": "cleanup-tokens",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StatusMessage"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Remove expired tokens",
"tags": [
"auth"
]
}
},
"/api/v1/version": {
"get": {
"description": "Returns the server version and its changelog.",
"operationId": "get-version",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VersionData"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Latest server version",
"tags": [
"server"
]
}
},
"/api/v1/version/history": {
"get": {
"description": "Returns all server versions with their changelogs, newest first.",
"operationId": "get-version-history",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/VersionData"
},
"type": "array"
}
}
},
"description": "OK"
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Unauthorized"
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIError"
}
}
},
"description": "Internal Server Error"
}
},
"security": [
{
"bearer": []
}
],
"summary": "Version history",
"tags": [
"server"
]
}
}
}
}