The Streaming TTS API uses WebSockets for real-time text-to-speech. You connect once, stream text chunks, fetch base64 audio chunks as they become available, and send a commit message to save the session and get the processing summary.
This endpoint only supports text chunks with character lengths between 10 and 100
This endpoint requires an Integrator Account

Runtime limits

Max session lifetime: 300 seconds
Max idle time between text chunks input: 60 seconds
Min text characters count: 10
Max text characters count: 100

Endpoint

wss://infer.voice.intron.io/tts/v1/stream

Authentication

All requests require a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_KEY

Connection query parameters

The websocket route reads these values from request.args.get(...).
ParameterTypeDescriptionRequiredDefault
voice_accentStringAccent for the speech voiceyessee page of supported accents
voice_genderStringAccent for the speech voiceyesmale / female
voice_languageStringLanguage of the input textnosee page of supported languages,en
output_audio_formatStringSpecify the output audio formatnosee list of supported audio formats below,wav

Supported Output Audio Formats

FormatExtensions
WAV.wav
OPUS.opus

Supported Language And Accents

Supported Languages And Accents

Comprehensive list of languages and accents supported

WebSocket handshake examples

wscat -c 'wss://infer.voice.intron.io/tts/v1/stream' \
	-H 'Authorization: Bearer YOUR_API_KEY'

Input message types

INPUT_TEXT_CHUNK

FieldTypeRequiredDescription
message_typeStringYesMust be INPUT_TEXT_CHUNK
textStringYesthe input text
ack_idIntegerNoClient chunk sequence ID echoed by server ACK
JSON
{
	"message_type": "INPUT_TEXT_CHUNK",
	"text": "<text>",
	"ack_id": 1
}

FETCH_AUDIO_CHUNK

FieldTypeRequiredDescription
message_typeStringYesMust be FETCH_AUDIO_CHUNK
chunk_idIntegerNoid of the input text chunk
JSON
{
	"message_type": "FETCH_AUDIO_CHUNK",
	"chunk_id": 1
}

COMMIT

FieldTypeRequiredDescription
message_typeStringYesMust be COMMIT
JSON
{
	"message_type": "COMMIT"
}

Session Responses

Sent immediately after successful authentication, capacity checks, and quota checks. It returns the active session_id, current credit balance, and the effective stream configuration.
JSON
{
	"message_type": "SESSION_CREATED",
	"session_id": "12a9760f-b165-4404-91d0-a65d4cdt78fs",
	"credit_balance": 120.0,
	"configs": {
		"voice_language": "en",
        "voice_accent": "yoruba",
        "voice_gender": "yo",
        "output_audio_format": "wav"
	}
}
Sent after the server accepts and stores a text chunk. The server echoes the client ack_id when present, otherwise it uses the running chunk count.
JSON
{
	"message_type": "TEXT_CHUNK_ACK",
	"chunck_id": 1,
	"total_chunks": 1
}
This is sent in response to the request FETCH_AUDIO_CHUNK,with the base64 audio is available, the processing_status is READY when that chunk is fully processed with a base64 audio else it’s PROCESSING
JSON
{
	"message_type": "FETCH_AUDIO_CHUNK",
	"processing_staus": "PROCESSING"
    "chunk_id": 1
    "audio_base_64": ""
    "extension": ".wav"
    "audio_config_num_channels": 1
    "audio_config_sample_width": 16
    "audio_config_frame_rate": 48000
    "total_duration_in_seconds": 10
    "total_size_in_bytes": 1000
    "total_size_in_kb": 1
}
Sent after the client sends COMMIT and the backend finishes processing the full stream. This is the summary payload for the session.
JSON
{
	"message_type": "COMMITTED_AUDIO",
	"text_id": "e1c4a90b-e319-4de6-9f22-0e0cf5e8b7a2",
	"audio_len": 10
}

Error and Terminal Responses

Sent for unexpected server-side failures that do not map to a more specific websocket error message.
JSON
{
	"message_type": "ERROR",
	"message": "connection error"
}
Sent when the request payload is invalid, such as malformed JSON, an invalid message structure, invalid request data.
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "invalid input message_type received"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "Invalid data structure for text chunk"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "Invalid request data for fetch audio chunk,ensure chunk id is integer"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "Missing chunk_id to fetch audio chunk"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "Invalid data structure for commit audio request"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "no data received"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "invalid input message_type received"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "invalid input data"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "Commit request already received, cannot accept more text chunks"
}
JSON
{
	"message_type": "INPUT_ERROR",
	"message": "Error processing data"
}
Sent when the Authorization header is missing, invalid, or the access key fails authentication. The server closes the connection after sending this message.
JSON
{
	"message_type": "AUTHENTICATION_ERROR",
	"message": "permission denied,access-key error"
}
Sent when the service does not currently have enough available capacity to accept the stream. The status field indicates the capacity state returned by the backend.
JSON
{
	"message_type": "RESOURCE_EXHAUSTED",
	"status": "CAPACITY_NOT_AVAILABLE"
}
Sent when the authenticated user or entity has insufficient credits or has exceeded an allowed usage limit. The server closes the connection after sending this message.
JSON
{
	"message_type": "QUOTA_EXCEEDED",
	"credits_balance": "0",
	"message": "insufficient credits balance"
}
Sent when the websocket session exceeds the maximum allowed session lifetime.
JSON
{
	"message_type": "SESSION_TIME_LIMIT_EXCEEDED",
	"session_time_limit": "300"
}
Sent when no text chunk has been received for longer than the allowed idle timeout while the session is still active.
JSON
{
	"message_type": "INSUFFICIENT_TEXT_ACTIVITY",
	"message": "insufficient text activity detected,exceed max idle time of 60 seconds"
}
Sent when the provided sequential integer ack_id in the INPUT_TEXT_CHUNK request does match the count total chunks sent.
JSON
{
	"message_type": "CHUNK_ID_MISMATCH_WITH_TOTAL",
	"chunk_id_input": 20
	"chunk_id_expected": 3
	"chunk_id_total": 2
}
Sent when the received text chunk character count is smaller than the minimum required.
JSON
{
	"message_type": "CHUNCK_SIZE_TOO_SMALL",
	"chunk_size_min": "10"
}
Sent when the received text chunk character count is larger than the maximum allowed.
JSON
{
	"message_type": "CHUNK_SIZE_TOO_LARGE",
	"chunk_size_max": "100"
}

Typical flow

  1. Open websocket connection with query parameters and Authorization header.
  2. Receive SESSION_CREATED.
  3. Send INPUT_TEXT_CHUNK messages repeatedly.
  4. Send FETCH_AUDIO_CHUNK requests to get the base64 audio when READY
  5. Send COMMIT when done streaming audio.
  6. Receive COMMITTED_AUDIO and the connection closes.