Music Assistant API

Version {VERSION}

Welcome

Music Assistant provides a powerful API to control your music library, manage players, and stream audio. Whether you're building a custom interface, integrating with home automation, or creating a music app, our API gives you complete control.

This documentation will help you get started quickly with examples and best practices.

API Documentation

Explore the Music Assistant API with our documentation tools:

📚 Commands Reference

Complete list of all available commands with parameters, descriptions, working curl examples, and interactive testing

View Commands

📊 Schemas Reference

All data models and types with their properties, descriptions, and relationships

View Schemas

📘 Swagger UI

Interactive API explorer with OpenAPI specification and "Try it out" functionality

Open Swagger UI

Quick Start

WebSocket API (Recommended)

The WebSocket API provides real-time bidirectional communication and automatic event notifications. Perfect for applications that need live updates.

Note: WebSocket messages require a message_id field to match requests with responses. This allows multiple concurrent requests over the same connection.
# Connect to WebSocket ws://{SERVER_HOST}/ws # Step 1: Authenticate (REQUIRED as first command) { "message_id": "auth-123", "command": "auth", "args": { "token": "your_access_token" } } # Auth response { "message_id": "auth-123", "result": { "authenticated": true, "user": {...user info...} } } # Step 2: Send commands (message_id is REQUIRED) { "message_id": "unique-id-123", "command": "players/all", "args": {} } # Receive response { "message_id": "unique-id-123", "result": [...player data...] } # Receive automatic events { "event": "player_updated", "data": {...updated player...} }

HTTP API (RPC)

The HTTP API provides a simple RPC-like interface for executing commands. This allows you to call the same commands available via WebSocket over a simple HTTP POST endpoint. Perfect for one-off commands without needing real-time updates.

Note: The message_id field is optional for HTTP requests since each HTTP request is isolated. The response returns the command result directly.
# Get all players (requires authentication) curl -X POST {BASE_URL}/api \ -H "Authorization: Bearer your_access_token" \ -H "Content-Type: application/json" \ -d '{ "command": "players/all", "args": {} }' # Play media on a player (requires authentication) curl -X POST {BASE_URL}/api \ -H "Authorization: Bearer your_access_token" \ -H "Content-Type: application/json" \ -d '{ "command": "player_queues/play_media", "args": { "queue_id": "player_123", "media": ["library://track/456"] } }' # Get server info (no authentication required) curl {BASE_URL}/info

WebSocket Events

When connected via WebSocket, you automatically receive real-time event notifications for all state changes. No polling required!

🔊 Player Events

  • player_added - New player discovered
  • player_updated - Player state changed
  • player_removed - Player disconnected
  • player_config_updated - Settings changed

🎵 Queue Events

  • queue_added - New queue created
  • queue_updated - Queue state changed
  • queue_items_updated - Content changed
  • queue_time_updated - Playback position updated

📚 Library Events

  • media_item_added - New media added
  • media_item_updated - Metadata updated
  • media_item_deleted - Media removed
  • media_item_played - Playback started

⚙️ System Events

  • providers_updated - Provider status changed
  • sync_tasks_updated - Sync progress updated
  • application_shutdown - Server shutting down

Client Libraries

Don't want to implement the API from scratch? Use our official client libraries:

Python Client

Official Python client library with full type hints and async support:

# Install pip install music-assistant-client # Usage from music_assistant_client import MusicAssistantClient async with MusicAssistantClient("{SERVER_HOST}") as client: # Get all players players = await client.get_players() # Play media await client.play_media( queue_id="player_123", media=["library://track/456"] )

TypeScript/JavaScript

Reference implementation in the Music Assistant frontend:

// Example from frontend code import { MusicAssistantApi } from './api'; const api = new MusicAssistantApi('{SERVER_HOST}'); // Connect await api.connect(); // Subscribe to events api.subscribe('player_updated', (event) => { console.log('Player updated:', event.data); }); // Call commands const players = await api.getPlayers();
Coming Soon: A dedicated TypeScript client library is in development! For now, you can use the frontend's API implementation as a reference.

Best Practices

✓ Do:

  • Use WebSocket API for real-time applications
  • Handle connection drops and reconnect automatically
  • Subscribe to relevant events instead of polling
  • Use unique message IDs for WebSocket commands
  • Implement proper error handling

✗ Don't:

  • Poll the REST API frequently for updates (use WebSocket events instead)
  • Send commands without waiting for previous responses
  • Ignore error responses
  • Hardcode server URLs (make them configurable)

Authentication

As of API Schema Version 28, authentication is now mandatory for all API access (except when accessed through Home Assistant Ingress).

Authentication Overview

