Create speech asynchronously and keep your application responsive. Pro includes API access. Requests share the plan’s audio allowance, concurrency limits and storage allowance.

1. Create an API key

Open Developer API in your workspace. Create a named key and copy the secret immediately. It is displayed only once. Send it as a Bearer token in the Authorization header; keep it on your server.

2. List available voices

curl https://cadencevoicelab.com/v1/voices \
  -H "Authorization: Bearer $VOICE_API_KEY"

Choose a speech model

List available models with GET /v1/speech-models. Each model includes its current display name, stable ID, supported languages, delivery controls and online status. Send its ID as modelId when generating. Display names can change; IDs stay the same. Check the voice’s supportedModels before choosing.

curl https://cadencevoicelab.com/v1/speech-models -H "Authorization: Bearer $VOICE_API_KEY"

3. Create a generation

Use an ID from the voices response. Reuse the same Idempotency-Key when retrying an identical request.

curl -X POST https://cadencevoicelab.com/v1/tts \
  -H "Authorization: Bearer $VOICE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" \
  -d '{"text":"Give your words a voice.","voiceId":"VOICE_UUID","language":"en","modelId":"chatterbox-v3","style":"natural"}'

JavaScript

const response = await fetch("https://cadencevoicelab.com/v1/tts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.VOICE_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({ text: "Hello, world.", voiceId, language: "en", modelId: "qwen3-tts" })
});
if (!response.ok) throw new Error(await response.text());
const { generations } = await response.json();

Python

import os, uuid, requests
response = requests.post("https://cadencevoicelab.com/v1/tts", headers={
    "Authorization": "Bearer " + os.environ["VOICE_API_KEY"],
    "Idempotency-Key": str(uuid.uuid4())
}, json={"text": "Hello, world.", "voiceId": voice_id, "language": "en", "modelId": "chatterbox-v3"}, timeout=30)
response.raise_for_status()
generation = response.json()["generations"][0]

4. Poll and retrieve the result

GET https://cadencevoicelab.com/v1/generations/{id}
Authorization: Bearer YOUR_API_KEY

Poll every 3–5 seconds. Status transitions through queued and processing to completed, failed or cancelled. Completed responses contain audioSeconds, mp3Url and an eligible wavUrl. Audio links expire after 15 minutes. Poll again to request fresh links.

Voice cloning

POST multipart/form-data to /v1/voice-clones with sample, name, language and consent=true. The consent requirement and plan voice limits apply. Upload 6–60 seconds of speech, at most 20 MB.

Errors and limits

HTTPMeaning
400Invalid text, parameters or upload
401Missing, invalid or revoked key
403Plan, consent or allowance restriction
409Idempotency conflict
429Rate or concurrency limit; retry later
503Generation or another required service is unavailable

Errors contain error.code, error.message and a requestId. Keep the request ID when contacting support. Never retry a payment by changing its idempotency key unless you intend a separate purchase.