ListenHubOpenAPI
API 参考

播客生成

通过 API 创建单人或双人播客,支持 quick、debate、deep 三种模式,可指定音色与参考资料。

创建单人播客

POST /v1/podcast/episodes

创建一个单主持人播客。支持三种模式:quick(快速)、debate(辩论,需要2个音色)、deep(深度)。

Quick 模式示例

curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "今日科技新闻速报",
    "speakers": [
      {"speakerId": "chat-girl-105-cn"}
    ],
    "language": "zh",
    "mode": "quick"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/podcast/episodes', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '今日科技新闻速报',
    speakers: [{ speakerId: 'chat-girl-105-cn' }],
    language: 'zh',
    mode: 'quick',
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/podcast/episodes',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'query': '今日科技新闻速报',
        'speakers': [{'speakerId': 'chat-girl-105-cn'}],
        'language': 'zh',
        'mode': 'quick',
    }
)
data = response.json()
print(data)

Deep 模式示例

curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "深度解析大语言模型的技术原理和应用前景",
    "speakers": [
      {"speakerId": "CN-Man-Beijing-V2"}
    ],
    "language": "zh",
    "mode": "deep"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/podcast/episodes', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '深度解析大语言模型的技术原理和应用前景',
    speakers: [{ speakerId: 'CN-Man-Beijing-V2' }],
    language: 'zh',
    mode: 'deep',
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/podcast/episodes',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'query': '深度解析大语言模型的技术原理和应用前景',
        'speakers': [{'speakerId': 'CN-Man-Beijing-V2'}],
        'language': 'zh',
        'mode': 'deep',
    }
)
data = response.json()
print(data)

支持的模式

  • quick — 快速模式(适合时效性内容)
  • debate — 辩论模式(需要 2 个音色)
  • deep — 深度模式(适合专业内容)

创建双人播客

POST /v1/podcast/episodes

创建双主持人对话式播客,支持 quickdebatedeep 三种模式。

Debate 模式(双人辩论)

# Debate 模式必须选择 2 个声音/speaker
curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "远程办公是否应该成为主流工作模式?",
    "speakers": [
      {"speakerId": "CN-Man-Beijing-V2"},
      {"speakerId": "chat-girl-105-cn"}
    ],
    "language": "zh",
    "mode": "debate"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/podcast/episodes', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '远程办公是否应该成为主流工作模式?',
    speakers: [
      { speakerId: 'CN-Man-Beijing-V2' },
      { speakerId: 'chat-girl-105-cn' },
    ],
    language: 'zh',
    mode: 'debate',
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/podcast/episodes',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'query': '远程办公是否应该成为主流工作模式?',
        'speakers': [
            {'speakerId': 'CN-Man-Beijing-V2'},
            {'speakerId': 'chat-girl-105-cn'},
        ],
        'language': 'zh',
        'mode': 'debate',
    }
)
data = response.json()
print(data)

Deep 模式(双人对话)

curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "探讨人工智能对就业市场的影响",
    "speakers": [
      {"speakerId": "CN-Man-Beijing-V2"},
      {"speakerId": "chat-girl-105-cn"}
    ],
    "language": "zh",
    "mode": "deep"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/podcast/episodes', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '探讨人工智能对就业市场的影响',
    speakers: [
      { speakerId: 'CN-Man-Beijing-V2' },
      { speakerId: 'chat-girl-105-cn' },
    ],
    language: 'zh',
    mode: 'deep',
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/podcast/episodes',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'query': '探讨人工智能对就业市场的影响',
        'speakers': [
            {'speakerId': 'CN-Man-Beijing-V2'},
            {'speakerId': 'chat-girl-105-cn'},
        ],
        'language': 'zh',
        'mode': 'deep',
    }
)
data = response.json()
print(data)

使用 sources 提供参考资料

curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "分析这篇技术文章的核心观点",
    "sources": [
      {
        "type": "url",
        "content": "https://blog.samaltman.com/reflections"
      }
    ],
    "speakers": [
      {"speakerId": "CN-Man-Beijing-V2"},
      {"speakerId": "chat-girl-105-cn"}
    ],
    "language": "zh",
    "mode": "deep"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/podcast/episodes', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '分析这篇技术文章的核心观点',
    sources: [
      {
        type: 'url',
        content: 'https://blog.samaltman.com/reflections',
      },
    ],
    speakers: [
      { speakerId: 'CN-Man-Beijing-V2' },
      { speakerId: 'chat-girl-105-cn' },
    ],
    language: 'zh',
    mode: 'deep',
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/podcast/episodes',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'query': '分析这篇技术文章的核心观点',
        'sources': [
            {
                'type': 'url',
                'content': 'https://blog.samaltman.com/reflections',
            }
        ],
        'speakers': [
            {'speakerId': 'CN-Man-Beijing-V2'},
            {'speakerId': 'chat-girl-105-cn'},
        ],
        'language': 'zh',
        'mode': 'deep',
    }
)
data = response.json()
print(data)

查询播客状态

GET /v1/podcast/episodes/{episodeId}

创建播客后,用返回的 episodeId 轮询查询状态,直到 processStatussuccess

curl -X GET "https://api.marswave.ai/openapi/v1/podcast/episodes/{episodeId}" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY"
const response = await fetch(
  `https://api.marswave.ai/openapi/v1/podcast/episodes/${episodeId}`,
  {
    headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
  }
);
const data = await response.json();
console.log('Status:', data.data.processStatus);
console.log('Audio URL:', data.data.audioUrl);
import os
import requests

response = requests.get(
    f'https://api.marswave.ai/openapi/v1/podcast/episodes/{episode_id}',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'}
)
data = response.json()
print('Status:', data['data']['processStatus'])
print('Audio URL:', data['data']['audioUrl'])

生成完成后的响应(processStatussuccess):

{
  "code": 0,
  "message": "",
  "data": {
    "episodeId": "{episodeId}",
    "processStatus": "success",
    "credits": 27,
    "title": "听AI讲自己的故事:智能时代如何诞生",
    "audioUrl": "https://assets.listenhub.ai/listenhub-public-prod/podcast/{episodeId}.mp3",
    "audioStreamUrl": "https://assets.listenhub.ai/listenhub-public-prod/podcast/{episodeId}.m3u8",
    "scripts": [
      {
        "speakerId": "CN-Man-Beijing-V2",
        "speakerName": "原野",
        "content": "如今我们好像每天都被人工智能的新闻包围着。"
      }
    ]
  }
}

播客生成通常需要 1-4 分钟。推荐轮询策略:等待 60 秒后开始,每 10 秒查询一次。生成失败时 processStatusfailed,错误原因见 failCode


两阶段生成

将播客生成拆分为两个独立阶段:先生成脚本文本,确认或编辑后再触发音频渲染。适合需要在录制前审核内容、按需控制积分消耗的场景。

language 为必填参数,且所选 Speaker 的语言必须与 language 一致,否则返回 Speaker language mismatch 错误。

生成脚本

调用 POST /v1/podcast/episodes/text-content,只生成脚本文本,不触发音频渲染:

curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes/text-content" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "深入探讨量子计算的发展现状",
    "speakers": [
      {"speakerId": "CN-Man-Beijing-V2"},
      {"speakerId": "chat-girl-105-cn"}
    ],
    "language": "zh",
    "mode": "deep"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/podcast/episodes/text-content', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '深入探讨量子计算的发展现状',
    speakers: [
      { speakerId: 'CN-Man-Beijing-V2' },
      { speakerId: 'chat-girl-105-cn' },
    ],
    language: 'zh',
    mode: 'deep',
  }),
});
const data = await response.json();
const episodeId = data.data.episodeId;
console.log('Episode ID:', episodeId);
import os
import requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/podcast/episodes/text-content',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'query': '深入探讨量子计算的发展现状',
        'speakers': [
            {'speakerId': 'CN-Man-Beijing-V2'},
            {'speakerId': 'chat-girl-105-cn'},
        ],
        'language': 'zh',
        'mode': 'deep',
    }
)
data = response.json()
episode_id = data['data']['episodeId']
print('Episode ID:', episode_id)

响应示例

{
  "code": 0,
  "message": "",
  "data": {
    "episodeId": "{episodeId}",
    "message": "Text content generation started. Audio generation can be triggered later."
  }
}

等待脚本生成完成

轮询 GET /v1/podcast/episodes/{episodeId},直到 contentStatustext-success

