ListenHubDocs
API 参考

音乐生成

用 Mureka 或 Suno 生成歌曲、纯音乐与配乐,并分析已有音频——歌词识别、音频描述与音轨分离。

Music API 将文本、歌词、图片或参考音频转化为音乐,并分析已有曲目。生成能力由 Mureka 与 Suno 两个 provider 提供,在同时支持两者的端点上通过 provider 字段逐请求选择。所有端点位于 https://api.marswave.ai/openapi/v1/music 下,使用 Authorization: Bearer $LISTENHUB_API_KEY 鉴权。

接口分为两种响应模式:

模式端点结果如何返回
异步生成/generate、/cover、/instrumental、/soundtrack、/track、/remix、/extend返回 202 与 taskId,轮询 GET /v1/music/tasks/{taskId} 直到 status 为 success。
同步分析/recognize、/describe、/stem返回 200,结果直接在同一响应中。无需轮询。

每个响应都包裹在 { "code": 0, "message": "", "data": { ... } } 中。code 非 0 表示错误——见错误处理。下文示例均从 data 读取字段。

Provider

provider 接受 mureka、suno 或 default,default 解析为 Mureka。只有两个端点读取该字段,其余端点固定由单一 provider 承载并忽略它。

端点MurekaSunoprovider 选择
/generate✓✓由 provider 决定,默认 Mureka
/extend✓✓由 provider 决定,默认 Mureka
/cover—✓固定 Suno
/instrumental✓—固定 Mureka
/soundtrack✓—固定 Mureka
/track✓—固定 Mureka
/remix✓—固定 Mureka
/recognize✓—固定 Mureka
/describe✓—固定 Mureka
/stem✓—固定 Mureka

/remix 与 /cover 都是重新演绎已有录音,但不可互换:/remix 用新歌词重唱 Mureka 歌曲,/cover 通过 Suno 把上传的音频用新风格重录。

GET /v1/music/tasks 与 GET /v1/music/tasks/{taskId} 返回两个 provider 的任务,每个任务在 provider 字段中标明实际执行它的 provider。

模型

model 的取值范围由承载该请求的 provider 决定:Mureka 端点用 Mureka 模型名,Suno 端点用 Suno 档位。积分列适用于按档位计价的 /generate、/instrumental 与 /cover;/extend 走另一张表——mureka-7.6 与 auto(计价前先解析为 mureka-7.6)10 积分,其余模型(含全部 Suno 档位)15 积分——其余端点为固定价,列在积分。

Mureka 模型:

模型积分说明
auto10Mureka 默认值。由服务自动选择模型。
mureka-7.65
mureka-810
mureka-910/instrumental 不支持。
mureka-o210

Suno 模型:

模型积分说明
V415
V4_515
V4_5PLUS15
V4_5ALL15
V515
V5_520
V620Suno 默认值。最新档位。

全部档位都可显式指定。Suno 请求不传 model 时运行在 V6。

音轨分离 /stem 使用另一套模型:audio-separation-1(默认)或 audio-separation-2(额外产出 MIDI)。

Suno 专有参数

Suno 有七个 Mureka 没有对应项的参数。在 /generate 与 /cover 上它们放在 providerParams 内;在 /extend 上是顶层表单字段。

字段类型适用端点说明
negativeTagsstring/generate、/cover、/extend需要规避的风格标签,逗号分隔
vocalGenderstring/generate、/cover、/extendm 或 f。注意与 /track 不同,后者取 male / female
styleWeightnumber/generate、/cover、/extend0–1。结果贴合 style 的程度
weirdnessConstraintnumber/generate、/cover、/extend0–1。结果允许偏离常规的程度
audioWeightnumber/generate、/cover、/extend0–1。源录音的权重,仅在请求带源音频时有意义
personaIdstring/generate、/cover演唱该曲目的 Suno persona。在 /cover 上仅 custom mode 生效
personaModelstring/generate、/cover创建该 persona 时所用的档位,与 personaId 一起传

不在上表中的键会在请求到达 Suno 前从 providerParams 中丢弃。

异步任务生命周期

  1. 提交生成请求,响应携带 taskId,初始 status 为 pending。
  2. 轮询 GET /v1/music/tasks/{taskId},status 依次经过 pending → generating → uploading → success。
  3. 成功后读取 tracks 数组(标题、标签、时长、签名 audioUrl);失败则读取 errorMessage。params.model 给出该任务实际运行的档位,也是 creditCost 的计价依据。

推荐轮询节奏:提交后约 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.app/.../track-1.mp3"
      }
    ],
    "creditCost": 10,
    "createdAt": 1730000000000,
    "updatedAt": 1730000180000
  }
}

音轨的 audioUrl 是签名 URL,在任务被获取后约 1 小时失效。请在过期前下载音频,或重新获取任务以刷新 URL。

