You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import{OpenAPIClient}from'@marswave/listenhub-sdk';constclient=newOpenAPIClient({apiKey: 'lh_sk_...'});// or set LISTENHUB_API_KEY env var and call new OpenAPIClient()const{items: speakers}=awaitclient.listSpeakers({language: 'en'});const{episodeId}=awaitclient.createFlowSpeech({sources: [{type: 'text',content: 'Hello world'}],speakers: [{speakerId: speakers[0].speakerId}],});
OAuth (for client-side apps)
Clone the repo and run the OAuth login example — it opens a browser, handles the callback, and prints your tokens:
git clone https://github.com/marswaveai/listenhub-sdk.git
cd listenhub-sdk
pnpm i
npx tsx examples/oauth-login.ts
Client options
The SDK provides two clients for different auth modes:
// OpenAPI Key — server-side, no user login requiredconstopenapi=newOpenAPIClient({apiKey: 'lh_sk_...',// or LISTENHUB_API_KEY env varbaseURL: 'https://api.marswave.ai/openapi',// or LISTENHUB_OPENAPI_URL env vartimeout: 60_000,maxRetries: 2,});// OAuth access token — client-side, user login requiredconstclient=newListenHubClient({accessToken: 'token',// static string or () => string | undefinedbaseURL: 'https://api.listenhub.ai/api',timeout: 30_000,maxRetries: 2,});
Powered by the Mureka provider (the default). Generation endpoints are asynchronous —
they return a taskId; poll getMusicTask(taskId) until status is success.
Analysis endpoints (recognize / describe / stem) are synchronous.
File inputs accept a Blob (browser File, or new Blob([buffer]) in Node 18+).
Method
Kind
Description
createMusicGenerate(params)
async
Generate music from a text prompt / lyrics
createMusicRemix(params)
async
Re-create a song from existing audio + new lyrics
createMusicInstrumental(params)
async
Generate an instrumental (prompt or reference audio)
Seedance reference images/videos need dimensions for server-side validation. Put media URLs in
content, and put dimensions in top-level referenceImages / referenceVideos.
// Local image helper: uploads the image and reads width/height for Seedance validation.import{readFile}from'node:fs/promises';constfirstFrame=awaitclient.uploadVideoReferenceImage({file: newBlob([awaitreadFile('./cat.png')],{type: 'image/png'}),fileName: 'cat.png',role: 'first_frame',});awaitclient.createVideoGeneration({model: 'doubao-seedance-2-fast',content: [{type: 'text',text: 'A cat running through a garden'},firstFrame.content],referenceImages: [firstFrame.referenceImage],resolution: '720p',duration: 5,});// URL input: provide metadata explicitly.awaitclient.createVideoGeneration({model: 'doubao-seedance-2-fast',content: [{type: 'text',text: 'A cat running through a garden'},{type: 'image_url',image_url: {url: 'https://example.com/cat.jpg'},role: 'first_frame'},],referenceImages: [{role: 'first_frame',width: 1080,height: 1920,size: 3_600_000}],resolution: '720p',duration: 5,});
PixVerse uses a separate endpoint (createPixVerseVideoGeneration) with a capability-driven
request shape. Poll results with the shared getVideoGenerationTask / listVideoGenerationTasks.
List ListenHub Voice tasks with optional filtering
Constraints (enforced server-side): text <= 1400 chars; voices 1-3 items; voices and image are mutually exclusive; durationHint in [1, 110]. audioUrl is only present when status === 'success'.
// Single voice (id is a ListenHub speakerInnerId or an official platform voice_type)consttask=awaitclient.createListenHubVoice({text: '欢迎收听 ListenHub。',voices: [{type: 'speaker',id: 'zh_female_wanwanxiaohe_moon_bigtts'}],audioConfig: {format: 'mp3'},durationHint: 30,});// Multi-voice dialogue (each item should be a custom reference audio)awaitclient.createListenHubVoice({text: '@音频1 你好。@音频2 你也好。',voices: [{type: 'reference',url: 'https://example.com/voice-a.mp3'},{type: 'reference',url: 'https://example.com/voice-b.mp3'},],});// Image-to-audio (mutually exclusive with voices)awaitclient.createListenHubVoice({text: '为这张图配一段旁白。',image: {url: 'https://example.com/scene.jpg'},});constdetail=awaitclient.getListenHubVoiceTask(task.taskId);if(detail.status==='success'){console.log(detail.audioUrl,detail.audioDuration);}
List by product
Method
Description
listPodcasts(params?)
List podcast episodes
listTTS(params?)
List TTS episodes
listExplainerVideos(params?)
List explainer videos
listSlides(params?)
List slides
listAIImages(params?)
List AI-generated items
getCreation(episodeId)
Get full creation detail
deleteCreations({ids})
Batch delete creations (incl. AI video)
deleteAIImages({ids})
Batch delete AI images
Users
Method
Description
getCurrentUser()
Get current user profile
getSubscription()
Get subscription and credit usage info
Speakers
Method
Description
listSpeakers(params?)
List available speakers by language
Custom requests
client.api exposes the underlying ky instance for endpoints not yet covered by the SDK: