HiAPI
블로그

튜토리얼

minimax-music-3 API: curl 및 Python 가이드

Aug 18, 2026
minimax-music-3 API: curl 및 Python 가이드

hiapi에서 minimax-music-3로 트랙 한 곡을 생성하려면 POST /v1/tasks 호출 한 번과 폴링만 있으면 됩니다. 이는 플랫폼의 모든 모델이 사용하는 비동기 작업 패턴과 완전히 동일합니다. 이 가이드는 실제 요청과 응답(작업 생성, 폴링, 최종 오디오 URL)을 기록한 것이므로, 아래 코드는 단순한 예시가 아니라 그대로 복사해서 실행할 수 있습니다.

준비물

  1. hiapi API 키 하나 — 콘솔에서 생성하세요. 모든 요청에 Bearer 토큰으로 전송됩니다.
  2. 그게 전부입니다. 이미지-투-비디오나 이미지-투-이미지 모델과 달리 minimax-music-3는 파일이나 URL 입력을 받지 않으며, 텍스트만으로 생성합니다.

최소 동작 요청(curl)

작업 생성:

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "minimax-music-3",
    "input": {
      "prompt": "chill lofi hip hop beat, mellow piano, soft drums",
      "lyrics": "[Instrumental]"
    }
  }'

응답:

{"code":200,"data":{"taskId":"tk-hiapi-01M09A11R6WEC2JDQ8RK6E7N55"},"message":"success"}

완료될 때까지 작업을 폴링:

curl https://api.hiapi.ai/v1/tasks/tk-hiapi-01M09A11R6WEC2JDQ8RK6E7N55 \
  -H "Authorization: Bearer sk-<your-key>"

작업이 실행되는 동안 status는 handling → archiving을 거쳐 최종적으로 success(또는 failed)가 됩니다. 테스트에서 한 트랙은 제출부터 success까지 약 2분 30초가 걸렸습니다. 완료 후 응답은 다음과 같습니다:

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-01M09A11R6WEC2JDQ8RK6E7N55",
    "status": "success",
    "model": "minimax-music-3",
    "created": 1787018905,
    "completed": 1787019051,
    "storage": "temp",
    "output": [
      {
        "type": "audio",
        "url": "https://temp.hiapi.ai/7c6ttvrbpt/01M09A11R6WEC2JDQ8RK6E7N55-0.wav",
        "artifactId": "78585",
        "expireAt": 1787623851
      }
    ]
  },
  "message": "success"
}

output[0].url이 바로 WAV 파일입니다. expireAt에 주의하세요. 이 URL의 장기 유효성에 의존하는 기능을 만들기 전에 아래 저장소 관련 설명을 먼저 읽어 보세요.

Python에서의 동일한 흐름

import time
import requests

API_KEY = "sk-<your-key>"
BASE_URL = "https://api.hiapi.ai/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}


def create_track(prompt: str, lyrics: str = "[Instrumental]") -> str:
    resp = requests.post(
        f"{BASE_URL}/tasks",
        headers=HEADERS,
        json={"model": "minimax-music-3", "input": {"prompt": prompt, "lyrics": lyrics}},
        timeout=30,
    )
    body = resp.json()
    if resp.status_code != 200 or "error" in body:
        raise RuntimeError(f"create failed: {body}")
    return body["data"]["taskId"]


def wait_for_track(task_id: str, timeout_s: int = 300, interval_s: int = 6) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        resp = requests.get(f"{BASE_URL}/tasks/{task_id}", headers=HEADERS, timeout=30)
        data = resp.json()["data"]
        if data["status"] == "success":
            return data["output"][0]["url"]
        if data["status"] == "failed":
            raise RuntimeError(f"task {task_id} failed: {data}")
        time.sleep(interval_s)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")


if __name__ == "__main__":
    task_id = create_track("upbeat synthwave, driving bassline, retro 80s")
    audio_url = wait_for_track(task_id)
    audio = requests.get(audio_url, timeout=60).content
    with open("track.wav", "wb") as f:
        f.write(audio)
    print(f"saved track.wav from task {task_id}")

minimax-music-3가 실제로 검증하는 파라미터

입력 스키마는 엄격합니다. 나열되지 않은 필드를 보내면 API가 요청을 큐에 넣기 전에 전체 요청을 거부합니다:

  • prompt(문자열, 필수) — 스타일, 분위기, 편성. 실제로 트랙의 형태를 결정합니다.
  • lyrics(문자열, 필수) — 순수 기악 트랙이라도 항상 필수입니다. 자리 표시자로 "[Instrumental]"을 전달하세요. 보컬이 있는 트랙에는 [Verse] / [Chorus] 같은 섹션 태그를 사용하세요.
  • callback(객체, 선택) — {"url": "...", "when": "final"}. when에 지원되는 유일한 값은 "final"이며, 다른 값을 보내면 invalid callback.when: only 'final' is supported 오류와 함께 400이 반환됩니다.

