Muro Box Open API — 사용자 안내서
버전 1.0 (2026-08-16)
Muro Box Open API를 사용하면 제3자 서비스 및 자동화 도구(예: Home Assistant, IFTTT 또는 사용자가 직접 작성한 스크립트)가 Muro Box 계정에 연결된 API 키를 통해 Muro Box를 제어하여 곡 및 재생목록을 재생하고, 재생을 중지하며, 설정을 조정하고, 곡/재생목록 카탈로그를 검색할 수 있습니다.
이 API는 Muro Box에서의 재생을 중심으로 설계되었습니다. MIDI 파일이나 다운로드 URL은 반환하지 않으며, 모든 재생은 해당 기기에서 이루어집니다.
1. 빠른 시작
- API 키 생성 — Muro Box App을 열고 설정 → API 키 → 추가를 선택합니다. 키 이름을 지정한 후 확인합니다. 전체 키는 생성 직후에 한 번만 표시되므로, 복사하여 안전한 곳에 보관해야 합니다(추후 다시 확인할 수 없습니다).
- 기기 일련번호 찾기 (
device_sn) — 앱에서 페어링된 Muro Box의 기기 설정 페이지에 표시됩니다. - API 호출 — 다음을 포함하여
POST요청을 전송합니다:- URL:
https://api.murobox.com/muro_api/v1/...(§3 참조) - 헤더:
api-key: <your key> - 헤더:
Content-Type: application/json - 필수 필드가 포함된 JSON 본문
- URL:
Postman Collection을 다운로드한 뒤 클릭 한 번으로 가져와 테스트를 시작하십시오.
예시(곡 재생):
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"}'
응답 예시:
{"status": true, "message": "scuuess"}
성공 여부를 판단하려면 항상 status 필드를 파싱해야 합니다. message 텍스트는 참고용 정보일 뿐입니다.
2. 인증
| 항목 | 값 |
|---|---|
| 헤더 | api-key |
| 값 | 사용자의 API 키(32자리 16진수 문자, 생성 시 한 번만 표시) |
| 귀속 대상 | 사용자의 Muro Box 계정에 속하며, 해당 계정에 페어링된 박스를 제어할 수 있습니다 |
- 키는 서버에 SHA-256 지문으로만 저장되며, 생성 후에는 평문 키를 다시 조회할 수 없습니다. 이 키를 비밀로 유지하십시오 — 키를 보유한 사람은 누구나 귀하의 Muro Box를 제어할 수 있습니다.
- 여러 개의 키를 생성할 수 있으며(예: 서비스별로 하나씩), Muro Box App(설정 → API 키)에서 각 키의 이름 변경/삭제를 수행할 수 있습니다.
속도 제한
- API 키당 분당 60건의 요청이 허용됩니다. 이 한도를 초과하면 HTTP
429응답과Retry-After헤더를 받게 됩니다. 자동화를 설계할 때에는 이 한도를 고려하십시오.
3. Base URL 및 엔드포인트
Base URL: https://api.murobox.com
모든 엔드포인트는 POST + JSON 본문을 사용합니다.
| # | 엔드포인트 | 목적 | 주요 필드 |
|---|---|---|---|
| 1 | /muro_api/v1/devices/play_song/ |
단일 곡 재생 | device_sn, song_id |
| 2 | /muro_api/v1/devices/play_playlist/ |
플레이리스트 재생 | device_sn, playlist_id |
| 3 | /muro_api/v1/devices/stop_playing/ |
재생 중지 | device_sn |
| 4 | /muro_api/v1/devices/device_settings/ |
설정 읽기/업데이트 | device_sn + 설정 하나 이상 |
| 5 | /muro_api/v1/search/songs/ |
곡 검색 | keyword, 선택 사항 page, lang |
| 6 | /muro_api/v1/search/packages/ |
플레이리스트 검색 | keyword, 선택 사항 page |
4. 엔드포인트 세부 정보
4.1 곡 재생 — POST /muro_api/v1/devices/play_song/
{
"device_sn": "YOUR_BOX_SN",
"song_id": "YOUR_SONG_ID"
}
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
device_sn |
문자열 | 예 | 사용자의 Muro Box 일련번호 |
song_id |
문자열 | 예 | 곡 식별자(§6 참조) |
성공: 200, {"status": true, "message": "scuuess"} 포함. 오류: 400 필드 누락 · 404 기기 또는 곡을 찾을 수 없음 · 403 페어링 사용자가 아니거나 권한이 없음 · 429 요청 한도 초과.
4.2 재생 목록 재생 — POST /muro_api/v1/devices/play_playlist/
{
"device_sn": "YOUR_BOX_SN",
"playlist_id": "YOUR_PLAYLIST_ID"
}
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
device_sn |
문자열 | 예 | Muro Box 일련번호 |
playlist_id |
문자열 | 예 | 재생목록 식별자(§6 참조) |
권한 필터링: 재생목록의 곡은 Muro Box로 전송되기 전에 사용자 계정의 권한에 따라 필터링되므로, 비공개 곡이 포함된 공개 재생목록에서는 재생 권한이 있는 곡만 전달됩니다:
- 공개 재생목록 → 공개 곡 + 본인 곡
- 내 비공개 플레이리스트 → 내 곡 + 다른 사용자가 공개한 곡
- 기기 / 저작권 / 오프라인 플레이리스트 → 박스가 본인에게 연결되어 있어야 함
성공: 200 및 {"status": true, "message": "scuuess"}. 오류: 400 필드 누락 · 404 기기 또는 재생 목록을 찾을 수 없음 · 403 페어링 사용자가 아니거나 권한이 없음 · 422 이 재생 목록에 재생 가능한 곡이 없음 (빈 재생 목록 포함) · 429 요청 한도 초과.
4.3 재생 중지 — POST /muro_api/v1/devices/stop_playing/
{ "device_sn": "YOUR_BOX_SN" }
성공: 200 및 {"status": true, "message": "scuuess"}. 오류: 400 · 404 · 403 · 429.
4.4 기기 설정 — POST /muro_api/v1/devices/device_settings/
{
"device_sn": "YOUR_BOX_SN",
"motorSpeed": 85,
"plRandom": false,
"plMaxTime": 10800,
"midiPortEnabled": true,
"bleMidiEnabled": true
}
| 필드 | 유형 | 범위 / 값 | 설명 |
|---|---|---|---|
device_sn |
문자열 | — | 필수; Muro Box 일련번호 |
motorSpeed |
정수 | 50–120 (제한됨) | 모터 속도 백분율 |
plRandom |
불리언 | true / false (또한 지원"true"/"false", 1/0) |
셔플 재생 |
plMaxTime |
정수 | 0–2147483647초 (클램프됨) | 최대 재생 시간 |
midiPortEnabled |
불리언 | true / false |
MIDI 출력 켜기/끄기 |
bleMidiEnabled |
불리언 | true / false |
BLE MIDI 켜기/끄기 |
참고 사항:
- 설정 필드를 하나 이상 지정해야 합니다(
device_sn만 포함한 호출은400을(를) 반환합니다). - 이 엔드포인트는 위의 자동화에 적합한 하위 집합만 허용하며, 그 밖의 설정(표시 이름, 일광 절약 시간(DST), 모터 미세 조정, 전원 켜짐 시 자동 재생 등)은 무시합니다.
성공: 200(업데이트된 하위 집합 포함):
{
"status": true,
"data": {
"motorSpeed": 85,
"plRandom": false,
"plMaxTime": 10800,
"midiPortEnabled": true,
"bleMidiEnabled": true
}
}
오류: 400 — 누락된 device_sn / 유효하지 않은 필드 / 업데이트할 항목 없음 · 404 · 403 · 429.
4.5 곡 검색 — POST /muro_api/v1/search/songs/
{
"keyword": "your keyword",
"page": 1,
"lang": "en"
}
| 필드 | 유형 | 필수 여부 | 설명 |
|---|---|---|---|
keyword |
문자열 | 예 | 검색 키워드 |
page |
정수 | 아니오 (기본값 1) | 페이지 번호. 페이지당 결과는 10건이며, 범위를 벗어난 페이지는 빈 목록을 반환합니다. |
lang |
문자열 | 아니오 | 선호하는 display_name 언어(예: en, zh-hant, zh-hans, ja, ko, de)이며, 기본 이름을 사용하려면 생략하십시오 |
성공: 200
{
"status": true,
"data": [
{
"song_id": "8bad5d17bccc4b7b9fca727ce2390983",
"display_name": "Your Song",
"owner_name": "Artist Name",
"code": "GI20",
"visibility": "public"
}
],
"page": 1,
"total_page": 3
}
참고:
- MIDI 파일 URL은 절대 반환되지 않습니다 — 재생은 반드시
play_song를 통해야 합니다. - 기본 멜로디 코드 필터링은 제공되지 않습니다. 자동화 작업에서 특정 멜로디 유형이 필요하다면 반환되는
code필드를 기준으로 직접 필터링하십시오. - 공개 범위는 세 가지 상태를 갖는
visibility필드로 반환됩니다(public/unlisted/private). 레거시 불리언is_public필드는 더 이상 포함되지 않습니다(2026-08-17 제거).
오류: 400 누락 keyword / 유효하지 않은 page · 429.
4.6 재생 목록 검색 — POST /muro_api/v1/search/packages/
{
"keyword": "playlist keyword",
"page": 1
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
keyword |
문자열 | 예 | 검색 키워드 |
page |
정수 | no (기본값 1) | 페이지 번호, 페이지당 결과 10개; 범위를 벗어난 페이지는 빈 목록을 반환합니다 |
성공: 200
{
"status": true,
"data": [
{
"package_id": "485029fa2d3e4fa9ae5db030079c95df",
"package_name": "My Playlist",
"owner_name": "Owner",
"visibility": "public",
"songs_count": 12
}
],
"page": 1,
"total_page": 2
}
참고:
- 메타데이터만 반환합니다(플레이리스트 내부의 곡 목록은 포함하지 않습니다).
- 공개 범위는 세 가지 상태를 나타내는
visibility필드로 반환됩니다. 기존의is_publish및is_offline필드는 더 이상 포함되지 않습니다(2026-08-17에 제거되었으며, 오프라인 플레이리스트는 오르골 가상 계정에 연결됩니다). songs_count는 계정으로 재생할 수 있는 곡 수입니다(앱과 동일한 규칙).- 재생은 반드시
play_playlist을 통해야 합니다.
오류: 400 keyword 누락 / 유효하지 않은 page · 429.
5. 오류 처리
모든 실패 응답은 동일한 구조의 JSON을 반환합니다:
{ "status": false, "message": "..." }
| HTTP | 의미 | 처리 방법 |
|---|---|---|
| 400 | 필드가 누락되었거나 유효하지 않음 | §4를 기준으로 요청 본문을 확인하십시오 |
| 404 | 기기 / 곡 / 플레이리스트를 찾을 수 없음 | 다음을 확인하십시오: device_sn, song_id, playlist_id |
| 403 | 페어링 사용자가 아니거나 권한이 없음 | 키의 계정은 기기와 페어링되어 있어야 하며, 재생 목록의 경우 권한 필터링(§4.2)을 확인하십시오. |
| 422 | 이 재생목록에는 재생 가능한 곡이 없습니다. | 재생 목록이 비어 있거나, 회원님의 계정에서 재생할 수 있는 곡이 포함되어 있지 않습니다. |
| 429 | 요청 한도를 초과했습니다. | …을 존중하십시오Retry-After헤더; 요청 예산 60건/min/키 |
6. song_id 및 playlist_id 얻기
- 앱에서 확인(권장):
song_id— 곡 플레이어 열기 →⋯메뉴 → 곡 ID 복사.playlist_id— 재생목록 상세 페이지 열기 →⋯메뉴 → 재생목록 ID 복사 (오프라인 재생목록을 포함한 모든 재생목록 유형에서 사용 가능).
- API에서: Search 엔드포인트(§4.5 / §4.6)를 사용하여 키워드로 식별자를 조회하십시오.
7. Postman 컬렉션
즉시 가져올 수 있는 Postman 컬렉션은 open-api-postman-collection-prod.json에서 제공됩니다:
- Postman → Import → 파일을 선택합니다.
- 컬렉션 변수에
api_key및device_sn값을 입력합니다. - 필요에 따라
song_id/playlist_id값을 설정합니다(§6 참조). base_url의 경우 이미 프로덕션 환경(https://api.murobox.com)을 가리킵니다.
8. 보안 및 운영상 유의 사항
- API 키는 비밀번호처럼 취급하십시오. 키는 한 번만 표시되며 복구할 수 없습니다.
- 키별로 속도 제한(60/분)이 적용되며 감사 대상입니다(서버는 성공한 호출을 기록합니다). 더 이상 사용하지 않는 키는 앱에서 폐기하십시오.
- API는 계정에 페어링된 오르골의 재생을 트리거할 뿐이며, 곡이나 MIDI 파일을 다운로드하는 용도로는 사용할 수 없습니다.
- 대규모 자동화를 계획하고 있다면 키별 속도 제한을 준수하거나, 독립적인 할당량을 위해 키를 여러 개 생성하십시오.
사용 중 문제가 발생하거나 새로운 기능을 요청하고자 하실 경우, support@tevofy.com으로 이메일을 보내 문의해 주십시오.
Muro Box 팀