The LAN REST/SSE server is not in the shipping binary; fix license/repo metadata and mark the document historical while retaining path schemas.
1200 lines
32 KiB
YAML
1200 lines
32 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: QBZ Remote Control API (historical, not available in 2.0 Slint)
|
|
description: |
|
|
**STATUS (2.0+):** This OpenAPI document describes the LAN Remote Control HTTP
|
|
API that shipped with the pre-2.0 Tauri/Svelte tree. That server is **not**
|
|
part of the shipping Slint binary. Settings storage for remote-control
|
|
preferences may still exist in `qbz-app`, but there is no in-process Axum
|
|
API, SSE `/api/events` stream, or Settings UI panel that exposes this surface
|
|
on current `pre-release` / 2.0.x.
|
|
|
|
Keep this file only as a historical reference for the `legacy-tauri-svelte`
|
|
tag and any future re-port. Do not treat endpoints below as live.
|
|
|
|
---
|
|
|
|
REST API for controlling QBZ music player remotely (1.x era). This API
|
|
allowed custom clients (web, CLI, mobile) to control playback, manage queue,
|
|
search music, and receive real-time updates.
|
|
|
|
## Authentication
|
|
|
|
All endpoints (except `/api/cert`) require authentication via one of:
|
|
- Header: `X-API-Key: <token>`
|
|
- Header: `Authorization: Bearer <token>`
|
|
- Query parameter: `?token=<token>` (historical; prefer headers)
|
|
|
|
## Network Requirements
|
|
|
|
- API only accepts connections from LAN (private IP addresses)
|
|
- Default port: 8182 (configurable)
|
|
- Supports HTTP and HTTPS (self-signed certificate)
|
|
|
|
## Real-time Updates
|
|
|
|
Clients used the `/api/events` SSE endpoint for real-time playback state updates instead of polling.
|
|
|
|
version: 1.0.0-historical
|
|
contact:
|
|
name: QBZ Project
|
|
url: https://github.com/vicrodh/qbz
|
|
license:
|
|
name: MIT
|
|
url: https://opensource.org/licenses/MIT
|
|
|
|
servers:
|
|
- url: http://{host}:{port}
|
|
description: QBZ Remote Control Server (HTTP)
|
|
variables:
|
|
host:
|
|
default: 192.168.1.100
|
|
description: Local IP address of the machine running QBZ
|
|
port:
|
|
default: "8182"
|
|
description: Remote control port (configurable in QBZ settings)
|
|
- url: https://{host}:{port}
|
|
description: QBZ Remote Control Server (HTTPS)
|
|
variables:
|
|
host:
|
|
default: 192.168.1.100
|
|
port:
|
|
default: "8182"
|
|
|
|
tags:
|
|
- name: Connection
|
|
description: Connection and authentication endpoints
|
|
- name: Playback
|
|
description: Playback control (play, pause, seek, volume)
|
|
- name: Queue
|
|
description: Queue management (add, remove, shuffle, repeat)
|
|
- name: Search
|
|
description: Search for tracks, albums, and artists
|
|
- name: Favorites
|
|
description: Manage user favorites
|
|
- name: Library
|
|
description: Album and artist information
|
|
- name: Real-time
|
|
description: Real-time updates via SSE/WebSocket
|
|
|
|
security:
|
|
- ApiKeyHeader: []
|
|
- BearerAuth: []
|
|
- ApiKeyQuery: []
|
|
|
|
paths:
|
|
/api/ping:
|
|
get:
|
|
tags: [Connection]
|
|
summary: Test connection
|
|
description: Check if the server is running and get device info. Use this to verify your connection is working.
|
|
responses:
|
|
"200":
|
|
description: Server is running
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PingResponse"
|
|
example:
|
|
ok: true
|
|
version: "1.1.8"
|
|
name: "blitzkrieg-pc"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/cert:
|
|
get:
|
|
tags: [Connection]
|
|
summary: Download TLS certificate
|
|
description: |
|
|
Download the self-signed TLS certificate for HTTPS connections.
|
|
Only available when secure mode is enabled. This endpoint does NOT require authentication.
|
|
security: []
|
|
responses:
|
|
"200":
|
|
description: PEM certificate file
|
|
content:
|
|
application/x-pem-file:
|
|
schema:
|
|
type: string
|
|
format: binary
|
|
"500":
|
|
description: Certificate not available
|
|
|
|
/api/now-playing:
|
|
get:
|
|
tags: [Playback]
|
|
summary: Get current playback state
|
|
description: Returns the current playback state and track information.
|
|
responses:
|
|
"200":
|
|
description: Current playback state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/NowPlayingResponse"
|
|
example:
|
|
playback:
|
|
isPlaying: true
|
|
position: 125
|
|
duration: 320
|
|
trackId: 12345678
|
|
volume: 0.75
|
|
track:
|
|
id: 12345678
|
|
title: "Bohemian Rhapsody"
|
|
artist: "Queen"
|
|
album: "A Night at the Opera"
|
|
durationSecs: 320
|
|
artworkUrl: "https://static.qobuz.com/images/..."
|
|
hires: true
|
|
bitDepth: 24
|
|
sampleRate: 96.0
|
|
isLocal: false
|
|
albumId: "abc123"
|
|
artistId: 456
|
|
streamable: true
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/status:
|
|
get:
|
|
tags: [Playback]
|
|
summary: Get current playback state (alias)
|
|
description: Alias for `/api/now-playing`.
|
|
responses:
|
|
"200":
|
|
description: Current playback state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/NowPlayingResponse"
|
|
|
|
/api/playback/play:
|
|
post:
|
|
tags: [Playback]
|
|
summary: Resume playback
|
|
description: Resume playback if paused.
|
|
responses:
|
|
"204":
|
|
description: Playback resumed
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
description: Playback error
|
|
|
|
/api/playback/pause:
|
|
post:
|
|
tags: [Playback]
|
|
summary: Pause playback
|
|
description: Pause current playback.
|
|
responses:
|
|
"204":
|
|
description: Playback paused
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
description: Playback error
|
|
|
|
/api/playback/next:
|
|
post:
|
|
tags: [Playback]
|
|
summary: Skip to next track
|
|
description: Skip to the next track in the queue.
|
|
responses:
|
|
"200":
|
|
description: Next track info (or null if queue ended)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/playback/previous:
|
|
post:
|
|
tags: [Playback]
|
|
summary: Go to previous track
|
|
description: Go back to the previous track in history.
|
|
responses:
|
|
"200":
|
|
description: Previous track info (or null if no history)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/playback/seek:
|
|
post:
|
|
tags: [Playback]
|
|
summary: Seek to position
|
|
description: Seek to a specific position in the current track.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SeekRequest"
|
|
example:
|
|
position: 60
|
|
responses:
|
|
"204":
|
|
description: Seek successful
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
description: Seek error
|
|
|
|
/api/playback/volume:
|
|
post:
|
|
tags: [Playback]
|
|
summary: Set volume
|
|
description: Set the playback volume (0.0 to 1.0).
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VolumeRequest"
|
|
example:
|
|
volume: 0.75
|
|
responses:
|
|
"204":
|
|
description: Volume set
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
description: Volume error
|
|
|
|
/api/playback/preferences:
|
|
get:
|
|
tags: [Playback]
|
|
summary: Get playback preferences
|
|
description: Get current playback preferences including autoplay mode.
|
|
responses:
|
|
"200":
|
|
description: Playback preferences
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PlaybackPreferences"
|
|
example:
|
|
autoplayMode: "continue"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/playback/autoplay:
|
|
post:
|
|
tags: [Playback]
|
|
summary: Set autoplay mode
|
|
description: |
|
|
Set what happens when the current track/queue ends.
|
|
- `continue`: Continue playing within the current album/playlist
|
|
- `track_only`: Stop after current track
|
|
- `infinite`: Start infinite radio based on current track
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AutoplayRequest"
|
|
example:
|
|
mode: "continue"
|
|
responses:
|
|
"204":
|
|
description: Autoplay mode set
|
|
"400":
|
|
description: Invalid mode
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/queue:
|
|
get:
|
|
tags: [Queue]
|
|
summary: Get queue state
|
|
description: Get the current queue including upcoming tracks, history, and settings.
|
|
responses:
|
|
"200":
|
|
description: Queue state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/QueueState"
|
|
example:
|
|
currentTrack:
|
|
id: 12345678
|
|
title: "Bohemian Rhapsody"
|
|
artist: "Queen"
|
|
album: "A Night at the Opera"
|
|
durationSecs: 320
|
|
currentIndex: 2
|
|
upcoming:
|
|
- id: 12345679
|
|
title: "Another Track"
|
|
artist: "Artist"
|
|
album: "Album"
|
|
durationSecs: 240
|
|
history:
|
|
- id: 12345677
|
|
title: "Previous Track"
|
|
artist: "Artist"
|
|
album: "Album"
|
|
durationSecs: 180
|
|
shuffle: false
|
|
repeat: "Off"
|
|
totalTracks: 10
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/queue/add:
|
|
post:
|
|
tags: [Queue]
|
|
summary: Add track to queue
|
|
description: Add a track to the end of the queue.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AddToQueueRequest"
|
|
responses:
|
|
"204":
|
|
description: Track added
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/queue/add-next:
|
|
post:
|
|
tags: [Queue]
|
|
summary: Add track to play next
|
|
description: Add a track to play immediately after the current track.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AddToQueueRequest"
|
|
responses:
|
|
"204":
|
|
description: Track added to play next
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/queue/play:
|
|
post:
|
|
tags: [Queue]
|
|
summary: Play track at index
|
|
description: Start playing a specific track in the queue by its index.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PlayIndexRequest"
|
|
example:
|
|
index: 3
|
|
responses:
|
|
"200":
|
|
description: Track info (or null if index invalid)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Playback failed
|
|
|
|
/api/queue/shuffle:
|
|
post:
|
|
tags: [Queue]
|
|
summary: Set shuffle mode
|
|
description: Enable or disable shuffle mode.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ShuffleRequest"
|
|
example:
|
|
enabled: true
|
|
responses:
|
|
"200":
|
|
description: Updated shuffle/repeat state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ShuffleRepeatResponse"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/queue/repeat:
|
|
post:
|
|
tags: [Queue]
|
|
summary: Set repeat mode
|
|
description: |
|
|
Set the repeat mode:
|
|
- `off`: No repeat
|
|
- `all`: Repeat entire queue
|
|
- `one`: Repeat current track
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/RepeatRequest"
|
|
example:
|
|
mode: "all"
|
|
responses:
|
|
"200":
|
|
description: Updated shuffle/repeat state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ShuffleRepeatResponse"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/search:
|
|
get:
|
|
tags: [Search]
|
|
summary: Search tracks
|
|
description: Search for tracks by query string.
|
|
parameters:
|
|
- name: q
|
|
in: query
|
|
required: true
|
|
description: Search query
|
|
schema:
|
|
type: string
|
|
example: "bohemian rhapsody"
|
|
- name: limit
|
|
in: query
|
|
description: Maximum results (default 20)
|
|
schema:
|
|
type: integer
|
|
default: 20
|
|
- name: offset
|
|
in: query
|
|
description: Results offset for pagination
|
|
schema:
|
|
type: integer
|
|
default: 0
|
|
responses:
|
|
"200":
|
|
description: Search results
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SearchResultsPage"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Search service unavailable
|
|
|
|
/api/search/all:
|
|
get:
|
|
tags: [Search]
|
|
summary: Search all types
|
|
description: Search for tracks, albums, and artists simultaneously.
|
|
parameters:
|
|
- name: q
|
|
in: query
|
|
required: true
|
|
description: Search query
|
|
schema:
|
|
type: string
|
|
- name: limit
|
|
in: query
|
|
description: Maximum results per type (default 10)
|
|
schema:
|
|
type: integer
|
|
default: 10
|
|
- name: offset
|
|
in: query
|
|
description: Results offset
|
|
schema:
|
|
type: integer
|
|
default: 0
|
|
responses:
|
|
"200":
|
|
description: Search results for all types
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SearchAllResults"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Search service unavailable
|
|
|
|
/api/favorites:
|
|
get:
|
|
tags: [Favorites]
|
|
summary: Get favorites
|
|
description: Get user's favorite items by type.
|
|
parameters:
|
|
- name: fav_type
|
|
in: query
|
|
required: true
|
|
description: Type of favorites to retrieve
|
|
schema:
|
|
type: string
|
|
enum: [tracks, albums, artists]
|
|
- name: limit
|
|
in: query
|
|
description: Maximum results (default 50)
|
|
schema:
|
|
type: integer
|
|
default: 50
|
|
- name: offset
|
|
in: query
|
|
description: Results offset
|
|
schema:
|
|
type: integer
|
|
default: 0
|
|
responses:
|
|
"200":
|
|
description: Favorites list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
description: Paginated favorites (structure varies by type)
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Service unavailable
|
|
|
|
/api/favorites/add:
|
|
post:
|
|
tags: [Favorites]
|
|
summary: Add to favorites
|
|
description: Add an item to user's favorites.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FavoriteRequest"
|
|
example:
|
|
favType: "tracks"
|
|
itemId: "12345678"
|
|
responses:
|
|
"204":
|
|
description: Added to favorites
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Service unavailable
|
|
|
|
/api/favorites/remove:
|
|
post:
|
|
tags: [Favorites]
|
|
summary: Remove from favorites
|
|
description: Remove an item from user's favorites.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FavoriteRequest"
|
|
example:
|
|
favType: "tracks"
|
|
itemId: "12345678"
|
|
responses:
|
|
"204":
|
|
description: Removed from favorites
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Service unavailable
|
|
|
|
/api/album/{id}:
|
|
get:
|
|
tags: [Library]
|
|
summary: Get album details
|
|
description: Get full album information including track list.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Album ID
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Album details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Album"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Service unavailable
|
|
|
|
/api/album/play:
|
|
post:
|
|
tags: [Library]
|
|
summary: Play album
|
|
description: Clear queue and play all tracks from an album.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PlayAlbumRequest"
|
|
example:
|
|
albumId: "abc123xyz"
|
|
responses:
|
|
"204":
|
|
description: Album playback started
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
description: Album not found or has no tracks
|
|
"502":
|
|
description: Playback failed
|
|
|
|
/api/artist/{id}:
|
|
get:
|
|
tags: [Library]
|
|
summary: Get artist details
|
|
description: Get artist information including discography.
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Artist ID
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Artist details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Artist"
|
|
"400":
|
|
description: Invalid artist ID
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"502":
|
|
description: Service unavailable
|
|
|
|
/api/events:
|
|
get:
|
|
tags: [Real-time]
|
|
summary: SSE event stream
|
|
description: |
|
|
Server-Sent Events stream for real-time playback updates. This is the recommended
|
|
way to receive updates instead of polling `/api/now-playing`.
|
|
|
|
**Connection:**
|
|
```javascript
|
|
const es = new EventSource('http://host:port/api/events?token=YOUR_TOKEN');
|
|
es.onmessage = (event) => {
|
|
const data = JSON.parse(event.data);
|
|
console.log('Playback update:', data);
|
|
};
|
|
```
|
|
|
|
**Events:**
|
|
- Playback state changes (play/pause, position, volume)
|
|
- Track changes
|
|
- Shuffle/repeat mode changes
|
|
|
|
**Keep-alive:** Server sends ping every 15 seconds.
|
|
|
|
**Reconnection:** EventSource automatically reconnects on connection loss.
|
|
responses:
|
|
"200":
|
|
description: SSE event stream
|
|
content:
|
|
text/event-stream:
|
|
schema:
|
|
type: string
|
|
description: |
|
|
Stream of SSE events. Each event contains JSON data:
|
|
```
|
|
data: {"isPlaying":true,"position":125,"duration":320,"trackId":12345678,"volume":0.75,"sampleRate":96000,"bitDepth":24,"shuffle":false,"repeat":"off"}
|
|
```
|
|
example: |
|
|
data: {"isPlaying":true,"position":125,"duration":320,"trackId":12345678,"volume":0.75}
|
|
|
|
data: {"isPlaying":true,"position":126,"duration":320,"trackId":12345678,"volume":0.75}
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
/api/ws:
|
|
get:
|
|
tags: [Real-time]
|
|
summary: WebSocket connection (deprecated)
|
|
description: |
|
|
WebSocket endpoint for real-time updates. **Deprecated:** Use `/api/events` (SSE) instead
|
|
for simpler integration and automatic reconnection.
|
|
|
|
**Connection:**
|
|
```javascript
|
|
const ws = new WebSocket('ws://host:port/api/ws?token=YOUR_TOKEN');
|
|
ws.onmessage = (event) => {
|
|
const data = JSON.parse(event.data);
|
|
console.log('Playback update:', data);
|
|
};
|
|
```
|
|
deprecated: true
|
|
responses:
|
|
"101":
|
|
description: WebSocket upgrade
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
|
|
components:
|
|
securitySchemes:
|
|
ApiKeyHeader:
|
|
type: apiKey
|
|
in: header
|
|
name: X-API-Key
|
|
description: API token, generated in the 1.x Settings > Remote Control panel (no longer present in 2.0)
|
|
BearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
description: API token as Bearer token
|
|
ApiKeyQuery:
|
|
type: apiKey
|
|
in: query
|
|
name: token
|
|
description: API token as query parameter (useful for SSE/WebSocket)
|
|
|
|
responses:
|
|
Unauthorized:
|
|
description: Missing or invalid authentication token
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
example: "Unauthorized"
|
|
|
|
schemas:
|
|
PingResponse:
|
|
type: object
|
|
required: [ok, version, name]
|
|
properties:
|
|
ok:
|
|
type: boolean
|
|
description: Always true if server is running
|
|
version:
|
|
type: string
|
|
description: QBZ version
|
|
example: "1.1.8"
|
|
name:
|
|
type: string
|
|
description: Device hostname
|
|
example: "my-pc"
|
|
|
|
NowPlayingResponse:
|
|
type: object
|
|
required: [playback]
|
|
properties:
|
|
playback:
|
|
$ref: "#/components/schemas/PlaybackState"
|
|
track:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
nullable: true
|
|
description: Current track info (null if nothing playing)
|
|
|
|
PlaybackState:
|
|
type: object
|
|
required: [isPlaying, position, duration, trackId, volume]
|
|
properties:
|
|
isPlaying:
|
|
type: boolean
|
|
description: Whether playback is active
|
|
position:
|
|
type: integer
|
|
format: int64
|
|
description: Current position in seconds
|
|
duration:
|
|
type: integer
|
|
format: int64
|
|
description: Track duration in seconds
|
|
trackId:
|
|
type: integer
|
|
format: int64
|
|
description: Current track ID (0 if nothing playing)
|
|
volume:
|
|
type: number
|
|
format: float
|
|
minimum: 0
|
|
maximum: 1
|
|
description: Volume level (0.0 to 1.0)
|
|
|
|
PlaybackEvent:
|
|
type: object
|
|
description: Real-time playback event (sent via SSE/WebSocket)
|
|
required: [isPlaying, position, duration, trackId, volume]
|
|
properties:
|
|
isPlaying:
|
|
type: boolean
|
|
position:
|
|
type: integer
|
|
format: int64
|
|
duration:
|
|
type: integer
|
|
format: int64
|
|
trackId:
|
|
type: integer
|
|
format: int64
|
|
volume:
|
|
type: number
|
|
format: float
|
|
sampleRate:
|
|
type: integer
|
|
nullable: true
|
|
description: Current stream sample rate in Hz
|
|
example: 96000
|
|
bitDepth:
|
|
type: integer
|
|
nullable: true
|
|
description: Current stream bit depth
|
|
example: 24
|
|
shuffle:
|
|
type: boolean
|
|
nullable: true
|
|
description: Queue shuffle state
|
|
repeat:
|
|
type: string
|
|
nullable: true
|
|
enum: [off, all, one]
|
|
description: Queue repeat mode
|
|
|
|
QueueTrack:
|
|
type: object
|
|
required: [id, title, artist, album, durationSecs]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
description: Track ID
|
|
title:
|
|
type: string
|
|
description: Track title
|
|
artist:
|
|
type: string
|
|
description: Artist name
|
|
album:
|
|
type: string
|
|
description: Album title
|
|
durationSecs:
|
|
type: integer
|
|
format: int64
|
|
description: Duration in seconds
|
|
artworkUrl:
|
|
type: string
|
|
format: uri
|
|
nullable: true
|
|
description: Album artwork URL
|
|
hires:
|
|
type: boolean
|
|
default: false
|
|
description: Whether track is Hi-Res
|
|
bitDepth:
|
|
type: integer
|
|
nullable: true
|
|
description: Maximum bit depth available
|
|
example: 24
|
|
sampleRate:
|
|
type: number
|
|
nullable: true
|
|
description: Maximum sample rate in kHz
|
|
example: 96.0
|
|
isLocal:
|
|
type: boolean
|
|
default: false
|
|
description: Whether track is from local library
|
|
albumId:
|
|
type: string
|
|
nullable: true
|
|
description: Album ID for navigation
|
|
artistId:
|
|
type: integer
|
|
format: int64
|
|
nullable: true
|
|
description: Artist ID for navigation
|
|
streamable:
|
|
type: boolean
|
|
default: true
|
|
description: Whether track is available for streaming
|
|
|
|
QueueState:
|
|
type: object
|
|
required: [shuffle, repeat, totalTracks]
|
|
properties:
|
|
currentTrack:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
nullable: true
|
|
currentIndex:
|
|
type: integer
|
|
nullable: true
|
|
description: Index of current track in queue
|
|
upcoming:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
description: Upcoming tracks
|
|
history:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
description: Previously played tracks
|
|
shuffle:
|
|
type: boolean
|
|
description: Shuffle mode enabled
|
|
repeat:
|
|
type: string
|
|
enum: [Off, All, One]
|
|
description: Repeat mode
|
|
totalTracks:
|
|
type: integer
|
|
description: Total tracks in queue
|
|
|
|
SeekRequest:
|
|
type: object
|
|
required: [position]
|
|
properties:
|
|
position:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
description: Target position in seconds
|
|
|
|
VolumeRequest:
|
|
type: object
|
|
required: [volume]
|
|
properties:
|
|
volume:
|
|
type: number
|
|
format: float
|
|
minimum: 0
|
|
maximum: 1
|
|
description: Volume level (0.0 to 1.0)
|
|
|
|
PlayIndexRequest:
|
|
type: object
|
|
required: [index]
|
|
properties:
|
|
index:
|
|
type: integer
|
|
minimum: 0
|
|
description: Queue index to play
|
|
|
|
AddToQueueRequest:
|
|
type: object
|
|
required: [track]
|
|
properties:
|
|
track:
|
|
$ref: "#/components/schemas/QueueTrack"
|
|
|
|
ShuffleRequest:
|
|
type: object
|
|
required: [enabled]
|
|
properties:
|
|
enabled:
|
|
type: boolean
|
|
description: Enable shuffle mode
|
|
|
|
RepeatRequest:
|
|
type: object
|
|
required: [mode]
|
|
properties:
|
|
mode:
|
|
type: string
|
|
enum: [off, all, one]
|
|
description: Repeat mode
|
|
|
|
ShuffleRepeatResponse:
|
|
type: object
|
|
required: [shuffle, repeat]
|
|
properties:
|
|
shuffle:
|
|
type: boolean
|
|
repeat:
|
|
type: string
|
|
enum: [off, all, one]
|
|
|
|
PlaybackPreferences:
|
|
type: object
|
|
properties:
|
|
autoplayMode:
|
|
type: string
|
|
enum: [continue, track_only, infinite]
|
|
description: What happens when queue ends
|
|
|
|
AutoplayRequest:
|
|
type: object
|
|
required: [mode]
|
|
properties:
|
|
mode:
|
|
type: string
|
|
enum: [continue, track_only, infinite]
|
|
description: |
|
|
- `continue`: Continue within current source
|
|
- `track_only`: Stop after current track
|
|
- `infinite`: Start infinite radio
|
|
|
|
FavoriteRequest:
|
|
type: object
|
|
required: [favType, itemId]
|
|
properties:
|
|
favType:
|
|
type: string
|
|
enum: [tracks, albums, artists]
|
|
itemId:
|
|
type: string
|
|
description: Item ID to add/remove
|
|
|
|
PlayAlbumRequest:
|
|
type: object
|
|
required: [albumId]
|
|
properties:
|
|
albumId:
|
|
type: string
|
|
description: Album ID to play
|
|
|
|
SearchResultsPage:
|
|
type: object
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Track"
|
|
total:
|
|
type: integer
|
|
description: Total matching results
|
|
offset:
|
|
type: integer
|
|
limit:
|
|
type: integer
|
|
|
|
SearchAllResults:
|
|
type: object
|
|
properties:
|
|
albums:
|
|
$ref: "#/components/schemas/SearchResultsPage"
|
|
tracks:
|
|
$ref: "#/components/schemas/SearchResultsPage"
|
|
artists:
|
|
$ref: "#/components/schemas/SearchResultsPage"
|
|
playlists:
|
|
$ref: "#/components/schemas/SearchResultsPage"
|
|
|
|
Track:
|
|
type: object
|
|
description: Track from search results
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
title:
|
|
type: string
|
|
duration:
|
|
type: integer
|
|
description: Duration in seconds
|
|
hires:
|
|
type: boolean
|
|
maximumBitDepth:
|
|
type: integer
|
|
maximumSamplingRate:
|
|
type: number
|
|
streamable:
|
|
type: boolean
|
|
performer:
|
|
$ref: "#/components/schemas/ArtistSummary"
|
|
album:
|
|
$ref: "#/components/schemas/AlbumSummary"
|
|
|
|
Album:
|
|
type: object
|
|
description: Full album details
|
|
properties:
|
|
id:
|
|
type: string
|
|
title:
|
|
type: string
|
|
artist:
|
|
$ref: "#/components/schemas/ArtistSummary"
|
|
image:
|
|
type: object
|
|
properties:
|
|
small:
|
|
type: string
|
|
format: uri
|
|
large:
|
|
type: string
|
|
format: uri
|
|
tracks:
|
|
type: object
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Track"
|
|
total:
|
|
type: integer
|
|
|
|
AlbumSummary:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
title:
|
|
type: string
|
|
image:
|
|
type: object
|
|
properties:
|
|
small:
|
|
type: string
|
|
format: uri
|
|
large:
|
|
type: string
|
|
format: uri
|
|
|
|
Artist:
|
|
type: object
|
|
description: Full artist details
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
name:
|
|
type: string
|
|
image:
|
|
type: object
|
|
nullable: true
|
|
properties:
|
|
small:
|
|
type: string
|
|
format: uri
|
|
large:
|
|
type: string
|
|
format: uri
|
|
albums:
|
|
type: object
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/AlbumSummary"
|
|
|
|
ArtistSummary:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
name:
|
|
type: string
|