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, the API gives you complete control.
The API documentation is automatically generated and available at http://YOUR_MA_SERVER_IP:8095/api-docs
Before you start
Section titled “Before you start”- Every request needs an authentication token. Create a long lived access token in the MA UI via Settings → Profile and send it in the
Authorization: Bearer <token>header (the examples below show a truncated token) - The
message_idis any string of your choosing; it is echoed back in the response so you can match responses to requests - Each example below is shown in two forms: a
curlcommand you can run from any terminal, and the equivalent Home Assistant rest_command YAML for use in automations
Examples
Section titled “Examples”Play a random track from a playlist
Save current queue as a playlist
Get All Available Player Settings
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "config/players/get", "args": { "player_id": "RINCON_48A6B820191201400" }}'rest_command: ma_get_player_settings: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "config/players/get", "args": { "player_id": "{{ player_id }}" } } content_type: 'application/json; charset=utf-8'Set One or More Player Settings
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "config/players/save", "args": { "player_id": "RINCON_48A6B820191201400", "values": { "airplay_mode": true } }}'rest_command: ma_set_player_settings: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "config/players/save", "args": { "player_id": "b8:27:eb:8a:b8:8e", "values": { "crossfade": true } } } content_type: 'application/json; charset=utf-8'Add Item to Favorites
item needs to be a URI or share URL
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "music/favorites/add_item", "args": { "item": "spotify://track/1234567" }}'Get Album Tracks
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "music/albums/album_tracks", "args": { "item_id": "1", "provider_instance_id_or_domain": "library", "in_library_only": true }}'rest_command: ma_album_tracks: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "music/albums/album_tracks", "args": { "item_id": "{{ item_id }}", "provider_instance_id_or_domain": "{{ provider_instance_id_or_domain }}", "in_library_only": "{{ in_library_only }}" } } content_type: 'application/json; charset=utf-8'Get Full Item Details (By Providing a URI)
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "music/item_by_uri", "args": { "uri": "spotify://track/1234" }}'Get Recently Played Items
limit and media_types are optional
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "music/recently_played_items", "args": { "limit": 10, "media_types": ["track", "album"] }}'Get In Progress Items (Audiobooks, Podcast Episodes)
Return a list of the Audiobooks and PodcastEpisodes that are in progress. limit is optional
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "music/in_progress_items", "args": { "limit": 10 }}'Starting Sync
Start running the sync of (all or selected) musicproviders. media_types: only sync these media types. None for all. providers: only sync these provider instances. None for all.
curl --location 'http://192.168.1.1:8095/api' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR......I' \--data '{ "message_id": "1", "command": "music/sync", "args": { "media_types": ["track", "album"], "providers": ["filesystem--1234"] }}'Refresh Playlist
rest_command: ma_refresh_playlist: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "music/playlists/playlist_tracks", "args": { "item_id": "1234", "provider_instance_or_domain": "builtin", "force_refresh": true } } content_type: 'application/json; charset=utf-8'Change crossfade state of a player
player_id can be found at the top of the individual player settings
rest_command: ma_set_player_settings: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "config/players/save", "args": { "player_id": "b8:27:eb:8a:b8:8e", "values": { "crossfade": true } } } content_type: 'application/json; charset=utf-8'Get all items in the queue
queue_id will be the same as the player_id unless the player is grouped. To confirm create a rest_command that calls player_queues/all and review the information returned. The limit defaults to 500 if you omit it. You are cautioned to not set a value greater than 500 to avoid breaking your system. The practical limit will depend on the resources available on your host. offset can also be omitted.
rest_command: ma_get_full_queue: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "player_queues/items", "args": { "queue_id": "b8:27:eb:8a:b8:8e", "limit": 500, "offset": 0 } } content_type: 'application/json; charset=utf-8'Play latest podcast episode
Pass latest or newest as the start_item parameter.
rest_command: ma_podcast_latest: url: http://192.168.1.58:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "player_queues/play_media", "args": { "queue_id": "115ee854-3ac5-38c1-277d-7bdb4f3c126d", "media": "library://podcast/2", "start_item": "latest" } } content_type: 'application/json; charset=utf-8'Play from a specific playlist item or podcast episode
Pass a 3 character or more string as the start_item. For example, passing Mirrors will find the first item in the playlist with that word (case insensitive) within and then play the playlist from that point.
rest_command: ma_playlist_specific: url: http://192.168.1.58:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "player_queues/play_media", "args": { "queue_id": "115ee854-3ac5-38c1-277d-7bdb4f3c126d", "media": "library://playlist/13", "start_item": "Mirrors" } } content_type: 'application/json; charset=utf-8'Refresh a podcast and play the latest episode
Firstly, note that this only works with RSS based feeds such as podcastfeed (RSS), iTunes Podcasts, gPodder and Overcast. For others, they may already always return the latest episode on request. For yet others, it may not be possible to update the list more frequently due to caching of the episode list (e.g. Deezer, iHeartradio, Spotify, Storytel)
Considerations:
- The token has to belong to an admin user.
- The
provider_instance_idis shown in the provider’s settings. - Nothing happens if podcast sync is turned off for that provider.
- With many subscribed podcasts, 10 seconds may not be long enough for the sync to reach the one you want.
rest_command: ma_sync_podcast: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "music/sync", "args": { "media_types": ["podcast"], "providers": ["{{ provider_instance_id }}"] } } content_type: 'application/json; charset=utf-8'
ma_play_podcast_latest: url: http://192.168.1.1:8095/api method: POST headers: accept: "application/json, text/html" authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR......I" payload: > { "message_id": "1", "command": "player_queues/play_media", "args": { "queue_id": "{{ queue_id }}", "media": "{{ media }}", "start_item": "latest" } } content_type: 'application/json; charset=utf-8'
script: ma_play_latest_podcast_fresh: alias: Sync podcast and play latest episode fields: queue_id: description: MA queue id (same as the player_id unless the player is grouped) required: true provider_instance_id: description: Provider instance to sync, e.g. podcastfeed--abc123 required: true podcast_uri: description: MA URI of the podcast, e.g. library://podcast/2 required: true sequence: - action: rest_command.ma_sync_podcast data: provider_instance_id: "{{ provider_instance_id }}" - delay: "00:00:10" - action: rest_command.ma_play_podcast_latest data: queue_id: "{{ queue_id }}" media: "{{ podcast_uri }}"Example call:
action: script.ma_play_latest_podcast_freshdata: queue_id: 115ee854-3ac5-38c1-277d-7bdb4f3c126d provider_instance_id: podcastfeed--abc123 podcast_uri: library://podcast/2This website uses privacy-first analytics to help us improve the site. You can view all data in our public dashboard.