Developers
VoiceoverWise REST API
Generate voiceovers from your own app or pipeline, with your pronunciation dictionary and smart reading applied. Available on every account.
Authentication
Create an API key in Dashboard → Settings → API key. Keys start with vw_live_ and are shown once. Send the key as a bearer token and JSON bodies with Content-Type: application/json:
curl https://voiceoverwise.com/api/v1/voices \
-H "Authorization: Bearer vw_live_your_key"
Rate limits & errors
Up to 60 requests per minute per key. Errors return a JSON body {"error": "message"} with a standard HTTP status: 400 invalid input, 401 invalid key, 402 not enough credits, 404 not found, 409 not ready yet, 410 audio expired (files are kept 30 days), 429 rate limited, 503 generation temporarily unavailable.
Voices
Lists voices (id, name, tone, gender, best for) and delivery styles (id, name).
{ "voices": [ { "id": "nova", "name": "Nova", "tone": "Bright and friendly", … } ],
"styles": [ { "id": "natural", "name": "Natural narrator" }, …, { "id": "custom", "name": "Custom direction" } ] }Speech
Creates a voiceover. Credits equal to the script's character count are reserved immediately and returned if generation fails. Returns 202; generation usually takes a few seconds per minute of audio.
{
"text": "Plans start at $29. [pause] Call (816) 555-0123.", // required, up to 20,000 chars
"voice": "nova", // see /voices
"style": "natural", // or "custom" with "direction": "calm, slow, like a museum guide"
"pace": "normal", // slow | normal | fast
"format": "mp3", // mp3 | wav
"smart": true, // smart reading on/off
"title": "Pricing intro" // optional, used for file names
}Status and details. When status is done, audioUrl and subtitlesUrl are set (they need the same bearer token).
{ "speech": { "id": "clp_…", "status": "done", "chars": 49, "credits": 49,
"durationMs": 4210, "format": "mp3", "audioUrl": "https://voiceoverwise.com/api/v1/speech/clp_…/audio",
"subtitlesUrl": "https://voiceoverwise.com/api/v1/speech/clp_…/subtitles.srt", "expiresAt": "…" } }The audio file (audio/mpeg or audio/wav). Supports range requests.
The SRT subtitle file.
Your most recent voiceovers.
Batches
Up to 200 scripts with shared settings, each up to 3,000 characters. Pass rows (array of {"title","text"}), csv (with "title" and "text" columns) or lines (one script per line), plus the same voice settings as /speech.
{ "name": "Product audio", "voice": "coral", "rows": [ { "title": "earbuds", "text": "…" } ] }Progress and every clip in the batch, plus zipUrl once files are available.
All finished audio files and their subtitles in one ZIP.
Quickstart
const KEY = process.env.VOICEOVERWISE_API_KEY;
const api = (path, opts = {}) => fetch('https://voiceoverwise.com/api/v1' + path, {
...opts, headers: { Authorization: 'Bearer ' + KEY, 'Content-Type': 'application/json' }
});
const { speech } = await (await api('/speech', {
method: 'POST',
body: JSON.stringify({ text: 'Welcome to our store!', voice: 'coral', style: 'warm' })
})).json();
let s = speech;
while (s.status === 'queued' || s.status === 'processing') {
await new Promise(r => setTimeout(r, 2000));
s = (await (await api('/speech/' + s.id)).json()).speech;
}
if (s.status === 'done') {
const audio = Buffer.from(await (await api('/speech/' + s.id + '/audio')).arrayBuffer());
require('fs').writeFileSync('welcome.mp3', audio);
}
Credits
Current balance, split into free and purchased credits, with expiry dates.
{ "balance": 284500, "free": 10000, "purchased": 274500, "lots": [ … ] }Use of the API is subject to the Terms of Service and the Acceptable Use Policy. See pricing for credit packs.