音楽生成
Mureka で楽曲、インストゥルメンタル、サウンドトラックを生成し、既存の音声を分析します——歌詞認識、音声の説明、ステム分離。
Music API はテキスト、歌詞、画像、参照音声を音楽に変換し、既存のトラックを分析します。生成機能は Mureka が提供します。すべてのエンドポイントは https://api.marswave.ai/openapi/v1/music 配下にあり、Authorization: Bearer $LISTENHUB_API_KEY で認証します。
この API は 2 つのレスポンスパターンに分かれます:
| パターン | エンドポイント | 結果の返り方 |
|---|---|---|
| 非同期生成 | /generate、/instrumental、/soundtrack、/track、/remix、/extend | 202 と taskId を返します。status が success になるまで GET /v1/music/tasks/{taskId} をポーリングします。 |
| 同期分析 | /recognize、/describe、/stem | 200 を返し、結果は同じレスポンスに含まれます。ポーリングは不要です。 |
すべてのレスポンスは { "code": 0, "message": "", "data": { ... } } の形にラップされます。code が 0 以外ならエラーです——エラーハンドリングを参照してください。以下の例はすべて data からフィールドを読み取ります。
モデル
生成系のエンドポイントは、プロバイダー非依存の契約に基づく model パラメータを受け付けます。Mureka のモデル:
| モデル | 説明 |
|---|---|
auto | デフォルト。サービス側がモデルを自動選択します。 |
mureka-7.6 | |
mureka-8 | |
mureka-9 | /instrumental では利用できません。 |
mureka-o2 |
ステム分離(/stem)は別のモデルセットを使います:audio-separation-1(デフォルト)または audio-separation-2(MIDI も出力)。
非同期タスクのライフサイクル
- 生成リクエストを送信します。レスポンスには
taskIdと初期statusのpendingが含まれます。 GET /v1/music/tasks/{taskId}をポーリングします。statusはpending→generating→uploading→successと遷移します。successになったら、完成したtracks配列(タイトル、タグ、長さ、署名付きaudioUrl)を読み取ります。failedの場合はerrorMessageを読み取ります。
推奨のポーリング方法:送信後およそ 30 秒待ってから、10 秒ごとにポーリングします。音楽タスクは通常 1–3 分で完了します。
{
"code": 0,
"message": "",
"data": {
"id": "68e780390fc5c9a54f695a7e",
"provider": "mureka",
"taskType": "GENERATE",
"status": "success",
"params": {
"model": "auto",
"prompt": "r&b, slow, passionate, male vocal",
"instrumental": false
},
"tracks": [
{
"title": "Night Walk",
"tags": "r&b, slow",
"duration": 142.5,
"audioUrl": "https://assets.listenhub.ai/.../track-1.mp3"
}
],
"creditCost": 20,
"createdAt": 1730000000000,
"updatedAt": 1730000180000
}
}トラックの audioUrl は署名付きで、タスクを取得してから約 1 時間で失効します。失効する前に音声をダウンロードするか、タスクを再取得して URL を更新してください。
テキストまたは歌詞から生成する
POST /v1/music/generate
スタイルのプロンプトや歌詞から楽曲を作成します。JSON を送信します。Mureka の場合、インストゥルメンタル以外のリクエストには lyrics を含めてください。
curl -X POST "https://api.marswave.ai/openapi/v1/music/generate" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "r&b, slow, passionate, male vocal",
"lyrics": "[verse]\nWalking down the empty street at night\n[chorus]\nFeel the rhythm, feel the light",
"title": "Night Walk",
"model": "auto"
}'const response = await fetch('https://api.marswave.ai/openapi/v1/music/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt: 'r&b, slow, passionate, male vocal',
lyrics: '[verse]\nWalking down the empty street at night\n[chorus]\nFeel the rhythm, feel the light',
title: 'Night Walk',
model: 'auto',
}),
});
const { data } = await response.json();
console.log('Task ID:', data.taskId);import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/generate',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'prompt': 'r&b, slow, passionate, male vocal',
'lyrics': '[verse]\nWalking down the empty street at night\n[chorus]\nFeel the rhythm, feel the light',
'title': 'Night Walk',
'model': 'auto',
},
)
data = response.json()['data']
print('Task ID:', data['taskId'])リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
prompt | string | いいえ | スタイル / 内容のプロンプト |
lyrics | string | いいえ | 歌詞。Mureka でインストゥルメンタル以外の場合は必須 |
style | string | いいえ | スタイルタグ。prompt のフォールバックとして使われます |
title | string | いいえ | トラックのタイトル |
instrumental | boolean | いいえ | ボーカルなしで生成します |
model | string | いいえ | モデルを参照。デフォルトは auto |
vocalId | string | いいえ | Mureka の vocal id を再利用します |
provider | string | いいえ | default(Mureka)、mureka、suno。デフォルトは default |
providerParams | object | いいえ | プロバイダー固有のパラメータ |
202 と { "taskId": "...", "status": "pending" } を返します。結果はタスクをポーリングして取得します。
インストゥルメンタルを生成する
POST /v1/music/instrumental
テキストプロンプト または 参照音声ファイルから、単体のインストゥルメンタルを作成します。prompt と referenceAudio のどちらか一方だけを指定してください。multipart/form-data を送信します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/instrumental" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "prompt=lofi hip hop, mellow, rainy night" \
-F "model=auto"const form = new FormData();
form.append('prompt', 'lofi hip hop, mellow, rainy night');
form.append('model', 'auto');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/instrumental', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log('Task ID:', data.taskId);import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/instrumental',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
data={'prompt': 'lofi hip hop, mellow, rainy night', 'model': 'auto'},
)
data = response.json()['data']
print('Task ID:', data['taskId'])リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
prompt | string | いずれか | スタイル / ジャンルの説明。referenceAudio とは排他です |
referenceAudio | file | いずれか | 参照音声(mp3/m4a、最大 10MB)。prompt とは排他です |
model | string | いいえ | auto、mureka-7.6、mureka-8、mureka-o2。デフォルトは auto |
画像や動画からサウンドトラックを生成する
POST /v1/music/soundtrack
画像や動画に合う音楽を生成します。image と video のどちらか一方だけを指定してください。multipart/form-data を送信します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/soundtrack" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "image=@scene.jpg" \
-F "prompt=cinematic, hopeful, orchestral" \
-F "model=auto"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append('image', new Blob([await readFile('scene.jpg')]), 'scene.jpg');
form.append('prompt', 'cinematic, hopeful, orchestral');
form.append('model', 'auto');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/soundtrack', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log('Task ID:', data.taskId);import os
import requests
with open('scene.jpg', 'rb') as f:
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/soundtrack',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
files={'image': f},
data={'prompt': 'cinematic, hopeful, orchestral', 'model': 'auto'},
)
data = response.json()['data']
print('Task ID:', data['taskId'])リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
image | file | いずれか | 画像(jpg/jpeg/png/webp)。video とは排他です |
video | file | いずれか | 動画(mp4/mov/avi/mkv/webm)。image とは排他です |
prompt | string | いいえ | スタイル / 内容のプロンプト |
model | string | いいえ | auto、mureka-7.6、mureka-8、mureka-9、mureka-o2。デフォルトは auto |
単一トラックを生成する
POST /v1/music/track
参照音声ファイル または 既存の Mureka の providerSongId から、楽器またはボーカルのトラックを 1 本生成します。audio と providerSongId のどちらか一方だけを指定してください。multipart/form-data を送信します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/track" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "audio=@reference.mp3" \
-F "generateType=Drums" \
-F "prompt=funk, tight groove, 110 bpm"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append('audio', new Blob([await readFile('reference.mp3')]), 'reference.mp3');
form.append('generateType', 'Drums');
form.append('prompt', 'funk, tight groove, 110 bpm');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/track', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log('Task ID:', data.taskId);import os
import requests
with open('reference.mp3', 'rb') as f:
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/track',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
files={'audio': f},
data={'generateType': 'Drums', 'prompt': 'funk, tight groove, 110 bpm'},
)
data = response.json()['data']
print('Task ID:', data['taskId'])リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
generateType | string | はい | 生成するトラックの種類。Vocals、Instrumental、Drums、Bass、Guitar、Keyboard、Percussion、Strings、Synth、FX、Brass、Woodwinds のいずれか |
prompt | string | はい | スタイル / ジャンルの説明 |
audio | file | いずれか | 参照音声(mp3/m4a/wav、最大 10MB)。providerSongId とは排他です |
providerSongId | string | いずれか | 過去の結果に含まれる Mureka の song id。audio とは排他です |
lyrics | string | Vocals の場合 | 歌詞。generateType が Vocals のときは必須 |
vocalGender | string | いいえ | male または female。generateType=Vocals のときのみ有効 |
generateStart | number | いいえ | 範囲の開始位置(秒) |
generateEnd | number | いいえ | 範囲の終了位置(秒) |
既存の楽曲をリミックスする
POST /v1/music/remix
既存の楽曲を新しい歌詞で歌い直させます。元音源は次のいずれか 1 つの方法で指定します:アップロードした audio ファイル、ListenHub 内部の audioUrl、Mureka の providerSongId。multipart/form-data を送信します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/remix" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "audio=@original.mp3" \
-F "lyrics=[verse]\nA brand new story to tell" \
-F "prompt=upbeat pop, bright synths"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append('audio', new Blob([await readFile('original.mp3')]), 'original.mp3');
form.append('lyrics', '[verse]\nA brand new story to tell');
form.append('prompt', 'upbeat pop, bright synths');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/remix', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log('Task ID:', data.taskId);import os
import requests
with open('original.mp3', 'rb') as f:
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/remix',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
files={'audio': f},
data={
'lyrics': '[verse]\nA brand new story to tell',
'prompt': 'upbeat pop, bright synths',
},
)
data = response.json()['data']
print('Task ID:', data['taskId'])リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
lyrics | string | はい | 新しい歌詞 |
prompt | string | はい | スタイル / ジャンルの説明 |
audio | file | 元音源のいずれか 1 つ | 音声ファイル(mp3/m4a、最大 10MB) |
audioUrl | string | 元音源のいずれか 1 つ | ListenHub 内部の音声 URL(自分のものか公開されている必要があります) |
providerSongId | string | 元音源のいずれか 1 つ | 過去の結果に含まれる Mureka の song id |
楽曲を延長する
POST /v1/music/extend
既存の楽曲を、指定した時点から続けて生成します。multipart/form-data を送信します。元音源は audio、uploadUrl、providerSongId のいずれかで指定します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/extend" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "audio=@original.mp3" \
-F "model=mureka-8" \
-F "extendAt=30" \
-F "extendType=tail"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append('audio', new Blob([await readFile('original.mp3')]), 'original.mp3');
form.append('model', 'mureka-8');
form.append('extendAt', '30');
form.append('extendType', 'tail');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/extend', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log('Task ID:', data.taskId);import os
import requests
with open('original.mp3', 'rb') as f:
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/extend',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
files={'audio': f},
data={'model': 'mureka-8', 'extendAt': '30', 'extendType': 'tail'},
)
data = response.json()['data']
print('Task ID:', data['taskId'])リクエストパラメータ(Mureka の場合):
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
audio | file | 元音源のいずれか 1 つ | 音声ファイル(mp3/m4a、最大 10MB)。uploadUrl / providerSongId とは排他です |
uploadUrl | string | 元音源のいずれか 1 つ | 音声の URL(到達可能な外部リンク、または内部の GCS URL) |
providerSongId | string | 元音源のいずれか 1 つ | 過去の結果に含まれる Mureka の song id |
model | string | いいえ | モデルを参照 |
extendAt | number | いいえ | 延長の起点となる時間オフセット(秒、8–420) |
extendType | string | いいえ | tail(前方向、デフォルト)または head(後方向、mureka-8 のみ) |
lyrics | string | いいえ | 新しいセクションの歌詞 |
prompt | string | いいえ | スタイル / 内容の説明 |
style | string | いいえ | 音楽スタイル |
title | string | いいえ | トラックのタイトル |
instrumental | boolean | いいえ | 新しいセクションをボーカルなしで生成します |
/extend は continueAt、uploadUrl、Suno のモデルバージョンを使う Suno 経路にも対応しています。provider=suno と Suno 固有のフィールドを指定してください。デフォルトのプロバイダーは Mureka です。
歌詞を認識する
POST /v1/music/recognize
音声ファイルから、タイムスタンプ付きセクションとともに歌詞を書き起こします。同期です——結果はレスポンスに含まれます。multipart/form-data を送信します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/recognize" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "audio=@song.mp3"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append('audio', new Blob([await readFile('song.mp3')]), 'song.mp3');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/recognize', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log('Sections:', data.result.lyricsSections.length);import os
import requests
with open('song.mp3', 'rb') as f:
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/recognize',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
files={'audio': f},
)
data = response.json()['data']
print('Sections:', len(data['result']['lyricsSections']))リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
audio | file | はい | 音声ファイル(mp3/m4a、最大 10MB) |
data.result オブジェクトには duration と lyricsSections 配列が含まれます。
音声を説明する
POST /v1/music/describe
音声ファイルを分析し、説明文に加えてタグ、ジャンル、楽器を返します。同期です。multipart/form-data を送信します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/describe" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "audio=@song.mp3"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append('audio', new Blob([await readFile('song.mp3')]), 'song.mp3');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/describe', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log(data.result.description, data.result.genres);import os
import requests
with open('song.mp3', 'rb') as f:
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/describe',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
files={'audio': f},
)
data = response.json()['data']
print(data['result']['description'], data['result']['genres'])リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
audio | file | はい | 分析する音声ファイル(mp3/m4a、最大 10MB) |
data.result オブジェクトには description、tags、genres、instruments が含まれます。
ステムを分離する
POST /v1/music/stem
音声ファイルをステム(ボーカル、ベース、ドラム、その他)に分離し、ダウンロード URL を返します。同期です。multipart/form-data を送信します。
curl -X POST "https://api.marswave.ai/openapi/v1/music/stem" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-F "audio=@song.mp3" \
-F "model=audio-separation-1"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append('audio', new Blob([await readFile('song.mp3')]), 'song.mp3');
form.append('model', 'audio-separation-1');
const response = await fetch('https://api.marswave.ai/openapi/v1/music/stem', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
body: form,
});
const { data } = await response.json();
console.log('Stems ZIP:', data.result.zipUrl);import os
import requests
with open('song.mp3', 'rb') as f:
response = requests.post(
'https://api.marswave.ai/openapi/v1/music/stem',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
files={'audio': f},
data={'model': 'audio-separation-1'},
)
data = response.json()['data']
print('Stems ZIP:', data['result']['zipUrl'])リクエストパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
audio | file | はい | 分離する音声ファイル(mp3/m4a、最大 10MB) |
model | string | いいえ | audio-separation-1(デフォルト)または audio-separation-2(MIDI も出力) |
data.result オブジェクトには zipUrl、midiZipUrl(audio-separation-2 の場合)、expiresAt が含まれます。ダウンロードリンクは生成から約 24 時間で失効します。
タスク一覧を取得する
GET /v1/music/tasks
自分の音楽タスクを新しい順に一覧表示します。
curl -X GET "https://api.marswave.ai/openapi/v1/music/tasks?page=1&pageSize=20&status=success" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"const response = await fetch(
'https://api.marswave.ai/openapi/v1/music/tasks?page=1&pageSize=20',
{ headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` } }
);
const { data } = await response.json();
console.log(`${data.length} tasks`);import os
import requests
response = requests.get(
'https://api.marswave.ai/openapi/v1/music/tasks',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
params={'page': 1, 'pageSize': 20},
)
print(len(response.json()['data']), 'tasks')クエリパラメータ:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
page | integer | いいえ | ページ番号、最小 1。デフォルトは 1 |
pageSize | integer | いいえ | 1 ページあたりの件数、1–100。デフォルトは 20 |
status | string | いいえ | pending、generating、uploading、success、failed で絞り込みます |
単一タスクを取得する
GET /v1/music/tasks/{taskId}
タスクを 1 件取得します。非同期の生成リクエストを送信したあとにポーリングするのは、このエンドポイントです。
curl -X GET "https://api.marswave.ai/openapi/v1/music/tasks/{taskId}" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"const response = await fetch(
`https://api.marswave.ai/openapi/v1/music/tasks/${taskId}`,
{ headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` } }
);
const { data } = await response.json();
console.log('Status:', data.status);
if (data.status === 'success') console.log('Audio:', data.tracks[0].audioUrl);import os
import requests
response = requests.get(
f'https://api.marswave.ai/openapi/v1/music/tasks/{task_id}',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
)
data = response.json()['data']
print('Status:', data['status'])
if data['status'] == 'success':
print('Audio:', data['tracks'][0]['audioUrl'])タスクレスポンスのフィールド:
| フィールド | 型 | 説明 |
|---|---|---|
id | string | タスク ID |
provider | string | default、mureka、suno |
taskType | string | GENERATE、INSTRUMENTAL、REMIX、EXTEND、COVER |
status | string | pending、generating、uploading、success、failed |
params | object | 生成リクエストの内容をそのまま返します |
tracks | array | 完成したトラック:title、tags、duration(秒)、署名付き audioUrl |
creditCost | number | 消費したクレジット |
errorMessage | string | 失敗理由(status が failed のときのみ) |
createdAt | number | 作成時刻(ミリ秒タイムスタンプ) |
updatedAt | number | 最終更新時刻(ミリ秒タイムスタンプ) |
クレジット
各エンドポイントはモデルの階層に応じてクレジットを消費します。非同期生成では、送信時にクレジットを予約し、success で確定、failure の場合は自動的に返却されます。実際のコストはタスクごとに creditCost として返されます(分析系の呼び出しも結果に creditCost を含みます)。現在の残高は GET /v1/user/subscription で確認でき、クレジットと機能の対応関係は料金を参照してください。
SDK と CLI
公式 SDK と CLI は、非同期のポーリングも含め、このページのすべてのエンドポイントをラップしています。
JavaScript SDK
OpenAPIClient.createMusicGenerate / createMusicInstrumental / createMusicSoundtrack / createMusicTrack / createMusicRemix、および recognizeMusic / describeMusic / stemMusic と getMusicTask / listMusicTasks。
CLI
listenhub openapi music generate | instrumental | soundtrack | track | remix | recognize | describe | stem | list | get — ポーリング制御には --no-wait と --timeout を使います。