Text to speech API

Text to speech API with voice cloning and a TypeScript SDK

VoiceLabs has a REST API for text to speech and voice cloning at https://app.voicelabs.now/v1: send text, get speech in one of your own voices. The models run on our GPU servers, so there is nothing to host. Call it with a plain HTTP request, with the OpenAI-compatible speech endpoint, or with the @voicelabs/sdk package. API access is part of VoiceLabs Pro.

Make your first request

Create a key in the developer console, on the API keys tab, and tick the scopes it needs. Keys begin with vl_sandbox_… and go in an x-api-key header; an Authorization: Bearer header works too. This starts a generation and downloads the audio:

# 1. Start a generation. It answers at once with an id.
curl https://app.voicelabs.now/v1/speech \
  -H "x-api-key: $VOICELABS_API_KEY" \
  -H "content-type: application/json" \
  -d '{"text":"Welcome back. The briefing is ready.","voice_name":"Narrator"}'

# 2. Poll until status is "completed"; the answer then carries an audio_url.
curl https://app.voicelabs.now/v1/generations/GENERATION_ID \
  -H "x-api-key: $VOICELABS_API_KEY"

# 3. Follow audio_url. The link is signed, so it needs no key.
#    Add &format=mp3 (or opus, wav) to have it re-encoded.
curl "AUDIO_URL&format=mp3" --output speech.mp3

POST /v1/speech is asynchronous because speech is GPU work: it answers at once with a generation id, and GET /v1/generations/{generationId} returns the signed audio_url once the audio exists. The link is short-lived and carries its own proof, so it needs no key.

An OpenAI-compatible speech endpoint

If your code already sends an OpenAI-compatible speech request, point it here: change the base URL to https://app.voicelabs.now/v1 and the key to a VoiceLabs key. POST /v1/audio/speech holds the request open until the audio is ready and returns the bytes, so there is nothing to poll.

curl https://app.voicelabs.now/v1/audio/speech \
  -H "x-api-key: $VOICELABS_API_KEY" \
  -H "content-type: application/json" \
  -d '{"model":"chatterbox","voice":"Narrator","input":"Welcome back. The briefing is ready.","response_format":"mp3"}' \
  --output speech.mp3

What each field takes

  • model: a VoiceLabs engine id (qwen, qwen_custom_voice, luxtts, chatterbox, chatterbox_turbo, tada, kokoro) to choose the engine. The compatibility names tts-1, tts-1-hd, gpt-4o-mini-tts, gpt-4o-mini-tts-2025-12-15 are accepted so an existing client keeps working, but they select nothing: the voice’s own default engine is used.
  • voice: the id or name of a voice on your account, listed by GET /v1/voices. A preset name from another service is not a VoiceLabs voice and is refused.
  • input: the text, up to 10,000 characters.
  • response_format: mp3, opus, wav; mp3 if you leave it out.
  • seed and temperature: VoiceLabs additions that pin a take so it can be reproduced. Only the chatterbox and chatterbox_turbo engines accept a temperature.

Anything VoiceLabs cannot do is refused with a 400 that names the field, never accepted and ignored: a speed other than 1, an event stream and containers it does not encode all fail loudly. The whole file is returned at once.

The TypeScript SDK

@voicelabs/sdk is the typed client for the same API. Install it with npm install @voicelabs/sdk. It has no runtime dependencies, ships ESM and CommonJS with types, and runs on Node 18 and later, Bun, Deno, Cloudflare Workers and in browsers. Field names are the wire names, so what you read here, in the OpenAPI document and in a curl response is one set of names.

import { writeFile } from "node:fs/promises";
import { VoiceLabs } from "@voicelabs/sdk";

const voicelabs = new VoiceLabs({ apiKey: process.env.VOICELABS_API_KEY! });