从文本或歌词生成

POST /v1/music/generate

根据风格提示词和/或歌词生成歌曲。发送 JSON。不传 provider=suno 时由 Mureka 承载。Mureka 会拒绝不带 lyrics 的非纯器乐请求;Suno 则接受只带 lyrics 或只带 prompt 的请求。

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'])

请求参数:

字段类型必填说明
promptstring否Mureka 上是风格/描述提示词。Suno 把它当作歌词读取,因此建议改用 lyrics,风格走 style
lyricsstring否歌词。instrumental 不为 true 时 Mureka 必填。Suno 用它作为歌曲歌词
stylestring否风格标签。作为 prompt 的 fallback
titlestring否歌曲标题
instrumentalboolean否生成纯器乐(无人声)
customModeboolean否仅 Suno。默认 true,此时 style 与 title 承载风格描述、歌词正文取自 lyrics;设为 false 则整首歌只由 prompt 驱动
modelstring否见模型。Mureka 默认 auto,Suno 默认 V6
vocalIdstring否复用的 Mureka vocal id,仅 Mureka 支持
providerstring否default(Mureka)、mureka 或 suno。默认 default
providerParamsobject否Provider 特有参数。Suno 见 Suno 专有参数

返回 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'])

请求参数:

字段类型必填说明
promptstring二选一风格/流派描述。与 referenceAudio 互斥
referenceAudiofile二选一参考音频(mp3/m4a,最大 10MB)。与 prompt 互斥
modelstring否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'])

请求参数:

字段类型必填说明
imagefile二选一图片(jpg/jpeg/png/webp)。与 video 互斥
videofile二选一视频(mp4/mov/avi/mkv/webm)。与 image 互斥
promptstring否风格/描述提示词
modelstring否auto、mureka-7.6、mureka-8、mureka-9 或 mureka-o2。默认 auto

生成单条音轨

POST /v1/music/track

基于参考音频文件或已有的 Mureka providerSongId 生成单条乐器/人声音轨。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'])

请求参数:

字段类型必填说明
generateTypestring是目标音轨类型,取值之一:Vocals、Instrumental、Drums、Bass、Guitar、Keyboard、Percussion、Strings、Synth、FX、Brass、Woodwinds
promptstring是风格/流派描述
audiofile二选一参考音频(mp3/m4a/wav,最大 10MB)。与 providerSongId 互斥
providerSongIdstring二选一来自之前结果的 Mureka song id。与 audio 互斥
lyricsstring为 Vocals 时歌词。generateType 为 Vocals 时必填
vocalGenderstring否male 或 female。仅 generateType=Vocals
generateStartnumber否起始时间(秒)
generateEndnumber否结束时间(秒)

Remix 已有歌曲

POST /v1/music/remix

用新歌词重新演绎已有歌曲。源音频三选一:上传的 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'])

请求参数:

字段类型必填说明
lyricsstring是新歌词
promptstring是风格/流派描述
audiofile三选一音频文件(mp3/m4a,最大 10MB)
audioUrlstring三选一内部 ListenHub 音频 URL(须归属当前用户或公开)
providerSongIdstring三选一来自之前结果的 Mureka song id

翻唱已有录音

POST /v1/music/cover

把上传的曲目用新风格重录,保留原旋律。仅 Suno 支持。发送 JSON。

curl -X POST "https://api.marswave.ai/openapi/v1/music/cover" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "uploadUrl": "https://example.com/original.mp3",
    "style": "acoustic folk, fingerpicked guitar",
    "title": "Night Walk (Acoustic)",
    "prompt": "[verse]\nWalking down the empty street at night",
    "model": "V6"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/music/cover', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    uploadUrl: 'https://example.com/original.mp3',
    style: 'acoustic folk, fingerpicked guitar',
    title: 'Night Walk (Acoustic)',
    prompt: '[verse]\nWalking down the empty street at night',
    model: 'V6',
  }),
});
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/cover',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'uploadUrl': 'https://example.com/original.mp3',
        'style': 'acoustic folk, fingerpicked guitar',
        'title': 'Night Walk (Acoustic)',
        'prompt': '[verse]\nWalking down the empty street at night',
        'model': 'V6',
    },
)
data = response.json()['data']
print('Task ID:', data['taskId'])

请求参数:

字段类型必填说明
uploadUrlstring是源录音:公网可访问的 URL,或你自己的 ListenHub 资源 URL——后者会校验归属并签发短时下载链接
modelstring否Suno 模型,见模型。默认 V6
customModeboolean否默认 true。设为 false 时仅用 prompt 驱动翻唱
promptstringcustom mode 必填新人声的歌词,customMode 为 true 且 instrumental 为 false 时必填。非 custom mode 下它是自由描述
stylestringcustom mode 必填音乐风格
titlestringcustom mode 必填歌曲标题
instrumentalboolean否生成无人声的翻唱。默认 false
providerParamsobject否Suno 专有参数,见 Suno 专有参数

返回 202 与 { "taskId": "...", "status": "pending" }。按 Suno 模型档位计价,与 /generate 一致。

延伸歌曲

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 路径):

字段类型必填说明
audiofile三选一音频文件(mp3/m4a,最大 10MB)。与 uploadUrl / providerSongId 互斥
uploadUrlstring三选一音频 URL(任意可访问外链或内部 GCS URL)
providerSongIdstring三选一来自之前结果的 Mureka song id
modelstring否Mureka 模型名,见模型。默认 auto,本端点会把它解析为 mureka-7.6
extendAtnumber是延伸的起始时间偏移,必须在 8–420 秒之间
extendTypestring否tail(向后,默认)或 head(向前,仅 mureka-8)
lyricsstring是新增段落的歌词
promptstring否风格/描述
stylestring否音乐风格
titlestring否歌曲标题
instrumentalboolean否新增段落生成纯器乐(无人声)

请求参数(Suno 路径):

字段类型必填说明
providerstring是suno。不传则走 Mureka 路径
uploadUrlstring是源录音:公网可访问的 URL,或你自己的 ListenHub 资源 URL
continueAtnumber是从第几秒继续,必须大于 0
modelstring否Suno 模型,见模型。默认 V6
promptstring否续写段落的歌词。instrumental 为 true 时忽略
stylestring否音乐风格
titlestring否歌曲标题
instrumentalboolean否续写无人声段落
negativeTagsstring否见 Suno 专有参数
vocalGenderstring否见 Suno 专有参数
styleWeightnumber否见 Suno 专有参数
weirdnessConstraintnumber否见 Suno 专有参数
audioWeightnumber否见 Suno 专有参数

model 在预占积分之前先校验:不在模型两张表里的取值直接拒绝。显式传 provider 会把校验范围收窄到该 provider 的档位。

两条路径只共用 uploadUrl、prompt、style、title 与 instrumental。audio、providerSongId、extendAt、extendType、lyrics 仅 Mureka 可用;continueAt 仅 Suno 可用。

识别歌词

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']))

请求参数:

字段类型必填说明
audiofile是音频文件(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'])

请求参数:

字段类型必填说明
audiofile是待分析音频文件(mp3/m4a,最大 10MB)

data.result 对象包含 description、tags、genres 与 instruments。

分离音轨(stem)

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'])

请求参数:

字段类型必填说明
audiofile是待分离音频文件(mp3/m4a,最大 10MB)
modelstring否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.items.length} of ${data.total} 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},
)
data = response.json()['data']
print(len(data['items']), 'of', data['total'], 'tasks')

查询参数:

字段类型必填说明
pageinteger否页码,最小 1。默认 1
pageSizeinteger否每页数量,1–100。默认 20
statusstring否按 pending、generating、uploading、success 或 failed 过滤

data 是一页而不是数组:items 是本页任务,total 是总数,page 与 pageSize 回显本次生效的取值。

查询单个任务

GET /v1/music/tasks/{taskId}

获取单个任务。这是提交异步生成请求后用于轮询的端点。

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'])

任务响应字段:

字段类型说明
idstring任务 ID
providerstringmureka 或 suno。建单时已解析——任务不会存成 default
taskTypestringGENERATE、INSTRUMENTAL、REMIX、EXTEND、COVER、SOUNDTRACK、TRACK、RECOGNIZE、DESCRIBE、STEM、REGION_EDIT
statusstringpending、generating、uploading、success、failed
paramsobject生成请求参数的回显,含 model——任务实际运行的档位
tracksarray完成的音轨:title、tags、duration(秒)、签名 audioUrl
creditCostnumber消耗积分
errorMessagestring失败原因(仅 status 为 failed 时返回)
createdAtnumber创建时间(毫秒时间戳)
updatedAtnumber更新时间(毫秒时间戳)

积分

/generate、/instrumental 与 /cover 按模型档位计价,档位价见模型。其余端点为固定价:/remix 10,/extend 在 mureka-7.6 与 auto(解析为 mureka-7.6)上 10、其余模型 15,/soundtrack 15,/track 15,/describe 15,/recognize 3,/stem 在 audio-separation-1 上 10、audio-separation-2 上 100。

异步生成在提交时预占积分,成功时确认扣除,失败自动退回。每个任务的实际消耗通过 creditCost 返回(分析类调用在结果中同样返回 creditCost)。用 GET /v1/user/subscription 查询实时余额,并参见定价了解积分与功能的对应关系。

SDK 与 CLI

官方 SDK 与 CLI 封装了下列端点,包含异步轮询。两者目前都还不支持选择 provider 和传 Suno 专有参数——这两项请直接用 HTTP 调用。

本页内容