Music Assistant supports the following authentication methods:

  • Username/Password - Built-in authentication provider
  • Home Assistant OAuth - OAuth flow for HA users (optional)
  • Bearer Tokens - Token-based authentication for HTTP and WebSocket

HTTP Authentication Endpoints

The following HTTP endpoints are available for authentication (no auth required):

# Get server info (includes onboard_done status) GET {BASE_URL}/info # Get available login providers GET {BASE_URL}/auth/providers # Login with credentials (built-in provider is default) POST {BASE_URL}/auth/login { "credentials": { "username": "your_username", "password": "your_password" } } # Or specify a different provider (e.g., Home Assistant OAuth) POST {BASE_URL}/auth/login { "provider_id": "homeassistant", "credentials": {...provider-specific...} } # Response includes access token { "success": true, "token": "your_access_token", "user": { ...user info... } } # First-time setup (only if no users exist) POST {BASE_URL}/setup { "username": "admin", "password": "secure_password" }

Using Bearer Tokens

Once you have an access token, include it in all HTTP requests:

curl -X POST {BASE_URL}/api \ -H "Authorization: Bearer your_access_token" \ -H "Content-Type: application/json" \ -d '{ "command": "players/all", "args": {} }'

WebSocket Authentication

After establishing a WebSocket connection, you must send an auth command as the first message:

# Send auth command immediately after connection { "message_id": "auth-123", "command": "auth", "args": { "token": "your_access_token" } } # Response on success { "message_id": "auth-123", "result": { "authenticated": true, "user": { "user_id": "...", "username": "your_username", "role": "admin" } } }
Token Types:
  • Short-lived tokens: Created automatically during login. Expire after 30 days of inactivity but auto-renew on each use (sliding expiration window). Perfect for user sessions.
  • Long-lived tokens: Created via auth/token/create command. Expire after 10 years with no auto-renewal. Intended for external integrations (Home Assistant, mobile apps, API access).
Use the auth/tokens and auth/token/create WebSocket commands to manage your tokens.

User Management Commands

The following WebSocket commands are available for authentication management:

  • auth/users - List all users (admin only)
  • auth/user - Get user by ID (admin only)
  • auth/user/create - Create a new user (admin only)
  • auth/user/update - Update user profile, password, or role (admin for other users)
  • auth/user/enable - Enable user (admin only)
  • auth/user/disable - Disable user (admin only)
  • auth/user/delete - Delete user (admin only)
  • auth/tokens - List your tokens
  • auth/token/create - Create a new long-lived token
  • auth/token/revoke - Revoke a token

See the Commands Reference for detailed documentation of all auth commands.

Remote Access (WebRTC)

Music Assistant supports remote access via WebRTC, enabling you to connect to your Music Assistant instance from anywhere without port forwarding or VPN configuration.

How It Works

Remote access uses WebRTC technology to establish a secure, peer-to-peer connection between your remote client (PWA) and your local Music Assistant server:

  • WebRTC Data Channel: Establishes encrypted connection through NAT/firewalls
  • Signaling Server: Cloud-based server coordinates connection setup
  • Remote ID: Unique identifier (format: MA-XXXX-XXXX) to connect to your instance
  • API Bridge: Remote commands work identically to local WebSocket API

Getting Your Remote ID

Use the remote_access/info WebSocket command to get your Remote ID and connection status:

# Get remote access information { "message_id": "remote-123", "command": "remote_access/info", "args": {} } # Response { "message_id": "remote-123", "result": { "enabled": true, "connected": true, "remote_id": "MA-K7G3-P2M4", "signaling_url": "wss://signaling.music-assistant.io/ws" } }

Connecting Remotely

To connect from outside your local network:

  1. Get your Remote ID from the remote_access/info command
  2. Open the Music Assistant PWA from any device (https://app.music-assistant.io)
  3. Enter your Remote ID when prompted
  4. Authenticate with your username and password (or OAuth)
  5. Full API access over encrypted WebRTC connection
Availability Notice: Remote access is currently only available to users who:
  • Have the Home Assistant integration configured
  • Possess an active Home Assistant Cloud subscription
This limitation exists because remote access relies on cloud-based STUN/TURN servers provided by Home Assistant Cloud to establish WebRTC connections through NAT/firewalls. These servers are expensive to host and are made available as part of the Home Assistant Cloud service.

Security

Remote access maintains the same security standards as local access:

  • End-to-end encryption: All data encrypted via WebRTC (DTLS/SRTP)
  • Authentication required: Same login and token system as local access
  • No data inspection: Signaling server cannot decrypt your commands or data
  • Role-based access: Admin and user permissions work identically