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_KEYPoll 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
| HTTP | Meaning |
|---|---|
| 400 | Invalid text, parameters or upload |
| 401 | Missing, invalid or revoked key |
| 403 | Plan, consent or allowance restriction |
| 409 | Idempotency conflict |
| 429 | Rate or concurrency limit; retry later |
| 503 | Generation 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.