// Clone a voice from a short recording (the key needs the voice:clone scope).
const voice = await voicelabs.cloneVoice({
  name: "Narrator",
  reference_text: "The words spoken in the recording.",
  audio_url: "https://example.com/recording.wav",
});

// Speak in it. generateSpeech starts the job and waits for the audio.
const generation = await voicelabs.generateSpeech({
  text: "Welcome back. The briefing is ready.",
  voice_id: voice.id,
});

// The stored file is WAV.
const { bytes } = await voicelabs.downloadAudio(generation);
await writeFile("speech.wav", bytes);

Errors are typed: a spent monthly allowance, a rate limit and a missing scope each have their own class, so a retry loop does not hammer a limit that only the plan can lift. The package is MIT licensed and published on npm; the API docs say more.

Voice cloning over the API

POST /v1/voices/clone creates a cloned voice from a 2 to 30 second recording of clear speech, given as base64 audio or as the address of a public https file, together with the words spoken in it. It needs a key with the voice:clone scope, which is its own scope on purpose: a key made to generate speech was not made to build a voice from a recording. The response carries the new voice’s id, which you pass as voice_id to the speech endpoint. The voice lives on your account, so the studio, the MCP server and the browser extension list it too. Clone only a voice you have the right to use: the responsible use policy says what that means.

Every endpoint

  • GET /v1/voicesList voices. Needs the voice:read scope.
  • GET /v1/capturesList captures. Needs the voice:read scope.
  • GET /v1/generations/{generationId}Get a generation. Needs the voice:read scope.
  • POST /v1/speechCreate speech. Needs the voice:generate scope.
  • POST /v1/audio/speechCreate speech (OpenAI-compatible). Needs the voice:generate scope.
  • POST /v1/transcriptionsCreate a transcription. Needs the voice:generate scope.
  • POST /v1/voices/defaultEnsure the default voice. Needs the voice:generate scope.
  • POST /v1/voices/cloneClone a voice. Needs the voice:clone scope.
  • GET /v1/audio/{generationId}Download generated audio. Reached through a signed link, not a key.

The API reference documents every parameter and response, generated from the same OpenAPI 3.1 document the server publishes at https://app.voicelabs.now/openapi.json. Prefer an AI assistant to HTTP? The MCP server exposes the same voices as tools.

Limits, errors and the Pro gate

  • Pro only. On an account without an active subscription or trial, every request, reads included, is refused with 403 pro_plan_required. Keys are not revoked: the same key works again on the next request once the account is back on Pro.
  • Rate limits. Each key may make 600 requests an hour that do work, such as starting a generation. Reads are counted separately, at 300 requests a minute, so polling cannot lock you out of the next create. Responses carry RateLimit and RateLimit-Policy headers.
  • Errors you can branch on. Every error is an RFC 9457 problem document with a stable code. Branch on it, not on the status: rate_limit_exceeded clears by waiting, while quota_exhausted means the plan’s monthly audio is spent. Each code has a page of its own.
  • Safe retries. Send an Idempotency-Key header on a write and a retry replays the original response instead of generating twice.

Engines and languages

All seven text-to-speech engines are built on open-source models and hosted by us, and each has an id you can send as model to the compatible endpoint. Together they cover 23 languages.

  • Qwen3-TTSqwen
  • Qwen3-TTS CustomVoiceqwen_custom_voice
  • LuxTTSluxtts
  • Chatterbox Multilingualchatterbox
  • Chatterbox Turbochatterbox_turbo
  • TADAtada
  • Kokorokokoro

The engines page lists the upstream project behind each one, and the language index says which engines speak which language. For the case for hosted rather than local models, see cloud text to speech.

What it costs

One plan: VoiceLabs Pro, US$8 a month or US$59 a year, with a 7-day trial that asks for a card up front. It includes API access, voice cloning, all seven engines and 2 hours of generated audio a month (fair use). It is a flat subscription: no per-character fee and no usage bill. The pricing page has the detail.

Questions about the text to speech API

Is there a text to speech API with voice cloning?
Yes. VoiceLabs has a REST API at https://app.voicelabs.now/v1 that generates speech in your own voices and clones a voice from a short recording. The speech models run on our GPU servers, so there is nothing for you to host. The API includes an OpenAI-compatible speech endpoint and a TypeScript SDK, and API access is part of VoiceLabs Pro.The developer API docs
How do I authenticate with the VoiceLabs API?
With an API key. Create one in the developer console, on the API keys tab, and choose its scopes: voice:read to read voices and generations, voice:generate to make speech, voice:clone to create a cloned voice from a recording. Send the key in an x-api-key header, or as an Authorization: Bearer header if your HTTP client only does bearer auth. The secret is shown once, when you create it. On an account without an active Pro subscription or trial, every request is refused with 403 pro_plan_required.API keys, scopes and errors
Is there an OpenAI-compatible text to speech endpoint?
Yes: POST /v1/audio/speech accepts an OpenAI-compatible speech request, so a client written for that format only needs its base URL and API key changed (the base URL is https://app.voicelabs.now/v1). It answers synchronously with the audio itself, as mp3, opus and wav. Put a VoiceLabs engine id in model to choose the engine, and a voice id or name from your account in voice. Fields VoiceLabs cannot honour, such as a playback speed other than 1, are refused with a 400 that names the field, never ignored.Parameter by parameter
Is there a JavaScript or TypeScript SDK, and where do I get it?
Yes: @voicelabs/sdk on npm (npm install @voicelabs/sdk). It is MIT licensed, written by hand with no runtime dependencies, and runs on Node 18 and later, Bun, Deno, Cloudflare Workers and in browsers. It covers speech, voice cloning, transcription and reading your voices and generations, and gives a spent allowance, a rate limit and a missing scope each their own error class, so one is not mistaken for another. The API is also described by an OpenAPI 3.1 document, so any other language can generate a client from it.The SDK in the API docsAPI reference
How do I clone a voice through the API?
Call POST /v1/voices/clone with a name, the exact words spoken in the recording, and the recording itself: base64 audio, or the address of a public https file. The recording must be 2 to 30 seconds of clear speech, and the key needs the voice:clone scope, which is separate from voice:generate on purpose. The response is the new voice, whose id you pass as voice_id to the speech endpoint. Clone only a voice you have the right to use.Responsible use
What are the API's rate limits?
Each key may make 600 requests an hour that do work (POST requests, such as starting a generation). Reads, such as polling a generation, do not count against that, and have a separate ceiling of 300 requests a minute. Responses carry RateLimit and RateLimit-Policy headers, and a refused request is a 429 with a Retry-After. A 429 can mean different things: rate_limit_exceeded passes by waiting, while quota_exhausted means the plan's monthly audio is spent, so read the code field of the error rather than the status.Rate limits in the API docs
Which engines, languages and audio formats does the API support?
Seven engines built on open-source models, covering 23 languages in all, each with its own id you can send as model. One request takes up to 10,000 characters of text. The compatible endpoint returns mp3, opus and wav, and the signed audio link of an asynchronous generation serves the stored WAV file, or any of those formats if you append &format= to it.The enginesEvery language
How much does the text to speech API cost?
API access is included in VoiceLabs Pro, which is US$8 a month or US$59 a year, with a 7-day trial that asks for a card up front. Pro includes 2 hours of generated audio a month (fair use), all seven engines and voice cloning. It is a flat subscription: there is no per-character fee and no usage bill. You can also give one key a monthly ceiling in minutes of its own.Pricing

VoiceLabs Pro is US$8 a month or US$59 a year, with a 7-day trial. API access and voice cloning are included.

VoiceLabs is built on the open-source VoiceBox project (MIT), and that attribution is permanent. The hosted service, with its GPU inference, accounts and billing, is a commercial product from Devino Solutions.