Skip to main content
flag
Mon - Fri   10:00 – 18:00

Voice Broadcast with Text to Speech

API Documentation / Voice Broadcast / Voice Broadcast with Text to Speech

Base URL for your account: https://cpaas.studio

GET POST /api/voice/v1/broadcast/tts

Sends a broadcast whose audio is spoken from text. Two modes — send exactly one: (1) template_id + variables: an approved TTS template from your account, with a value for each of its variables; open to every voice.broadcast key. (2) text: free text; only for keys with audio auto-approval. Asynchronous: the response is 202 "preparing" — poll Broadcast with TTS Status. Every different message is a new audio: it costs TTS credits and takes a few seconds (up to about 30 for some voices) before dialling starts.

Template mode works with every voice.broadcast key. Free text needs a key with audio auto-approval enabled (contact support).

Parameters

Param Type Required Notes
did string yes Same as Voice Broadcast: the phone number of one of your active broadcast DIDs.
numbers array or string yes Same as Voice Broadcast. Maximum 1,000 numbers per request. In template mode every number hears the same values.
template_id string one of template_id/text Template mode. The id of an approved template (TTS Templates lists them, e.g. TPL7K2M9QX4WQ). Not with text.
variables object template mode One value per template variable: JSON {"name": "Anil"}, or variables[name]=Anil in a query string / form. Each value 1–30 characters after trimming, no line breaks or { }. Spoken as typed. Keys the template does not use are ignored.
text string one of template_id/text Free-text mode — keys with audio auto-approval only. The message to speak, up to 5,000 characters. Not with template_id.
language string no Free text: language code (e.g. en, hi, ml), default en; must be enabled for your account. Template mode: the template's language is used — if you send language it must be the same.
gender string yes female or male. If the language has no voice of that gender, the available voice is used.
speed number no 0.5–2.0. Defaults to 1.0.
schedule_at string (date) no As Voice Broadcast. If the time passes while the audio is being prepared, the broadcast is sent immediately.
ring_time / retry_count / retry_interval integer no As Voice Broadcast.
reference string, max 64 no Your label; also set on the broadcast (and, for free text, the audio asset). Status can be looked up by it.
name string, max 255 no Broadcast label. Defaults to reference or a generated label.
audio_uid / audio_reference / caller_id — do not supply Rejected on this endpoint — the audio comes from the text or template, the caller id from did.

Request example

curl -X POST "https://cpaas.studio/api/voice/v1/broadcast/tts" \
  -H "X-API-KEY: cpk_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8b1e0c4a-2f7d-4e59-9a61-3c5d2e7f9b10" \
  -d '{
    "did": "9876500000",
    "numbers": ["9876543210", "9876543211"],
    "template_id": "TPL7K2M9QX4WQ",
    "variables": {"customer_name": "Anil", "amount": "1500"},
    "gender": "female",
    "reference": "bill-4471"
  }'