이 세 개의 최상위 키 외에 sample_rate, duration 또는 오타 등 무엇이든 보내면 다음과 같은 응답을 받게 됩니다:

{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: <root>: additional properties 'sample_rate' not allowed"}

프로덕션 환경 유의사항

  • 두 가지 서로 다른 오류 형태. 검증 오류(필드 누락, 잘못된 열거형 값, 알 수 없는 키)는 최상위에 {"code":400,"error_code":"INVALID_REQUEST","message":"..."}를 반환합니다. 인증/권한 오류는 {"error":{"code":"permission_denied","message":"...","request_id":"..."}}를 반환합니다. 즉, 중첩된 error 객체와 HTTP 401입니다. 오류 처리에서 두 형태를 모두 확인하세요. resp["code"]만 확인하는 코드는 401 상황을 놓칩니다.
  • permission_denied는 요청이 아니라 키의 문제입니다. prompt/lyrics가 존재하고 타입도 올바른데도 401 permission_denied를 받는다면, 해당 API 키 자체에 이 모델이 활성화되지 않은 것입니다. JSON을 반복해서 들여다보지 말고 콘솔에서 확인하세요.
  • 출력 파일 저장은 임시입니다. storage: "temp"와 각 출력의 expireAt Unix 타임스탬프가 있으며, 캡처된 예시에서는 생성 후 약 7일입니다. 작업이 성공하면 즉시 파일을 다운로드하거나 자체 저장소로 푸시하세요. temp.hiapi.ai URL을 영구 링크로 저장하지 마세요.
  • 대량 작업에는 콜백을 사용하세요. 트랙 한 곡을 폴링하는 것은 문제없지만, 50곡을 폴링하면 50번의 반복 왕복이 발생합니다. callback.url과 when: "final"을 설정하면 작업이 실제로 완료될 때 hiapi가 결과를 한 번에 푸시해 줍니다.
  • taskId를 받기 전에 재시도하고, 받은 후에는 하지 마세요. 최초 POST /v1/tasks에서 네트워크 오류나 5xx가 발생하면 재시도해도 안전합니다. 이 시점에는 아직 아무것도 생성되지 않았기 때문입니다. taskId를 받은 후에 동일한 prompt를 다시 제출하면 별개의 트랙이 하나 더 생성됩니다. 이때는 폴링하거나 콜백을 기다리세요.

관련 자료

자주 묻는 질문

순수 기악 트랙에도 가사를 제공해야 하나요? 네. 보컬을 원하든 원하지 않든 lyrics는 필수 필드입니다. "[Instrumental]"을 전달하면 모델이 보컬 없는 트랙을 생성합니다.

폴링을 완전히 피할 수 있나요? 네. 작업을 생성할 때 callback: {"url": "https://your-endpoint", "when": "final"}을 설정하세요. 작업이 종료 상태에 도달하면 hiapi가 GET /v1/tasks/:id와 동일한 페이로드를 지정한 URL로 POST합니다. 현재 when에 지원되는 유일한 값은 "final"입니다.

왜 "additional properties not allowed"가 발생하나요? minimax-music-3의 입력 스키마는 input 내에서 prompt와 lyrics만 허용합니다(그리고 최상위 callback). 다른 모델에서 유효한 필드명이라도 요청이 실행되기 전에 거부됩니다.

다른 모델에서는 작동하는 키가 이 모델에서는 401을 반환하는 이유는 무엇인가요? 모델 접근 권한은 키별로 부여됩니다. error_code: "permission_denied"와 함께 401이 반환된다면 해당 키에 minimax-music-3 권한이 아직 부여되지 않은 것입니다. 콘솔에서 활성화하세요. 요청 본문의 버그가 아닙니다.

출력 파일을 다운로드하기 전에 얼마나 기다릴 수 있나요? 기다리지 마세요. output[0].url은 임시 링크입니다(실제로 expireAt은 약 일주일 후). 일회성 인계로 취급하여 작업 성공 후 즉시 다운로드하거나 다시 업로드하세요.

영구 AI 아티팩트로 빌드 시작하기

API 키를 받아 태스크 기반의 하나의 API로 이미지, 비디오, 오디오 모델을 호출하세요.

API 문서 보기