Muro Box Open API — User Guide
Version 1.0 (2026-08-16)
The Muro Box Open API lets third-party services and automation tools (for example Home Assistant, IFTTT, or your own scripts) control your Muro Box — play songs and playlists, stop playback, adjust settings, and search the song/playlist catalog — using an API key tied to your Muro Box account.
The API is designed around playback on your Muro Box: it never returns MIDI files or download URLs. All playback happens on the box.
1. Quick Start
- Create an API key — Open the Muro Box App → Settings → API Keys → Add. Give the key a name and confirm. The full key is displayed only once, right after creation — copy it and store it somewhere safe (you cannot retrieve it later).
- Find your device serial number (
device_sn) — shown in the App’s device settings page for your paired Muro Box. - Call the API — send a
POSTrequest with:- URL:
https://api.murobox.com/muro_api/v1/...(see §3) - Header:
api-key: <your key> - Header:
Content-Type: application/json - JSON body with the required fields
- URL:
Download the Postman Collection and import it with one click to start testing.
Example (play a song):
curl -X POST https://api.murobox.com/muro_api/v1/devices/play_song/ \
-H "api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"device_sn": "YOUR_BOX_SN", "song_id": "YOUR_SONG_ID"}'
Example response:
{"status": true, "message": "scuuess"}
Always parse the status field to decide success — the message text is informational only.
2. Authentication
| Item | Value |
|---|---|
| Header | api-key |
| Value | your API key (32 hexadecimal characters, shown once at creation) |
| Belongs to | your Muro Box account; it can control the boxes paired to that account |
- Keys are stored on the server only as a SHA-256 fingerprint; the plain key is never retrievable after creation. Keep it secret — anyone with the key can control your box.
- You can create multiple keys (e.g. one per service) and rename/delete them from the App (Settings → API Keys).
Rate limiting
- 60 requests per minute per API key. When exceeded you receive HTTP
429with aRetry-Afterheader. Design your automation with this budget in mind.
3. Base URL & Endpoints
Base URL: https://api.murobox.com
All endpoints use POST + JSON body.
| # | Endpoint | Purpose | Key fields |
|---|---|---|---|
| 1 | /muro_api/v1/devices/play_song/ |
Play a single song | device_sn, song_id |
| 2 | /muro_api/v1/devices/play_playlist/ |
Play a playlist | device_sn, playlist_id |
| 3 | /muro_api/v1/devices/stop_playing/ |
Stop playback | device_sn |
| 4 | /muro_api/v1/devices/device_settings/ |
Read/update settings | device_sn + at least one setting |
| 5 | /muro_api/v1/search/songs/ |
Search songs | keyword, optional page, lang |
| 6 | /muro_api/v1/search/packages/ |
Search playlists | keyword, optional page |
4. Endpoint Details
4.1 Play a Song — POST /muro_api/v1/devices/play_song/
{
"device_sn": "YOUR_BOX_SN",
"song_id": "YOUR_SONG_ID"
}
| Field | Type | Required | Description |
|---|---|---|---|
device_sn |
string | yes | your Muro Box serial number |
song_id |
string | yes | song identifier (see §6) |
Success: 200 with {"status": true, "message": "scuuess"}. Errors: 400 missing field · 404 device or song not found · 403 not a pairing user or no permission · 429 rate limited.
4.2 Play a Playlist — POST /muro_api/v1/devices/play_playlist/
{
"device_sn": "YOUR_BOX_SN",
"playlist_id": "YOUR_PLAYLIST_ID"
}
| Field | Type | Required | Description |
|---|---|---|---|
device_sn |
string | yes | your Muro Box serial number |
playlist_id |
string | yes | playlist identifier (see §6) |
Permission filtering: songs in the playlist are filtered by your account’s permissions before being sent to the box, so a public playlist that contains private songs will only deliver the songs you are allowed to play:
- Public playlists → public songs + your own songs
- Your private playlists → your songs + other users’ public songs
- Device / copyright / offline playlists → require the box to be bound to you
Success: 200 with {"status": true, "message": "scuuess"}. Errors: 400 missing field · 404 device or playlist not found · 403 not a pairing user or no permission · 422 no playable song in this playlist (including empty playlists) · 429 rate limited.
4.3 Stop Playing — POST /muro_api/v1/devices/stop_playing/
{ "device_sn": "YOUR_BOX_SN" }
Success: 200 with {"status": true, "message": "scuuess"}. Errors: 400 · 404 · 403 · 429.
4.4 Device Settings — POST /muro_api/v1/devices/device_settings/
{
"device_sn": "YOUR_BOX_SN",
"motorSpeed": 85,
"plRandom": false,
"plMaxTime": 10800,
"midiPortEnabled": true,
"bleMidiEnabled": true
}
| Field | Type | Range / Values | Description |
|---|---|---|---|
device_sn |
string | — | required; your Muro Box serial number |
motorSpeed |
integer | 50–120 (clamped) | motor speed percentage |
plRandom |
boolean | true / false (also accepts "true"/"false", 1/0) |
shuffle play |
plMaxTime |
integer | 0–2147483647 seconds (clamped) | maximum playback time |
midiPortEnabled |
boolean | true / false |
MIDI output on/off |
bleMidiEnabled |
boolean | true / false |
BLE MIDI on/off |
Notes:
- At least one setting field is required (a call with only
device_snreturns400). - Only the automation-friendly subset above is accepted; other settings (display name, DST, motor fine-tuning, power-on autoplay, …) are ignored by this endpoint.
Success: 200 with the updated subset:
{
"status": true,
"data": {
"motorSpeed": 85,
"plRandom": false,
"plMaxTime": 10800,
"midiPortEnabled": true,
"bleMidiEnabled": true
}
}
Errors: 400 missing device_sn / invalid field / nothing to update · 404 · 403 · 429.
4.5 Search Songs — POST /muro_api/v1/search/songs/
{
"keyword": "your keyword",
"page": 1,
"lang": "en"
}
| Field | Type | Required | Description |
|---|---|---|---|
keyword |
string | yes | search keyword |
page |
integer | no (default 1) | page number, 10 results per page; out-of-range pages return an empty list |
lang |
string | no | preferred display_name language, e.g. en, zh-hant, zh-hans, ja, ko, de; omit for the default name |
Success: 200
{
"status": true,
"data": [
{
"song_id": "8bad5d17bccc4b7b9fca727ce2390983",
"display_name": "Your Song",
"owner_name": "Artist Name",
"code": "GI20",
"visibility": "public"
}
],
"page": 1,
"total_page": 3
}
Notes:
- No MIDI file URL is ever returned — playback must go through
play_song. - There is no default melody-code filtering — filter by the returned
codefield yourself if your automation needs a specific melody type. - Visibility is returned as the three-state
visibilityfield (public/unlisted/private). Legacy booleanis_publicis no longer included (removed 2026-08-17).
Errors: 400 missing keyword / invalid page · 429.
4.6 Search Playlists — POST /muro_api/v1/search/packages/
{
"keyword": "playlist keyword",
"page": 1
}
| Field | Type | Required | Description |
|---|---|---|---|
keyword |
string | yes | search keyword |
page |
integer | no (default 1) | page number, 10 results per page; out-of-range pages return an empty list |
Success: 200
{
"status": true,
"data": [
{
"package_id": "485029fa2d3e4fa9ae5db030079c95df",
"package_name": "My Playlist",
"owner_name": "Owner",
"visibility": "public",
"songs_count": 12
}
],
"page": 1,
"total_page": 2
}
Notes:
- Returns metadata only (no song list inside the playlist).
- Visibility is returned as the three-state
visibilityfield. Legacyis_publishandis_offlineare no longer included (removed 2026-08-17; offline playlists are bound to the music box virtual account). songs_countis the number of songs playable by your account (same rule as the App).- Playback must go through
play_playlist.
Errors: 400 missing keyword / invalid page · 429.
5. Error Handling
All failures return JSON in the same shape:
{ "status": false, "message": "..." }
| HTTP | Meaning | How to handle |
|---|---|---|
| 400 | missing or invalid field | check the request body against §4 |
| 404 | device / song / playlist not found | verify device_sn, song_id, playlist_id |
| 403 | not a pairing user, or no permission | the key’s account must be paired with the box; for playlists, check permission filtering (§4.2) |
| 422 | no playable song in this playlist | the playlist is empty or contains no songs your account can play |
| 429 | rate limit exceeded | respect the Retry-After header; budget 60 requests/min/key |
6. Obtaining song_id and playlist_id
- From the App (recommended):
song_id— open the player for a song →⋯menu → Copy song ID.playlist_id— open a playlist detail page →⋯menu → Copy playlist ID (available for all playlist types, including offline playlists).
- From the API: use the Search endpoints (§4.5 / §4.6) to look up identifiers by keyword.
7. Postman Collection
A ready-to-import Postman collection is available at open-api-postman-collection-prod.json:
- Postman → Import → select the file.
- In the collection variables, fill in
api_keyanddevice_sn. - Set
song_id/playlist_idas needed (from §6). base_urlalready points to production (https://api.murobox.com).
8. Security & Operational Notes
- Treat your API key like a password — it is shown once and cannot be recovered.
- Keys are rate-limited per key (60/min) and audited (the server logs successful calls); revoke keys you no longer use from the App.
- The API only triggers playback on boxes paired to your account — it cannot be used to download songs or MIDI files.
- If you plan heavy automation, stay within the per-key rate limit or create multiple keys for independent budgets.
If you encounter any usage issues or have requests for new features, please contact us via email at: support@tevofy.com
Muro Box Team