<?php
$ch = curl_init('https://cpaas.studio/api/voice/v1/broadcast/tts');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-API-KEY: cpk_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        'Idempotency-Key: 8b1e0c4a-2f7d-4e59-9a61-3c5d2e7f9b10',
        'Content-Type: application/json',
    ],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode([
        'did' => '9876500000',
        'numbers' => ['9876543210', '9876543211'],
        'template_id' => 'TPL7K2M9QX4WQ',
        'variables' => ['customer_name' => 'Anil', 'amount' => '1500'],
        'gender' => 'female',
        'reference' => 'bill-4471',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# One number, its own values — e.g. an OTP. Each different code is a new audio.
curl "https://cpaas.studio/api/voice/v1/broadcast/tts?did=9876500000&numbers=9876543210&template_id=TPL3OTP8K2M4Q&variables[code]=4%208%202%201&gender=female" \
  -H "X-API-KEY: cpk_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Free text — keys with audio auto-approval only.
curl -X POST "https://cpaas.studio/api/voice/v1/broadcast/tts" \
  -H "X-API-KEY: cpk_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -d "did=9876500000" \
  -d "numbers=9876543210,9876543211" \
  -d "text=Your order 4471 has been shipped. Thank you for shopping with us." \
  -d "language=en" -d "gender=female" -d "speed=1" \
  -d "reference=order-4471"

Success response (data)

{
    "id": "TTB4M8Q2ZK7RX",
    "reference": "bill-4471",
    "status": "preparing",
    "tts": {
        "language": "en",
        "gender": "female",
        "speed": 1
    },
    "credits_estimated": {
        "voice.broadcast": 2,
        "voice.tts": 7
    },
    "template": {
        "id": "TPL7K2M9QX4WQ",
        "name": "Bill reminder"
    },
    "audio": null,
    "items": {
        "total": 1,
        "ready": 0,
        "failed": 0
    },
    "broadcast": null,
    "error": null,
    "created_at": "2026-10-05T13:10:00+00:00",
    "completed_at": null
}

Errors

Code Status When
TTS_TEMPLATE_NOT_FOUND 404 template_id doesn't match any template on your account.
TTS_TEMPLATE_NOT_APPROVED 422 The template is pending or rejected. error.details.status says which.
TTS_TEMPLATE_VARIABLE_MISSING 422 A template variable has no value. error.details.variables lists every variable with a problem (name, problem, message).
TTS_TEMPLATE_VARIABLE_INVALID 422 A value is longer than 30 characters, has a line break or control character, or contains { }. error.details.variables says which.
TTS_AUTO_APPROVAL_REQUIRED 403 Free text with a key that does not have audio auto-approval. Use a template instead.
TTS_LANGUAGE_UNAVAILABLE 422 The language (yours, or the template's) is not enabled for your account. error.details.available_languages lists the ones that are.
BCAST_DID_INVALID 422 did doesn't match any of your account's active, voice.broadcast-enabled DIDs.
BCAST_NO_VALID_NUMBERS 422 Every submitted number was invalid or a duplicate.
BCAST_ALL_NUMBERS_INVALID 422 Every submitted number failed format normalization.
BILLING_INSUFFICIENT_CREDITS 402 Your voice.broadcast or voice.tts balance does not cover this request. error.details shows needed vs balance for each.
REQ_SCHEDULE_IN_PAST 422 schedule_at is already in the past.
REQ_IDEMPOTENCY_KEY_CONFLICT 409 The Idempotency-Key matches a prior request with a different body (including different variables).
REQ_VALIDATION_FAILED 422 Both or neither of text/template_id, language different from the template's, missing gender/did/numbers, audio_uid/audio_reference/caller_id supplied, or any other field rule failure.

Notes

  • Asynchronous: 202 means accepted and preparing — the broadcast does not exist yet. Poll Broadcast with TTS Status with the returned id (or your reference).
  • Every different message is a new audio: it costs TTS credits (per word) and takes a few seconds before dialling — about 1–2 s on hosted voices, up to about 30 s on some Indian-language voices. Sending exactly the same message again (same text/values, language, gender, speed) reuses the audio with no TTS charge.
  • OTP and other per-number messages: send one request per number with its own variables. Every code is a new audio, so expect the TTS charge and the delay on each one.
  • Template mode: template is {id, name} and audio is always null — the audio is internal. Free text: template is null and audio is {audio_uid, reused}; the audio stays in your Audio Library (type broadcast).
  • Once status is "submitted", the response contains the broadcast (same shape as Voice Broadcast) — use its id with Voice Broadcast Number Status for per-number results. A number whose audio could not be prepared shows status no_audio there: not dialled, not charged.
  • If preparation fails, status is "failed" with error.code: TTS_GENERATION_FAILED (no TTS credits charged), AUDIO_DELIVERY_FAILED, TTS_UNAVAILABLE, TTS_TEMPLATE_NOT_APPROVED (template edited while preparing), BILLING_INSUFFICIENT_CREDITS, BCAST_DID_INVALID, etc. Send a new request to try again.
  • Credits are checked up front for both voice.tts (per word) and voice.broadcast (per number), and charged as they are used — TTS when the audio is made, broadcast per chunk as calls go out.

Need more context? See Getting started for authentication, the response envelope, and the full error-code reference.