ListenHubOpenAPI
API リファレンス

解説動画

あらゆるコンテンツを、AI が生成した画像と音声ナレーション付きの解説動画に変換します。

解説動画では、テキストや URL からナレーション付きのビジュアルコンテンツを作成できます。2 つのモードがあります:

info(デフォルト)story
用途知識解説、製品紹介ストーリー共有、事例紹介
画像スタイルインフォグラフィック、イラスト、データビジュアライゼーションストーリーシーンのイラスト
1 ページ目雑誌風の表紙ストーリーの表紙

mode パラメータは任意で、デフォルトは info です。


エピソードを作成する

POST /v1/storybook/episodes

AI が生成した画像とナレーションを含む解説動画のエピソードを作成します。

sources は最大 1 件、speakers は最大 1 件までです。

Info モード(デフォルト):

curl -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [
      {"type": "url", "uri": "https://example.com/article", "content": "https://example.com/article"}
    ],
    "speakers": [
      {"speakerId": "<SPEAKER_ID>"}
    ],
    "language": "en",
    "mode": "info"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/storybook/episodes', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    sources: [{ type: 'url', uri: 'https://example.com/article', content: 'https://example.com/article' }],
    speakers: [{ speakerId: '<SPEAKER_ID>' }],
    language: 'en',
    mode: 'info',
  }),
});
const data = await response.json();
console.log(data);
import os, requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/storybook/episodes',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'sources': [{'type': 'url', 'uri': 'https://example.com/article', 'content': 'https://example.com/article'}],
        'speakers': [{'speakerId': '<SPEAKER_ID>'}],
        'language': 'en',
        'mode': 'info',
    }
)
print(response.json())

Story モード

curl -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [
      {"type": "text", "content": "The founding story of a small startup that grew into a global platform..."}
    ],
    "speakers": [
      {"speakerId": "<SPEAKER_ID>"}
    ],
    "language": "en",
    "mode": "story"
  }'
const response = await fetch('https://api.marswave.ai/openapi/v1/storybook/episodes', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    sources: [{ type: 'text', content: 'The founding story of a small startup that grew into a global platform...' }],
    speakers: [{ speakerId: '<SPEAKER_ID>' }],
    language: 'en',
    mode: 'story',
  }),
});
const data = await response.json();
console.log(data);
import os, requests

response = requests.post(
    'https://api.marswave.ai/openapi/v1/storybook/episodes',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
    json={
        'sources': [{'type': 'text', 'content': 'The founding story of a small startup that grew into a global platform...'}],
        'speakers': [{'speakerId': '<SPEAKER_ID>'}],
        'language': 'en',
        'mode': 'story',
    }
)
print(response.json())

レスポンス

{
  "code": 0,
  "message": "",
  "data": {
    "episodeId": "{episodeId}"
  }
}

リクエストパラメータ

パラメータ必須説明
sourcesarray(1)はいコンテンツソース。最大 1 件。
sources[].typestringはい"text" または "url"
sources[].contentstringはいテキストコンテンツまたは URL
sources[].uristringtype が url の場合は必須ソースの URI
sources[].metadataobjectいいえソースのメタデータ
speakersarray(1)はい音声設定。最大 1 件。
speakers[].speakerIdstringはい話者 ID(話者一覧 を参照)
languagestringいいえ言語コード(例:"en""zh"
modestringいいえ"info"(デフォルト)または "story"
stylestringいいえビジュアルスタイル ID

エピソードのステータスを照会する

GET /v1/storybook/episodes/{episodeId}

返された episodeId を使って、processStatussuccess になるまでポーリングします。

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

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

レスポンスprocessStatussuccess のとき):

{
  "code": 0,
  "message": "",
  "data": {
    "episodeId": "{episodeId}",
    "createdAt": 1700000000,
    "mode": "info",
    "processStatus": "success",
    "credits": 30,
    "title": "How AI Is Changing the World",
    "cover": "https://assets.listenhub.ai/covers/{episodeId}.png",
    "audioUrl": "https://assets.listenhub.ai/storybook/{episodeId}.mp3",
    "audioDuration": 180,
    "videoUrl": "",
    "videoStatus": "not_generated",
    "pages": [
      {
        "text": "Artificial intelligence has transformed industries worldwide...",
        "pageNumber": 1,
        "imageUrl": "https://assets.listenhub.ai/pages/{episodeId}-1.png",
        "audioTimestamp": 0
      },
      {
        "text": "From healthcare to finance, AI applications continue to expand...",
        "pageNumber": 2,
        "imageUrl": "https://assets.listenhub.ai/pages/{episodeId}-2.png",
        "audioTimestamp": 25.3
      }
    ]
  }
}

素材pages[] の各要素には imageUrl(AI が生成した画像)と text(ナレーション原稿)が含まれます。これらは個別にダウンロードして、自分のコンテンツに利用できます。

processStatus

意味
pending処理中
success完了
fail失敗(failCode を確認)

videoStatus

意味
not_generated動画生成がまだトリガーされていない
pending動画を生成中
success動画の準備完了(videoUrl が利用可能)
fail動画の生成に失敗

生成には通常 2–5 分かかります。推奨のポーリング方法:60 秒待ってから、10 秒ごとにポーリングします。


動画を生成する

POST /v1/storybook/episodes/{episodeId}/video

完了したエピソードの動画生成をトリガーします。processStatussuccess である必要があります。

このエンドポイントを呼び出す前に、processStatussuccess になるまで待ってください。

curl -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes/{episodeId}/video" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY"
const response = await fetch(
  `https://api.marswave.ai/openapi/v1/storybook/episodes/${episodeId}/video`,
  {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
  }
);
console.log(await response.json());
import os, requests

response = requests.post(
    f'https://api.marswave.ai/openapi/v1/storybook/episodes/{episode_id}/video',
    headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'}
)
print(response.json())

レスポンス

{
  "code": 0,
  "message": "",
  "data": {
    "success": true
  }
}

トリガー後は、videoStatussuccess になるまで GET /v1/storybook/episodes/{episodeId} をポーリングします。


完全なワークフロー

エピソードを作成する

コンテンツソース、話者、モード(info または story)を指定して POST /v1/storybook/episodes を呼び出します。返された episodeId を保存してください。

完了までポーリングする

最初に 60 秒待ってから、processStatussuccess になるまで GET /v1/storybook/episodes/{episodeId} を 10 秒ごとにポーリングします。

素材を利用する(任意)

pages[] 配列には、各ページの AI 生成画像(imageUrl)とナレーション原稿(text)が含まれます。動画を生成せずに、そのまま利用できます。

動画を生成する

POST /v1/storybook/episodes/{episodeId}/video を呼び出して、各ページをナレーション付きの動画に合成します。

動画ステータスをポーリングする

videoStatussuccess になるまでポーリングします。videoUrl フィールドにダウンロードリンクが入ります。

このページの内容