SDK リファレンス
OpenAPIClient と ListenHubClient の全メソッドを製品ごとにまとめ、シグネチャ、エンドポイント、戻り値を掲載します。
@marswave/listenhub-sdk の完全なメソッドリファレンスです。メソッドは製品ごとにグループ分けしています。各項目には、シグネチャ、動作の 1 行説明、内部で呼び出される HTTP エンドポイントを記載しています。
SDK には 2 つのクライアントが含まれます。レスポンス処理は共通(code 0 なら data を展開し、それ以外は ListenHubError をスロー、429 は自動リトライ)ですが、対象とする API 面と認証方式が異なります。
OpenAPIClient | ListenHubClient | |
|---|---|---|
| 認証 | API キー(Authorization: Bearer) | OAuth ユーザーアクセストークン |
| Base URL | https://api.marswave.ai/openapi | https://api.listenhub.ai/api |
| 実行主体 | あなたのアカウント / キーの所有者 | サインイン中のユーザー |
| 用途 | サーバー、スクリプト、CI | ユーザー向けアプリ |
OpenAPIClient は公開 OpenAPI 製品であり、本リファレンスの中心です。ListenHubClient はファーストパーティアプリが使う OAuth クライアントで、そのメソッドは末尾の ListenHubClient メソッド にまとめています。
生成は非同期です。create* の呼び出しは即座に id を返します。対応する get* メソッドをポーリングし、processStatus(またはタスクの status)が pending / generating から抜けるまで待ってください。完全なループは クイックスタート を参照してください。
以下の表記ルールに従います。
- 「エンドポイント」のパスはクライアントの base URL からの相対パスです。
OpenAPIClientの場合はhttps://api.marswave.ai/openapi/です。 - メソッドは展開済みの
dataペイロードを返します。{ code, message, data }のエンベロープは SDK が処理します。 - 一部のメソッドは生の
Response(バイナリまたはストリーム)を返します — 該当する箇所では明示しています。 - クレジットのコストをハードコードしないでください。代わりに
estimate*CreditsメソッドとgetSubscription()を使ってください。
OpenAPIClient メソッド
Speakers(ボイス)
各ボイスは speakerId で識別されます。エピソードを作成する前にボイス一覧を取得し、使いたい id を渡してください。
| メソッド | エンドポイント | 戻り値 | 説明 |
|---|---|---|---|
listSpeakers(params?) | GET v1/speakers/list | { items: OpenAPISpeaker[] } | 利用可能なボイス |
listSpeakers のパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
language | string | 言語で絞り込み。例: en、zh、ja |
status | number | 利用可否での絞り込み |
各 OpenAPISpeaker は speakerId、name、gender、language、demoAudioUrl、および任意の profile(pitch、speed、traits、styles、scenes、accent、description)を持ちます。
const { items } = await client.listSpeakers({ language: 'en' });
const speakerId = items[0].speakerId;ListenHub Voice(AI 音声)
エンドツーエンドの音声生成(listenhub-voice-1.0): 単純なナレーション、効果音、単一ボイスの読み上げ、複数話者の対話、参考音声からのボイスクローン、画像からの音声生成に対応します。タスクを作成したら、status が success になるまで getListenHubVoiceTask をポーリングしてください。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createListenHubVoice(params) | POST v1/listenhub-voice/generate | { taskId, status } |
getListenHubVoiceTask(taskId) | GET v1/listenhub-voice/tasks/{taskId} | OpenAPIListenHubVoiceTaskDetail |
listListenHubVoiceTasks(params?) | GET v1/listenhub-voice/tasks | { items, page, pageSize, total } |
createListenHubVoice のパラメータ(OpenAPICreateListenHubVoiceParams):
| パラメータ | 型 | 説明 |
|---|---|---|
model | 'listenhub-voice-1.0' | 任意。既定値は listenhub-voice-1.0 |
text | string | 必須。最大 1400 文字。行の先頭に @音频1 / @音频2 を付けると、各ボイスにセリフを割り当てられます |
voices | Array<{ type: 'speaker'; id: string } | { type: 'reference'; url: string }> | 1〜3 件。プレーンテキスト / 効果音の場合は省略します。image とは排他 |
image | { url?: string; data?: string } | 画像から音声を生成する際の参考画像。url(http/https)または data(Base64)のいずれかを指定します。voices とは排他 |
audioConfig | { speechRate?; loudnessRate?; pitchRate?; format? } | speechRate / loudnessRate は -50〜100、pitchRate は -12〜12、format は 'mp3' | 'wav' | 'pcm' | 'ogg_opus'(既定値 mp3) |
durationHint | number | 目標の長さ 1〜110 秒。クレジット見積もりに影響します |
watermark | boolean | 音声ウォーターマークを付与します |
speaker の項目は組み込みボイス(ListenHub のボイスコード、またはプラットフォームの voice_type)を参照します。reference の項目は公開音声 URL からボイスをクローンします。複数話者の対話では 2〜3 件のボイスを列挙し、@音频N の接頭辞で配列の順に沿ってセリフを割り当てます。
OpenAPIListenHubVoiceTaskDetail には id、status(pending → generating → uploading → success | failed)、model、params(サニタイズ済みのエコー)、audioUrl(success 時)、audioDuration(課金対象の長さ)、creditCharged、creditRefunded、errorMessage(failed 時)、createdAt、updatedAt が含まれます。listListenHubVoiceTasks は { page?, pageSize?, status?, keyword? } を受け取ります。
const { taskId } = await client.createListenHubVoice({
text: 'Welcome to ListenHub. Here is your daily briefing.',
voices: [{ type: 'speaker', id: 'zh_female_warm' }],
durationHint: 20,
});
let task = await client.getListenHubVoiceTask(taskId);
while (task.status !== 'success' && task.status !== 'failed') {
await new Promise((r) => setTimeout(r, 3000));
task = await client.getListenHubVoiceTask(taskId);
}
if (task.status === 'success') console.log(task.audioUrl);Voice Cloning(ボイスクローン)
参考音声を再利用可能なプライベートボイスに変換します。アップロード、ポーリング、確定という流れで、得られた speakerId は speech、tts、audioSpeech で利用できます。対応はアップロード方式のみで、対話的な録音フローは Web 限定です。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createVoiceClone(params) | POST v1/voice-clone/clone | { taskId, status } |
getVoiceCloneTask(taskId) | GET v1/voice-clone/clone/{taskId} | OpenAPIVoiceCloneTaskDetail |
confirmVoiceClone(params) | POST v1/voice-clone/confirm | { speakerId } |
listVoiceCloneSpeakers() | GET v1/voice-clone/speakers | { speakers, quota, isLimitReached, maxSpeakers, remainingConfirmations } |
getVoiceCloneSpeaker(speakerId) | GET v1/voice-clone/speakers/{speakerId} | OpenAPIVoiceCloneSpeaker |
updateVoiceCloneSpeaker(speakerId, params) | PUT v1/voice-clone/speakers/{speakerId} | OpenAPIVoiceCloneSpeaker |
deleteVoiceCloneSpeaker(speakerId) | DELETE v1/voice-clone/speakers/{speakerId} | { speakerId } |
createVoiceClone のパラメータ(OpenAPICreateVoiceCloneParams)— SDK は multipart で送信します:
| パラメータ | 型 | 説明 |
|---|---|---|
audioFiles | Blob[] | 必須。1〜6 ファイル、1 ファイルあたり ≤5MB、合計 ≤20MB |
audioFilenames | string[] | 任意のファイル名。位置で対応付けられます |
language | 'zh' | 'en' | 'ja' | 必須 |
consentConfirmed | true | 必須。クローン対象者の同意を得ていることの宣言で、タスクとともに保存されます |
autoConfirm | boolean | クローン完了を検知したポーリングの中でそのまま確定します。name と gender が必要です |
name | string | ボイス名。最大 50 文字 |
gender | 'male' | 'female' | 'other' | ボイスの性別 |
useCredits | boolean | クォータを使い切った後の 300 クレジット課金を許可します。既定値は false |
OpenAPIVoiceCloneTaskDetail には 3 つの終了形があります。errorCode / errorMessage を伴う status: 'failed'、demoAudioUrl があり speakerId がない status: 'completed'(自動確定でボイスを保存できなかった場合は confirmError も付きます)、そして speakerId が存在する場合はボイスが保存済みであることを意味します。同一アカウントでの同時確定は 429、依存サービスが利用できない場合は 503 を返します。どちらもリトライ可能で、課金は発生しません。
const { taskId } = await client.createVoiceClone({
audioFiles: [referenceBlob],
audioFilenames: ['reference.mp3'],
language: 'en',
consentConfirmed: true,
});
let task = await client.getVoiceCloneTask(taskId);
while (task.status === 'pending' || task.status === 'processing') {
await new Promise((r) => setTimeout(r, 5000));
task = await client.getVoiceCloneTask(taskId);
}
if (task.status === 'failed') throw new Error(task.errorMessage);
const { speakerId } = await client.confirmVoiceClone({
taskId,
name: 'My API Voice',
gender: 'female',
});
await client.speech({ scripts: [{ content: 'Hello from my own voice.', speakerId }] });Podcast(ポッドキャスト)
ポッドキャストは query や sources から生成される複数話者の会話です。作成後、processStatus が success になるまで getPodcast をポーリングしてください。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createPodcast(params) | POST v1/podcast/episodes | { episodeId } |
getPodcast(episodeId) | GET v1/podcast/episodes/{episodeId} | OpenAPIPodcastDetail |
createPodcastTextContent(params) | POST v1/podcast/episodes/text-content | { episodeId, message } |
generatePodcastAudio(episodeId, params?) | POST v1/podcast/episodes/{episodeId}/audio | { success, message, episodeId, status } |
getPodcastTextStream(episodeId, event) | GET v1/podcast/episodes/{episodeId}/text-stream | 生の Response(ストリーム) |
createPodcast のパラメータ(OpenAPICreatePodcastParams):
| パラメータ | 型 | 説明 |
|---|---|---|
query | string | エピソードで扱う内容 |
sources | Array<{ type: 'text' | 'url'; content: string }> | 根拠となる素材。生テキストまたはページ URL |
speakers | Array<{ speakerId: string }> | 必須。ボイスごとに 1 件 |
language | string | 出力言語 |
mode | string | 生成の深さ(例: quick、deep) |
テキスト生成と音声生成を 2 段階に分けることで、音声に課金する前に台本を確認・編集できます。createPodcastTextContent は台本のみを生成し、その後 generatePodcastAudio(episodeId, { scripts }) が(必要に応じて書き換えた)台本から音声をレンダリングします。getPodcastTextStream(episodeId, 'script' | 'outline') は台本 / アウトラインのトークンをリアルタイムに受け取るためのストリーミング Response を返します。
OpenAPIPodcastDetail には processStatus、title、outline、cover、audioUrl、audioStreamUrl、subtitlesUrl、scripts(話者ごとのセリフ)、credits、および失敗時の failCode が含まれます。
Flow Speech / TTS
flow speech はテキストまたは URL を 1 つ以上のボイスによるナレーション音声に変換します。TTS エンドポイントはより低レベルで、明示的に指定した台本から音声を合成します。
Flow speech
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createFlowSpeech(params) | POST v1/flow-speech/episodes | { episodeId } |
getFlowSpeech(episodeId) | GET v1/flow-speech/episodes/{episodeId} | OpenAPIFlowSpeechDetail |
createFlowSpeechTTS(params) | POST v1/flow-speech/episodes/tts | { episodeId } |
getFlowSpeechTextStream(episodeId, event) | GET v1/flow-speech/episodes/{episodeId}/text-stream | 生の Response(ストリーム) |
createFlowSpeech のパラメータ(OpenAPICreateFlowSpeechParams):
| パラメータ | 型 | 説明 |
|---|---|---|
sources | Array<{ type: 'text' | 'url'; content?: string; uri?: string }> | 必須。テキストなら content、URL なら uri |
speakers | Array<{ speakerId: string }> | 必須 |
language | string | 出力言語 |
mode | 'smart' | 'direct' | smart はナレーション向けに書き換え、direct はそのまま読み上げます |
createFlowSpeechTTS は scripts: Array<{ content: string; speakerId: string }> と任意の title を受け取り、各行をそのままレンダリングします。テキストストリームの event は 'script' | 'outline' です。
OpenAPIFlowSpeechDetail には processStatus、title、outline、cover、audioUrl、audioStreamUrl、subtitlesUrl、scripts、sourceProcessResult が含まれます。
TTS / speech
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
speech(params) | POST v1/speech | OpenAPISpeechResponse |
tts(params) | POST v1/tts | 生の Response(音声バイト列) |
audioSpeech(params) | POST v1/audio/speech | 生の Response(音声バイト列) |
speech は scripts: Array<{ content: string; speakerId: string }> を受け取り、同期的な結果 { audioUrl, audioDuration, subtitlesUrl?, taskId, credits } を返します。
tts と audioSpeech は OpenAI 互換の単一ボイス合成です。{ input, voice, response_format? } を受け取り、response_format は mp3(既定値)、opus、aac、flac、wav、pcm のいずれかです。音声は生の Response として返るため、.arrayBuffer() で読み取るか .body をストリーミングしてください。
const res = await client.tts({ input: 'Hello world', voice: speakerId, response_format: 'mp3' });
const audio = Buffer.from(await res.arrayBuffer());Storybook(解説動画 / スライド)
Storybook はページ単位のビジュアルコンテンツ、つまり解説動画とスライドを生成します。形式は mode で選びます。音声は skipAudio によって任意です。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createStorybook(params) | POST v1/storybook/episodes | { episodeId } |
getStorybook(episodeId) | GET v1/storybook/episodes/{episodeId} | OpenAPIStorybookDetail |
generateStorybookVideo(episodeId) | POST v1/storybook/episodes/{episodeId}/video | { success } |
createStorybook のパラメータ(OpenAPICreateStorybookParams):
| パラメータ | 型 | 説明 |
|---|---|---|
sources | Array<{ type: 'text' | 'url'; content: string }> | 必須の根拠素材 |
speakers | Array<{ speakerId: string }> | 任意。音声を生成する場合のみ必要です |
mode | 'info' | 'story' | 'slides' | スライドなら slides、解説動画なら info / story |
skipAudio | boolean | true ならビジュアルのみを出力します |
style | string | ビジュアルスタイルのヒント |
language | string | 出力言語 |
エピソードが成功した後、generateStorybookVideo(episodeId) が各ページからダウンロード可能な動画をレンダリングします。getStorybook をポーリングして videoStatus(not_generated → pending → success / fail)を確認してください。成功すると videoUrl が現れます。
OpenAPIStorybookDetail には mode、processStatus、title、cover、audioUrl、audioDuration、videoUrl、videoStatus、pages(各ページに text、pageNumber、imageUrl、audioTimestamp)が含まれます。
Image(画像)
1 回の呼び出しで完結する画像生成です。OpenAPIClient にポーリング用の別メソッドはなく、レスポンスに結果が含まれます。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createImage(params) | POST v1/images/generation | OpenAPICreateImageResponse |
createImage のパラメータ(OpenAPICreateImageParams):
| パラメータ | 型 | 説明 |
|---|---|---|
provider | string | 必須の画像プロバイダー |
model | string | プロバイダーのモデル |
prompt | string | 必須のテキストプロンプト |
referenceImages | Array<{ fileData?; inlineData? }> | 参考画像 — fileData: { fileUri, mimeType } または inlineData: { data, mimeType }(base64) |
imageConfig | { imageSize?; aspectRatio? } | imageSize: 1K | 2K | 4K、aspectRatio: 16:9 | 4:3 | 1:1 | 3:4 | 9:16 | 21:9 |
Video(SeeDance / HappyHorse + PixVerse)
2 つの動画ファミリーはポーリング / 一覧 / 見積もりのメソッドを共有しますが、作成メソッドとパラメータが異なります。SeeDance(doubao-seedance-2-*)と HappyHorse は content 配列を使い、PixVerse は capability ベースの形式を使います。
SeeDance / HappyHorse
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createVideoGeneration(params) | POST v1/video-generation/generate | { taskId, status } |
getVideoGenerationTask(taskId) | GET v1/video-generation/tasks/{taskId} | OpenAPIVideoGenerationTaskDetail |
listVideoGenerationTasks(params?) | GET v1/video-generation/tasks | { items, page, pageSize, total } |
estimateVideoCredits(params) | POST v1/video-generation/estimate-credits | { tokens, credits } |
createVideoGeneration のパラメータ(OpenAPICreateVideoGenerationParams):
| パラメータ | 型 | 説明 |
|---|---|---|
model | 'doubao-seedance-2-pro' | 'doubao-seedance-2-fast' | 'happyhorse' | 既定値は SeeDance のモデル |
content | VideoContentItem[] | 必須。テキスト / 画像 / 動画 / 音声の項目を混在させます(下記参照) |
resolution | '480p' | '720p' | '1080p' | 1080p は doubao-seedance-2-pro のみ。happyhorse に 480p はありません |
ratio | '16:9' | '4:3' | '1:1' | '3:4' | '9:16' | '21:9' | '4:5' | '5:4' | 4:5 / 5:4 は happyhorse のみ |
duration | number | 秒数。SeeDance は最小 4、HappyHorse は最小 3 |
generateAudio | boolean | 音声トラックを生成します |
seed | number | 再現性のためのシード |
inputVideoDuration | number | 動画編集の入力用。SeeDance は [2,15]、HappyHorse は [3,60] |
audioSetting | 'auto' | 'origin' | HappyHorse の動画編集のみ。content に video_url が含まれる場合に有効 |
content の各項目は次のいずれかです。
{ type: 'text', text }{ type: 'image_url', image_url: { url }, role: 'first_frame' \| 'last_frame' \| 'reference_image' }{ type: 'video_url', video_url: { url }, role: 'reference_video' }{ type: 'audio_url', audio_url: { url }, role: 'reference_audio' }
HappyHorse は last_frame と audio_url の項目を受け付けません。estimateVideoCredits は { model, resolution, duration, hasVideoInput?, inputVideoDuration?, ratio? } を受け取ります。
const { taskId } = await client.createVideoGeneration({
model: 'doubao-seedance-2-pro',
content: [{ type: 'text', text: 'A timelapse of a city at dusk' }],
resolution: '1080p',
duration: 5,
});PixVerse
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createPixVerseVideoGeneration(params) | POST v1/video-generation/pixverse/generate | { taskId, episodeId?, status } |
estimatePixVerseVideoCredits(params) | POST v1/video-generation/pixverse/estimate-credits | { tokens, credits } |
PixVerse のタスクのポーリングと一覧取得には、上記と同じ getVideoGenerationTask / listVideoGenerationTasks を使います。
createPixVerseVideoGeneration のパラメータ(OpenAPICreatePixVerseVideoParams):
| パラメータ | 型 | 説明 |
|---|---|---|
capability | 'text_to_video' | 'image_to_video' | 'transition' | 'multi_transition' | 'fusion' | 'restyle' | 'mimic' | 'lip_sync' | 'agent' | 必須。生成モードを選択します |
model | 'pixverse' | 'v6' | 'v5' | 'v4.5' | PixVerse のモデルバージョン |
language | 'zh' | 'en' | サービスリージョン。en は国際版、zh は中国本土 |
prompt | string | テキストプロンプト |
duration | number | 秒数(1〜60、agent は 20/30/60) |
aspectRatio | '9:16' | '16:9' | '1:1' | '4:3' | '3:4' | 出力アスペクト比 |
quality | '360p' | '540p' | '720p' | '1080p' | mimic は 720p に固定、agent は 720p/1080p が必要 |
sourceTaskId | string | 成功済みの過去タスクを再利用します(restyle / lip_sync) |
images / videos / audios | Array<{ url; duration? }> | 入力アセット |
pixverse | OpenAPIPixVerseOptions | capability ごとのネストしたオプション |
ネストした pixverse オブジェクトは agentType、motionMode、cameraMovement、templateId、multiTransition、imageReferences、tts、soundEffect*、lipSyncTts*、brandSticker、introOutroClip をカバーします。どれが関係するかは capability によって決まります。estimatePixVerseVideoCredits は { capability, model?, language?, duration?, quality?, pixverse? } を受け取り、見積もり用に pixverse の形式は簡略化されています。
Music(音楽)
音楽エンドポイントは既定で Mureka プロバイダーを使います。非同期エンドポイントはタスク({ taskId, taskType, status })を返すので getMusicTask をポーリングしてください。同期エンドポイント(recognizeMusic、describeMusic、stemMusic)は結果を直接返します。
| メソッド | エンドポイント | 戻り値 | 同期? |
|---|---|---|---|
createMusicGenerate(params) | POST v1/music/generate | CreateMusicTaskResponse | 非同期 |
createMusicCover(params) | POST v1/music/cover | CreateMusicTaskResponse | 非同期(非推奨) |
createMusicExtend(params) | POST v1/music/extend | CreateMusicTaskResponse | 非同期 |
createMusicRemix(params) | POST v1/music/remix | CreateMusicTaskResponse | 非同期 |
createMusicInstrumental(params) | POST v1/music/instrumental | CreateMusicTaskResponse | 非同期 |
createMusicSoundtrack(params) | POST v1/music/soundtrack | CreateMusicTaskResponse | 非同期 |
createMusicTrack(params) | POST v1/music/track | CreateMusicTaskResponse | 非同期 |
recognizeMusic(params) | POST v1/music/recognize | RecognizeMusicResponse | 同期 |
describeMusic(params) | POST v1/music/describe | DescribeMusicResponse | 同期 |
stemMusic(params) | POST v1/music/stem | StemMusicResponse | 同期 |
getMusicTask(taskId) | GET v1/music/tasks/{taskId} | MusicTaskDetail | — |
listMusicTasks(params?) | GET v1/music/tasks | { items, page, pageSize, total } | — |
主な作成パラメータ:
createMusicGenerate:{ prompt?, lyrics?, model?, style?, title?, instrumental?, vocalId? }。modelはauto、mureka-7.6、mureka-8、mureka-9、mureka-o2のいずれかです。createMusicExtend:{ uploadUrl, model, continueAt, prompt?, style?, title?, instrumental?, negativeTags?, vocalGender?, styleWeight?, weirdnessConstraint?, audioWeight? }。ここでのmodelは Suno のバージョン(V4、V4_5、V4_5PLUS、V4_5ALL、V5、V5_5)です。createMusicRemix:{ audio?, audioFilename?, audioUrl?, providerSongId?, lyrics, prompt }。audio/audioUrl/providerSongIdのうち、ちょうど 1 つを指定します。非推奨のcreateMusicCoverではなく、こちらを使ってください。createMusicInstrumental:{ prompt?, referenceAudio?, referenceAudioFilename?, model? }。promptとreferenceAudioのどちらか一方を指定します。createMusicSoundtrack:{ image?, video?, prompt?, model? }。imageとvideoのどちらか一方を指定します。createMusicTrack:{ audio?, providerSongId?, generateType, prompt, lyrics?, vocalGender?, generateStart?, generateEnd? }。generateTypeでステム(Vocals、Instrumental、Drumsなど)を選びます。generateTypeがVocalsの場合はlyricsが必須です。
multipart のエンドポイント(remix、instrumental、soundtrack、track、recognize、describe、stem)は、音声 / 画像 / 動画のフィールドに Blob/File を受け取ります。Node 20 以降では new Blob([buffer]) でバッファをラップしてください。
const { taskId } = await client.createMusicGenerate({
prompt: 'lo-fi hip hop, mellow, rainy night',
model: 'auto',
});
let task = await client.getMusicTask(taskId);
while (task.status === 'pending' || task.status === 'generating') {
await sleep(10_000);
task = await client.getMusicTask(taskId);
}
console.log(task.tracks[0]?.audioUrl);同期エンドポイントの結果: recognizeMusic はタイムスタンプ付きの lyricsSections を返します。describeMusic は { description, tags, genres, instruments } を返します。stemMusic は { zipUrl, midiZipUrl, expiresAt } を返します(リンクは約 24 時間で期限切れになります)。
Content Extract(コンテンツ抽出)
URL から読みやすいコンテンツ(記事本文、任意で要約)を抽出します。非同期処理なので、作成してからポーリングしてください。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createContentExtract(params) | POST v1/content/extract | { taskId } |
getContentExtract(taskId) | GET v1/content/extract/{taskId} | OpenAPIContentExtractDetail |
createContentExtract のパラメータ(OpenAPICreateContentExtractParams):
| パラメータ | 型 | 説明 |
|---|---|---|
source | { type: 'url'; uri: string } | 必須。抽出対象のページ |
options | { summarize?; maxLength?; twitter? } | summarize は要約を追加します。twitter: { count? } はスレッドの深さを指定します |
status が completed になるまで getContentExtract をポーリングしてください。詳細には data.content、data.metadata、data.references、credits が含まれます。
Subscription(サブスクリプション)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
getSubscription() | GET v1/user/subscription | OpenAPISubscriptionInfo |
クレジット残高とプラン情報を返します: totalAvailableCredits、月次 / 永久 / 期間限定クレジットの内訳、resetAt、renewStatus、paidStatus、subscriptionPlan。コストの高いジョブの前には totalAvailableCredits で残高を確認してください。
Files(ファイル)
OpenAPIClient に専用のファイルアップロードメソッドはありません。ローカルファイルを入力として使うには、公開 URL でホストしてその URL を渡してください(たとえば source の uri、referenceImages.fileData.fileUri、動画の image_url.url として)。事前署名付きアップロードのフローは ListenHubClient にあります — 下記の Files を参照してください。
ListenHubClient メソッド
ListenHubClient は OAuth ユーザーアクセストークンで認証し、https://api.listenhub.ai/api を対象とします。ファーストパーティアプリ向けの API 面を提供します。製品の形式は OpenAPIClient と異なり、エピソードはネストした template オブジェクトを使い、作成メソッドは製品ごと(ポッドキャスト、TTS、解説動画、スライド)に分かれています。このクライアントは、各リクエストが個々のサインイン済みユーザーのもとで実行される場合にのみ使ってください。
Auth & session(認証とセッション)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
connectInit(params) | POST v1/auth/connect/init | { sessionId, authUrl } |
connectToken(params) | POST v1/auth/connect/token | { accessToken, refreshToken, expiresIn } |
refresh(params) | POST v1/auth/token | { accessToken, refreshToken, expiresIn } |
revoke(params) | POST v1/auth/token/revoke | void |
connectInit({ callbackPort }) はデバイス / OAuth フローを開始し、開くべき authUrl を返します。connectToken({ sessionId, code }) はその結果をトークンと交換します。refresh({ refreshToken }) は期限切れが近いアクセストークンをローテーションし、revoke({ refreshToken }) はそれを無効化します。
Speakers(ボイス)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
listSpeakers(params?) | GET v1/settings/speakers | { items: Speaker[] } |
パラメータ: { language?, status? }。戻り値の形式が OpenAPIClient とは異なる点に注意してください — 各 Speaker は speakerId ではなく speakerInnerId を公開し、さらに personality、accessType、weight を持ちます。エピソードの template.speakers 配列が期待するのは speakerInnerId です。
Voice Cloning(ボイスクローン)
サインイン済みユーザー向けのファーストパーティのクローンフローです。参考音声をアップロードし、ポーリングして、プライベートボイスとして確定します。この API 面は zh と en のみを受け付け、confirmVoiceClone はペイロードなしで解決します — スピーカー ID は listVoiceCloneSpeakers から読み取ってください。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createVoiceClone(params) | POST v1/voice-clone/clone | { taskId, status } |
getVoiceCloneTask(taskId) | GET v1/voice-clone/clone/{taskId} | { status, demoAudioUrl? } |
confirmVoiceClone(params) | POST v1/voice-clone/confirm | void |
listVoiceCloneSpeakers() | GET v1/voice-clone/speakers | { speakers, quota, isLimitReached, maxSpeakers, remainingConfirmations } |
getVoiceCloneSpeaker(speakerId) | GET v1/voice-clone/speakers/{speakerId} | VoiceCloneSpeaker |
updateVoiceCloneSpeaker(speakerId, params) | PUT v1/voice-clone/speakers/{speakerId} | VoiceCloneSpeaker |
deleteVoiceCloneSpeaker(speakerId) | DELETE v1/voice-clone/speakers/{speakerId} | { speakerId } |
createVoiceClone は { audioFiles: Blob[], audioFilenames?: string[], language: 'zh' | 'en' } を受け取り、confirmVoiceClone は { taskId, name, gender, useCredits? } を受け取ります。API キーの API 面とは異なり、クローンが失敗した場合はボディに失敗を返すのではなく ListenHubError でリジェクトされ、自動確定はありません。
Podcast(ポッドキャスト)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createPodcast(params) | POST v1/episodes/all-in-one | { episodeId } |
listPodcasts(params?) | GET v1/episodes(productId=aiPodcast) | ListEpisodesResponse |
createPodcast のパラメータ(CreatePodcastParams):
| パラメータ | 型 | 説明 |
|---|---|---|
type | 'podcast-solo' | 'podcast-duo' | 1 人または 2 人のホスト |
query | string | トピック |
sources | ContentSource[] | { type: 'url' | 'text'; uri?; content? } |
template | { type: 'podcast'; mode; speakers; language } | mode: quick | deep | debate、speakers: speakerInnerId[]、language: en | zh | ja |
Flow Speech / TTS
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createTTS(params) | POST v1/episodes/flow-speech | { episodeId } |
listTTS(params?) | GET v1/episodes(productId=textToSpeech) | ListEpisodesResponse |
createTTS のパラメータ(CreateTTSParams): { sources, template: { type: 'flowspeech', mode: 'smart' | 'direct', speakers, language } }。
Storybook(解説動画 / スライド)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createExplainerVideo(params) | POST v1/episodes/storybook | { episodeId } |
createSlides(params) | POST v1/episodes/storybook(mode: 'slides'、skipAudio: true) | { episodeId } |
exportExplainerVideo(episodeId) | POST v1/episodes/{episodeId}/storybook/video | void |
listExplainerVideos(params?) | GET v1/episodes(productId=explainerVideo) | ListEpisodesResponse |
listSlides(params?) | GET v1/episodes(productId=slideDeck) | ListEpisodesResponse |
createExplainerVideo と createSlides は同じ形式を共有します: { query?, sources?, style?, styleOverride?, skipAudio?, imageConfig?, template }。template は type: 'storybook'、mode(解説動画なら info / story、スライドなら slides)、speakers、language、および任意の style、size(2K / 4K)、aspectRatio(16:9 / 9:16 / 1:1)、pageCount を持ちます。createSlides は skipAudio を既定で true にし、mode を slides に固定します。exportExplainerVideo はダウンロード可能な動画のレンダリングを開始します。
Episodes(共通)
これらは ListenHubClient の 4 製品すべてで動作します。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
getCreation(episodeId) | GET v5/episodes/{episodeId}/detail | EpisodeDetail |
deleteCreations(params) | DELETE v1/episodes | void |
getCreation は完全な EpisodeDetail(ステータス、話者、タイトル / アウトライン / 音声 / 動画 / ページ / 台本を含む topicDetail)を返します。deleteCreations({ ids }) は id を指定して最大 100 件のエピソードを一括ソフト削除します。動画エピソードの id を渡すと、その動画タスクもソフト削除され、進行中のタスクがあればクレジットが返還されます。製品ごとの list* メソッドはいずれも productId フィルタ付きの GET v1/episodes を呼び出し、{ page?, pageSize? } を受け取ります。
Image(画像)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createAIImage(params) | POST v1/images | { imageId } |
getAIImage(imageId) | GET v1/images/{imageId} | AIImageItem |
listAIImages(params?) | GET v1/images | { items, pagination } |
deleteAIImages(params) | DELETE v1/images | void |
createAIImage のパラメータ(CreateAIImageParams):
| パラメータ | 型 | 説明 |
|---|---|---|
prompt | string | 必須 |
referenceImageUrls | string[] | 参考画像の URL |
language | 'auto' | 'en' | 'ja' | 'ko' | 'hi' | 'zh' | 'pt' | 'es' | プロンプトの言語 |
aspectRatio | '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '9:16' | '16:9' | '21:9' | … | 出力比率 |
imageSize | '1K' | '2K' | '4K' | 出力解像度 |
model | 'gemini-3-pro-image' | 'gemini-3.1-flash-image' | 画像モデル |
isLossless | boolean | ロスレスエンコード |
enableSearch | boolean | 根拠づけのための Web 検索を許可します |
生成は非同期です — status が終了状態になり imageUrl が設定されるまで getAIImage(imageId) をポーリングしてください。deleteAIImages({ ids }) は最大 100 件の画像を一括ソフト削除します(所有者のスコープ内。未知の id は無視されます)。
Music(音楽)
ListenHubClient は OpenAPIClient と同じ音楽メソッド群(同じエンドポイント、同じパラメータ)を公開します: createMusicGenerate、createMusicCover、createMusicExtend、createMusicRemix、createMusicInstrumental、createMusicSoundtrack、createMusicTrack、recognizeMusic、describeMusic、stemMusic、getMusicTask、listMusicTasks。パラメータとポーリングループは上記の Music を参照してください。
Lyrics(歌詞)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createLyrics(params) | POST v1/lyrics/generate | { taskId, status } |
getLyricsTask(taskId) | GET v1/lyrics/tasks/{taskId} | LyricsTaskDetail |
listLyricsTasks(params?) | GET v1/lyrics/tasks | { items, page, pageSize, total } |
createLyrics({ prompt }) は非同期の歌詞タスクを開始します。status が success になるまで getLyricsTask をポーリングし、その後 variants(各要素は { text, title, status })を読み取ってください。
Video Generation(動画生成)
ListenHubClient は OpenAPIClient と同じ動画メソッドを公開しますが、命名に 1 点だけ違いがあります。SeeDance / HappyHorse の見積もりメソッドは estimateVideoGenerationCredits です(OpenAPIClient では estimateVideoCredits)。
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createVideoGeneration(params) | POST v1/video-generation/generate | { taskId, status } |
getVideoGenerationTask(taskId) | GET v1/video-generation/tasks/{taskId} | VideoGenerationTaskDetail |
listVideoGenerationTasks(params?) | GET v1/video-generation/tasks | { items, page, pageSize, total } |
estimateVideoGenerationCredits(params) | POST v1/video-generation/estimate-credits | { tokens, credits } |
createPixVerseVideoGeneration(params) | POST v1/video-generation/pixverse/generate | { taskId, episodeId?, status } |
estimatePixVerseVideoCredits(params) | POST v1/video-generation/pixverse/estimate-credits | { tokens, credits } |
パラメータは上記の Video セクションと同じです。
Subscription & user(サブスクリプションとユーザー)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
getCurrentUser() | GET v1/users/me | UserProfile |
getSubscription() | GET v1/users/subscription | SubscriptionInfo |
getSettings() | GET v2/settings | SettingsResponse |
エンドポイントが OpenAPIClient とは異なる点に注意してください(v1/users/subscription と v1/user/subscription)。getSettings はユーザーが保存した製品ごとの既定値(スピーカー、言語、長さ、モード、スタイル画像)を返します。
Checkin(チェックイン)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
checkinSubmit() | POST v1/checkin | { checkinDate, rewardCredits } |
checkinStatus() | GET v1/checkin/status | CheckinStatusResponse |
報酬クレジットのための毎日のチェックインです。checkinStatus は hasCheckedInToday、lastCheckinTime、monthlyCheckinCount を返します。
Settings / API key
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
getApiKey() | GET v1/settings/api-key | { key } |
regenerateApiKey() | POST v1/settings/api-key/regenerate | { key } |
サインイン済みユーザーが自分の OpenAPI キーを読み取ったりローテーションしたりできます。regenerateApiKey は以前のキーを無効化します。
Files(ファイル)
| メソッド | エンドポイント | 戻り値 |
|---|---|---|
createFileUpload(params) | POST v1/files | { presignedUrl, fileUrl } |
getFileDownloadUrl(fileUrl) | GET v1/files | { downloadUrl } |
createFileUpload({ fileKey, contentType, category }) は、バイト列を PUT するための presignedUrl と、以後の参照に使う fileUrl を返します。getFileDownloadUrl(fileUrl) は保存済みのファイル URL に再署名し、期限付きの downloadUrl を返します。
client.api エスケープハッチ
ListenHubClient は、SDK がラップしていないエンドポイント向けに、内部の ky インスタンスを client.api として公開しています。認証、base URL、リトライの挙動は共通ですが、レスポンスは自分でパースします。パスは base URL からの相対で、先頭に / を付けません(ky の要件)。
const me = await client.api.get('v1/users/me').json();OpenAPIClient は client.api を公開しません。SDK がまだカバーしていない OpenAPI エンドポイントを呼ぶには、同じ Authorization: Bearer ヘッダーを付けて自前の HTTP クライアントから呼び出してください — OpenAPI リファレンス を参照してください。
エラー
すべてのメソッドは、code が 0 以外の場合や HTTP エラーの場合に ListenHubError をスローします。このエラーは status、code、requestId を持ちます — 問題を報告する際は requestId を添えてください。
import { ListenHubError } from '@marswave/listenhub-sdk';
try {
await client.getPodcast('nope');
} catch (err) {
if (err instanceof ListenHubError) {
console.error(`[${err.status}] code ${err.code} (request ${err.requestId})`);
} else {
throw err;
}
}