curl -X GET "https://api.marswave.ai/openapi/v1/podcast/episodes/{episodeId}" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY"
const result = await fetch(`https://api.marswave.ai/openapi/v1/podcast/episodes/${episodeId}`, {
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
  },
});
const status = await result.json();
console.log('Content status:', status.data.contentStatus);
import os
import requests

result = requests.get(
    f'https://api.marswave.ai/openapi/v1/podcast/episodes/{episode_id}',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'}
)
status = result.json()
print('Content status:', status['data']['contentStatus'])

脚本就绪的响应contentStatustext-success):

{
  "code": 0,
  "message": "",
  "data": {
    "episodeId": "{episodeId}",
    "processStatus": "success",
    "contentStatus": "text-success",
    "credits": 15,
    "title": "量子计算的现在与未来",
    "outline": "...",
    "scripts": [
      {
        "speakerId": "CN-Man-Beijing-V2",
        "speakerName": "原野",
        "content": "大家好,今天我们来聊聊量子计算..."
      },
      {
        "speakerId": "chat-girl-105-cn",
        "speakerName": "晓曼",
        "content": "是的,量子计算是一个令人激动的领域..."
      }
    ]
  }
}

轮询时必须检查 contentStatus 字段,而非 processStatus。只有 contentStatus == "text-success" 时才能进入下一步。

(可选)编辑脚本

从上一步的响应中取出 scripts 数组,按需修改台词内容。

编辑脚本时只能修改 content 字段。speakerId 必须保持原值不变,且脚本中必须包含 1-2 个不同的音色——这是 API 的硬性限制。

编辑后的脚本在下一步生成音频时作为请求体传入。

生成音频

调用 POST /v1/podcast/episodes/{episodeId}/audio。不传 scripts 则使用原始脚本,传入则使用修改后的版本:

# 使用原始脚本
curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes/{episodeId}/audio" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json"

# 使用修改后的脚本
curl -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes/{episodeId}/audio" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scripts": [
      {
        "content": "大家好,欢迎收听本期播客,今天我们深入探讨量子计算...",
        "speakerId": "CN-Man-Beijing-V2"
      },
      {
        "content": "量子计算确实是一个革命性的技术...",
        "speakerId": "chat-girl-105-cn"
      }
    ]
  }'
// 使用原始脚本
await fetch(`https://api.marswave.ai/openapi/v1/podcast/episodes/${episodeId}/audio`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
});

// 使用修改后的脚本
await fetch(`https://api.marswave.ai/openapi/v1/podcast/episodes/${episodeId}/audio`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    scripts: [
      { content: '大家好,欢迎收听本期播客,今天我们深入探讨量子计算...', speakerId: 'CN-Man-Beijing-V2' },
      { content: '量子计算确实是一个革命性的技术...', speakerId: 'chat-girl-105-cn' },
    ],
  }),
});
import os
import requests

# 使用原始脚本
requests.post(
    f'https://api.marswave.ai/openapi/v1/podcast/episodes/{episode_id}/audio',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'}
)

# 使用修改后的脚本
requests.post(
    f'https://api.marswave.ai/openapi/v1/podcast/episodes/{episode_id}/audio',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'scripts': [
            {'content': '大家好,欢迎收听本期播客,今天我们深入探讨量子计算...', 'speakerId': 'CN-Man-Beijing-V2'},
            {'content': '量子计算确实是一个革命性的技术...', 'speakerId': 'chat-girl-105-cn'},
        ]
    }
)

等待音频生成完成

继续轮询同一接口,直到 contentStatusaudio-success

{
  "code": 0,
  "message": "",
  "data": {
    "episodeId": "{episodeId}",
    "processStatus": "success",
    "contentStatus": "audio-success",
    "credits": 42,
    "title": "量子计算的现在与未来",
    "audioUrl": "https://assets.listenhub.ai/podcast/{episodeId}.mp3",
    "audioStreamUrl": "https://assets.listenhub.ai/podcast/{episodeId}.m3u8",
    "scripts": [...]
  }
}

contentStatus 说明

含义下一步
text-success脚本生成完成可触发音频生成
text-fail脚本生成失败需重新创建
audio-success音频生成完成任务结束
audio-fail音频生成失败可重新调用音频生成接口

积分说明:第一阶段仅消耗文本生成积分,第二阶段仅消耗音频生成积分,总积分 = 两阶段之和。


On this page