The API spec is now formatted like before (2-space indents, sorted keys): develop's spec with the upload paths and types added, so the diff to develop is only the upload API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4941 lines
132 KiB
JSON
4941 lines
132 KiB
JSON
{
|
|
"components": {
|
|
"schemas": {
|
|
"APIError": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"error": {
|
|
"description": "What went wrong",
|
|
"examples": [
|
|
"Not Found"
|
|
],
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"error"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"AlternativeNames": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"names": {
|
|
"description": "The new list of alternative names. Replaces the old list; send [] to remove them all.",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"maxItems": 50,
|
|
"type": "array"
|
|
}
|
|
},
|
|
"required": [
|
|
"names"
|
|
],
|
|
"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"
|
|
},
|
|
"CoverSource": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"id": {
|
|
"description": "The game's ID on SteamGridDB, or the anime's ID on AniList",
|
|
"maxLength": 50,
|
|
"minLength": 1,
|
|
"type": "string"
|
|
},
|
|
"source": {
|
|
"description": "Where the cover comes from",
|
|
"enum": [
|
|
"steamgriddb",
|
|
"anilist"
|
|
],
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"source",
|
|
"id"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"ProgressResponse": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"progress": {
|
|
"type": "string"
|
|
},
|
|
"time_spent": {
|
|
"description": "How long the sync has been running, as minutes and seconds, e.g. \"02:15\"",
|
|
"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"
|
|
},
|
|
"alternative_names": {
|
|
"description": "Other names the soundtrack is known by",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"type": "array"
|
|
},
|
|
"cover_modified": {
|
|
"description": "When the cover last changed, in Unix seconds. Missing when there is no cover.",
|
|
"format": "int64",
|
|
"type": "integer"
|
|
},
|
|
"last_played": {
|
|
"format": "date-time",
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"times_played": {
|
|
"format": "int32",
|
|
"type": "integer"
|
|
},
|
|
"uuid": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"uuid",
|
|
"name",
|
|
"alternative_names",
|
|
"times_played",
|
|
"added"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"SoundtrackWithSongList": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"added": {
|
|
"format": "date-time",
|
|
"type": "string"
|
|
},
|
|
"alternative_names": {
|
|
"description": "Other names the soundtrack is known by",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"type": "array"
|
|
},
|
|
"cover_modified": {
|
|
"description": "When the cover last changed, in Unix seconds. Missing when there is no cover.",
|
|
"format": "int64",
|
|
"type": "integer"
|
|
},
|
|
"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",
|
|
"alternative_names",
|
|
"times_played",
|
|
"added"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"SoundtrackWithSongs": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"alternative_names": {
|
|
"description": "Other names the soundtrack is known by",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"type": "array"
|
|
},
|
|
"cover_modified": {
|
|
"description": "When the cover last changed, in Unix seconds. Missing when there is no cover.",
|
|
"format": "int64",
|
|
"type": "integer"
|
|
},
|
|
"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",
|
|
"alternative_names",
|
|
"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": {
|
|
"description": "How long the sync took, as minutes and seconds, e.g. \"02:15\"",
|
|
"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"
|
|
},
|
|
"Upload": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"files": {
|
|
"description": "The songs received so far, sorted by name",
|
|
"items": {
|
|
"$ref": "#/components/schemas/UploadFile"
|
|
},
|
|
"type": "array"
|
|
},
|
|
"id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"description": "Name of the new soundtrack, also its folder name",
|
|
"type": "string"
|
|
},
|
|
"started": {
|
|
"format": "date-time",
|
|
"type": "string"
|
|
},
|
|
"total_size": {
|
|
"description": "Size of all songs received so far, in bytes",
|
|
"format": "int64",
|
|
"type": "integer"
|
|
}
|
|
},
|
|
"required": [
|
|
"id",
|
|
"name",
|
|
"started",
|
|
"files",
|
|
"total_size"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"UploadFile": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"size": {
|
|
"format": "int64",
|
|
"type": "integer"
|
|
}
|
|
},
|
|
"required": [
|
|
"name",
|
|
"size"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"UploadRequest": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"name": {
|
|
"description": "Name of the new soundtrack, also its folder name in the music folder",
|
|
"maxLength": 200,
|
|
"minLength": 1,
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"name"
|
|
],
|
|
"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/linux-package": {
|
|
"get": {
|
|
"description": "Redirects to the download URL of the latest MusicPlayer release for Linux (package with installer).",
|
|
"operationId": "download-client-linux-package",
|
|
"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 (package with installer)",
|
|
"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/uploads": {
|
|
"post": {
|
|
"description": "Starts adding a new soundtrack. Send its songs with PUT /soundtracks/uploads/{id}/files/{file}, then POST /soundtracks/uploads/{id}/finish. The name must be usable as a folder name, and no soundtrack, folder or other upload may have it, ignoring case. Unfinished uploads are removed after a day.",
|
|
"operationId": "start-upload",
|
|
"requestBody": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/UploadRequest"
|
|
}
|
|
}
|
|
},
|
|
"required": true
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Upload"
|
|
}
|
|
}
|
|
},
|
|
"description": "Created"
|
|
},
|
|
"400": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Bad Request"
|
|
},
|
|
"401": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Unauthorized"
|
|
},
|
|
"409": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Conflict"
|
|
},
|
|
"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"
|
|
},
|
|
"503": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Service Unavailable"
|
|
}
|
|
},
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"summary": "Start uploading a soundtrack",
|
|
"tags": [
|
|
"uploads"
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/soundtracks/uploads/{id}": {
|
|
"delete": {
|
|
"description": "Deletes an unfinished upload and its songs.",
|
|
"operationId": "cancel-upload",
|
|
"parameters": [
|
|
{
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"in": "path",
|
|
"name": "id",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"format": "uuid",
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"204": {
|
|
"description": "No Content"
|
|
},
|
|
"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": "Cancel an upload",
|
|
"tags": [
|
|
"uploads"
|
|
]
|
|
},
|
|
"get": {
|
|
"description": "Returns an unfinished upload with the songs received so far, for example to resume it.",
|
|
"operationId": "get-upload",
|
|
"parameters": [
|
|
{
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"in": "path",
|
|
"name": "id",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"format": "uuid",
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Upload"
|
|
}
|
|
}
|
|
},
|
|
"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"
|
|
},
|
|
"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": "Get an upload",
|
|
"tags": [
|
|
"uploads"
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/soundtracks/uploads/{id}/files/{file}": {
|
|
"put": {
|
|
"description": "Stores one song of the upload, replacing a song of the same name, so a failed song can be sent again. Only MP3 files are accepted. The size limits are set on the server with UPLOAD_MAX_FILE_MB and UPLOAD_MAX_TOTAL_MB.",
|
|
"operationId": "upload-song",
|
|
"parameters": [
|
|
{
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"in": "path",
|
|
"name": "id",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"format": "uuid",
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"description": "File name of the song, e.g. \"01 Title.mp3\". Plain names only: put songs from disc folders in one folder, e.g. \"1-01 Title.mp3\".",
|
|
"in": "path",
|
|
"name": "file",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "File name of the song, e.g. \"01 Title.mp3\". Plain names only: put songs from disc folders in one folder, e.g. \"1-01 Title.mp3\".",
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"content": {
|
|
"audio/mpeg": {
|
|
"schema": {
|
|
"contentMediaType": "application/octet-stream",
|
|
"format": "binary",
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"required": true
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/UploadFile"
|
|
}
|
|
}
|
|
},
|
|
"description": "OK"
|
|
},
|
|
"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"
|
|
},
|
|
"413": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Request Entity Too Large"
|
|
},
|
|
"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": "Upload a song",
|
|
"tags": [
|
|
"uploads"
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/soundtracks/uploads/{id}/finish": {
|
|
"post": {
|
|
"description": "Moves the songs into a new folder in the music folder, adds the soundtrack to the library and returns it. Refused when a soundtrack with the same songs exists.",
|
|
"operationId": "finish-upload",
|
|
"parameters": [
|
|
{
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"in": "path",
|
|
"name": "id",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "ID of the upload, from POST /soundtracks/uploads",
|
|
"format": "uuid",
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/SoundtrackWithSongList"
|
|
}
|
|
}
|
|
},
|
|
"description": "OK"
|
|
},
|
|
"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"
|
|
},
|
|
"409": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Conflict"
|
|
},
|
|
"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": "Finish an upload",
|
|
"tags": [
|
|
"uploads"
|
|
]
|
|
}
|
|
},
|
|
"/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/soundtracks/{uuid}/alternative-names": {
|
|
"put": {
|
|
"description": "Replaces the soundtrack's alternative names, which search and the cover search also use. Names are trimmed, and empty names, duplicates and the soundtrack's own name (ignoring case) are dropped.",
|
|
"operationId": "set-alternative-names",
|
|
"parameters": [
|
|
{
|
|
"description": "UUID of the soundtrack",
|
|
"in": "path",
|
|
"name": "uuid",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "UUID of the soundtrack",
|
|
"format": "uuid",
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/AlternativeNames"
|
|
}
|
|
}
|
|
},
|
|
"required": true
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Soundtrack"
|
|
}
|
|
}
|
|
},
|
|
"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": "Set alternative names",
|
|
"tags": [
|
|
"library"
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/soundtracks/{uuid}/cover": {
|
|
"delete": {
|
|
"description": "Deletes the soundtrack's cover, including one set by hand, so the automatic search looks for a new one.",
|
|
"operationId": "delete-soundtrack-cover",
|
|
"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": {
|
|
"204": {
|
|
"description": "No Content"
|
|
},
|
|
"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"
|
|
},
|
|
"503": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Service Unavailable"
|
|
}
|
|
},
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"summary": "Remove the cover",
|
|
"tags": [
|
|
"covers"
|
|
]
|
|
},
|
|
"get": {
|
|
"description": "Returns the soundtrack's cover image. cover_modified in the soundtrack responses tells when it last changed.",
|
|
"operationId": "get-soundtrack-cover",
|
|
"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": {
|
|
"image/jpeg": {
|
|
"schema": {
|
|
"contentMediaType": "application/octet-stream",
|
|
"format": "binary",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"image/png": {
|
|
"schema": {
|
|
"contentMediaType": "application/octet-stream",
|
|
"format": "binary",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"image/webp": {
|
|
"schema": {
|
|
"contentMediaType": "application/octet-stream",
|
|
"format": "binary",
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"description": "The cover 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"
|
|
}
|
|
},
|
|
"image/webp": {
|
|
"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"
|
|
},
|
|
"500": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Internal Server Error"
|
|
}
|
|
},
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"summary": "Soundtrack cover",
|
|
"tags": [
|
|
"covers"
|
|
]
|
|
},
|
|
"put": {
|
|
"description": "Stores the image as the soundtrack's cover. The automatic search never replaces it; delete it to go back to automatic.",
|
|
"operationId": "upload-soundtrack-cover",
|
|
"parameters": [
|
|
{
|
|
"description": "UUID of the soundtrack",
|
|
"in": "path",
|
|
"name": "uuid",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "UUID of the soundtrack",
|
|
"format": "uuid",
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"content": {
|
|
"image/*": {
|
|
"schema": {
|
|
"contentMediaType": "application/octet-stream",
|
|
"format": "binary",
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"required": true
|
|
},
|
|
"responses": {
|
|
"204": {
|
|
"description": "No Content"
|
|
},
|
|
"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"
|
|
},
|
|
"503": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Service Unavailable"
|
|
}
|
|
},
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"summary": "Upload a cover",
|
|
"tags": [
|
|
"covers"
|
|
]
|
|
}
|
|
},
|
|
"/api/v1/soundtracks/{uuid}/cover/source": {
|
|
"put": {
|
|
"description": "Downloads the cover of the given SteamGridDB game or AniList anime and stores it as the soundtrack's cover. The automatic search never replaces it. SteamGridDB needs STEAMGRIDDB_API_KEY on the server.",
|
|
"operationId": "set-soundtrack-cover-source",
|
|
"parameters": [
|
|
{
|
|
"description": "UUID of the soundtrack",
|
|
"in": "path",
|
|
"name": "uuid",
|
|
"required": true,
|
|
"schema": {
|
|
"description": "UUID of the soundtrack",
|
|
"format": "uuid",
|
|
"type": "string"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/CoverSource"
|
|
}
|
|
}
|
|
},
|
|
"required": true
|
|
},
|
|
"responses": {
|
|
"204": {
|
|
"description": "No Content"
|
|
},
|
|
"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"
|
|
},
|
|
"502": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Bad Gateway"
|
|
},
|
|
"503": {
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/APIError"
|
|
}
|
|
}
|
|
},
|
|
"description": "Service Unavailable"
|
|
}
|
|
},
|
|
"security": [
|
|
{
|
|
"bearer": []
|
|
}
|
|
],
|
|
"summary": "Pick a cover",
|
|
"tags": [
|
|
"covers"
|
|
]
|
|
}
|
|
},
|
|
"/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"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|