Music Assistant Webserver Controller API Commands: Complete Reference
The Music Assistant webserver controller exposes a REST/JSON-RPC API via aiohttp, supporting HTTP endpoints, WebSocket real-time communication, and dynamic authentication, with endpoints defined in controller.py and handlers registered in self.mass.command_handlers.
The Music Assistant server provides a comprehensive HTTP and WebSocket API for controlling media playback, managing libraries, and configuring players. Located in the music-assistant/server repository, the WebserverController serves as the central entry point that marshals all client requests through a secure, token-based authentication layer. This article explores the architecture, endpoints, and practical usage of the Music Assistant webserver controller API commands based on the current implementation in the dev branch.
Architecture Overview
The WebserverController acts as the central HTTP and WebSocket entry point, running on top of aiohttp and exposing a fully-featured REST/JSON-RPC API. All endpoints add permissive CORS headers (*) to allow calling from any origin.
Core Components
- WebserverController (
music_assistant/controllers/webserver/controller.py): Starts a configurableWebserverinstance, registers static assets (frontend, logo, CSS), adds dynamic routes, and wires all API endpoints. It coordinates authentication, remote access, and SendSpin proxy handling. - Webserver Helper (
music_assistant/helpers/webserver.py): A thin wrapper aroundaiohttp.web.Applicationthat supports dynamic route registration and static file serving. - Authentication Manager (
music_assistant/controllers/webserver/auth.py): Issues and validates bearer tokens stored hashed in an SQLite table, working with middleware inhelpers/auth_middleware.pyto inject user contexts into requests viaset_current_user. - WebSocket Handler (
music_assistant/controllers/webserver/websocket_client.py): Manages persistent connections to the/wsendpoint, wrapping each connection in aWebsocketClientHandlerfor bidirectional JSON-RPC communication and event streaming.
Request Flow
- Startup:
WebserverController.setup()builds static routes for frontend files, logos, and info endpoints, registering them on aWebserverinstance. - Authentication: Middleware extracts bearer tokens, validates them against the
auth_tokenstable, and injects aUserobject into the request context. - JSON-RPC Processing: The
_handle_jsonrpc_api_commandmethod receivesCommandMessageobjects at/api, dispatches them toself.mass.command_handlers[command], checks required roles, and returns JSON results. - WebSocket Upgrade: The
/wsendpoint creates aWebsocketClientHandlerthat streams events (e.g.,player_state_updated) automatically to connected clients.
API Endpoints and Commands
JSON-RPC Command Endpoint (POST /api)
The primary API surface for executing commands. The _handle_jsonrpc_api_command method in controller.py parses incoming JSON payloads into CommandMessage instances (defined in music_assistant_models.api) and routes them to the appropriate handler registered in self.mass.command_handlers.
WebSocket Real-Time API (GET /ws)
Clients connect to /ws for bidirectional communication. The WebsocketClientHandler forwards incoming JSON-RPC messages over the socket and pushes server events without client polling, enabling real-time updates for player state changes.
Setup and Onboarding (POST /setup)
When no admin user exists, the server runs in setup mode and redirects all non-ingress requests to /setup. The _handle_setup endpoint creates the first admin account and returns a bearer token for subsequent authentication.
Preview Streaming (GET /preview)
The serve_preview_stream function in controller.py handles /preview?provider=…&item_id=…, returning short AAC audio snippets (typically ~30 seconds) for tracks without requiring full library access.
Server Information (GET /info)
Returns server version, uptime seconds, and lists of connected players and providers. This endpoint does not require authentication.
SendSpin Proxy
An authenticated WebSocket proxy to the internal SendSpin server (used by certain players) is handled by sendspin_proxy.py, providing relay functionality for specific player protocols.
Authentication Implementation
Authentication is managed by the AuthenticationManager with tokens stored hashed in SQLite. The auth_middleware.py validates tokens on every protected request and supports the builtin provider (username/password) and Home Assistant OAuth integration via auth_providers.py.
- Setup Mode: Until an admin exists, the server restricts access to setup endpoints only.
- Token Format: JWT-style bearer tokens returned as
Authorization: Bearer <token>in the HTTP header. - Role-Based Access Control: Commands declare required roles, which are validated before handler execution.
Practical Code Examples
Obtaining an Authentication Token
curl -X POST http://localhost:8095/auth/login \
-H "Content-Type: application/json" \
-d '{"provider_id":"builtin","credentials":{"username":"admin","password":"mySecretPwd"}}'
Response:
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"user": { "user_id": "c4e3…", "username": "admin", "role": "admin" }
}
Executing a JSON-RPC Command
curl -X POST http://localhost:8095/api \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"command": "media_library.search",
"args": { "search_term": "Beatles", "media_type": "track" },
"message_id": "req-001"
}'
Retrieving Server Information (No Auth Required)
curl http://localhost:8095/info
Response:
{
"version": "2026.1.0",
"uptime": 34212,
"players": [ … ],
"providers": [ … ]
}
WebSocket Client Implementation
import websockets
import json
import asyncio
async def demo():
async with websockets.connect('ws://localhost:8095/ws') as ws:
# Send JSON-RPC command
await ws.send(json.dumps({
"command": "player.play",
"args": {"player_id": "my_player"},
"message_id": "ws-001"
}))
reply = await ws.recv()
print('Received:', reply)
asyncio.run(demo())
Streaming Audio Previews
curl http://localhost:8095/preview?provider=spotify&item_id=track-123 \
-o preview.aac
Summary
- The WebserverController in
music_assistant/controllers/webserver/controller.pymanages all HTTP and WebSocket traffic for the Music Assistant server. - JSON-RPC commands are dispatched via POST
/apito handlers registered inself.mass.command_handlers, with role validation performed by the controller. - WebSocket connections at
/wsprovide real-time bidirectional communication throughWebsocketClientHandler, automatically pushing events likeplayer_state_updated. - Authentication uses bearer tokens validated by middleware in
helpers/auth_middleware.pyand managed byauth.py, with support for builtin and OAuth providers. - Setup mode restricts access to
/setupuntil an admin user is created via the_handle_setupendpoint. - Preview streams and server info endpoints provide additional functionality, with
/previewserving short AAC clips viaserve_preview_streamand/infoproviding anonymous server status.
Frequently Asked Questions
How do I authenticate with the Music Assistant API?
Send a POST request to /auth/login with a JSON body containing provider_id (e.g., "builtin" ) and credentials object with username and password. The response includes a bearer token that must be included as Authorization: Bearer <token> in subsequent requests to protected endpoints.
What is the difference between the HTTP API and WebSocket API?
The HTTP API at /api handles stateless JSON-RPC commands using the _handle_jsonrpc_api_command method, while the WebSocket endpoint /ws maintains persistent connections managed by WebsocketClientHandler for real-time bidirectional communication, automatically pushing events like player state changes without requiring client polling.
Where can I find the list of available API commands?
The server dynamically generates OpenAPI specifications and a complete command list with schemas, accessible at /api-docs/commands.json and /api-docs/*. These are generated on-the-fly by api_docs.py from the registered command handlers in self.mass.command_handlers.
How does the initial setup process work via the API?
When the server has no admin user, it enters setup mode and redirects all requests to /setup. You must send a POST request to /setup to create the first admin account, which returns an initial authentication token. After this setup completes, the server exits setup mode and normal API access is permitted with the issued token.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →