▸ Agent Skills
5 min read

{ “title”: “Streaming Text to Speech”, “endpoint”: “wss://api.x.ai/v1/tts”, “description”: “Bidirectional streaming text-to-speech via WebSocket. Send text incrementally and receive audio chunks in real time. Shares the /v1/tts path with the batch POST endpoint — a GET with Upgrade: websocket activates streaming mode. Configuration is done via query parameters at connection time. Supports multi-utterance: after audio.done, send another stream of text.delta messages on the same connection.”,

“authentication”: { “headers”: [ { “name”: “Authorization”, “type”: “string”, “required”: true, “description”: “Bearer token for authentication. Use your xAI API key.”, “example”: “Bearer $XAI_API_KEY” } ] },

“queryParameters”: [ { “name”: “voice”, “type”: “string”, “required”: false, “description”: “Voice identifier. Use a built-in voice from GET /v1/tts/voices (e.g. eve, ara) or a custom voice ID.”, “default”: “eve” }, { “name”: “language”, “type”: “string”, “required”: true, “description”: “BCP-47 language code (e.g. en, zh, pt-BR) or auto for automatic language detection. Case-insensitive.”, “enum”: [ “auto”, “en”, “ar-EG”, “ar-SA”, “ar-AE”, “bn”, “zh”, “fr”, “de”, “hi”, “id”, “it”, “ja”, “ko”, “pt-BR”, “pt-PT”, “ru”, “es-MX”, “es-ES”, “tr”, “vi” ] }, { “name”: “codec”, “type”: “string”, “required”: false, “description”: “Audio codec for the output.”, “default”: “mp3”, “enum”: [“mp3”, “wav”, “pcm”, “mulaw”, “alaw”] }, { “name”: “sample_rate”, “type”: “integer”, “required”: false, “description”: “Sample rate in Hz.”, “default”: “24000”, “enum”: [8000, 16000, 22050, 24000, 44100, 48000] }, { “name”: “bit_rate”, “type”: “integer”, “required”: false, “description”: “Bit rate in bps. Only applies when codec is mp3.”, “default”: “128000”, “enum”: [32000, 64000, 96000, 128000, 192000] }, { “name”: “optimize_streaming_latency”, “type”: “integer”, “required”: false, “description”: “Latency optimization level. 0 (default): No optimization — best audio quality. 1: Reduced first-chunk size for lower time-to-first-audio, with minor quality tradeoff at chunk boundaries.”, “default”: “0”, “enum”: [0, 1] }, { “name”: “speed”, “type”: “number”, “required”: false, “description”: “Speech speed multiplier. 1.0 is normal speed. Values below 1.0 slow down speech, values above 1.0 speed it up. Range: 0.7 to 1.5.”, “default”: “1.0” }, { “name”: “text_normalization”, “type”: “boolean”, “required”: false, “description”: “Enable text normalization before synthesis. When enabled, the model normalizes written-form text (e.g. numbers, abbreviations, symbols) into spoken-form before generating audio.”, “default”: “false” }, { “name”: “with_timestamps”, “type”: “boolean”, “required”: false, “description”: “Return per-character timing metadata on each audio.delta event. When true, every audio.delta carries audio_timestamps.”, “default”: “false” } ],

“clientMessages”: [ { “type”: “text.delta”, “description”: “Send a chunk of text to be synthesized. Text is processed incrementally — audio generation begins as soon as enough text is buffered. Individual deltas are capped at 15,000 characters.”, “schema”: { “type”: “object”, “required”: [“type”, “delta”], “properties”: { “type”: { “type”: “string”, “description”: “Must be text.delta.” }, “delta”: { “type”: “string”, “description”: “Text chunk to synthesize. Supports speech tags like [laugh], [pause], [whisper].” } } }, “example”: { “type”: “text.delta”, “delta”: “Hello! Welcome to streaming text to speech. “ } }, { “type”: “text.done”, “description”: “Signal that all text for this utterance has been sent. The server will finish generating audio and send audio.done. After receiving audio.done, you can start a new utterance with another text.delta.”, “schema”: { “type”: “object”, “required”: [“type”], “properties”: { “type”: { “type”: “string”, “description”: “Must be text.done.” } } }, “example”: { “type”: “text.done” } } ],

“serverMessages”: [ { “type”: “audio.delta”, “description”: “A chunk of base64-encoded audio data. Decode and append to your audio buffer or pipe directly to playback. The format matches the codec and sample_rate specified in the query parameters. When the connection was opened with with_timestamps=true, the event also carries audio_timestamps and audio_duration for the characters that fall inside this chunk.”, “schema”: { “type”: “object”, “properties”: { “type”: { “type”: “string”, “description”: “Always audio.delta.” }, “delta”: { “type”: “string”, “description”: “Base64-encoded audio data chunk.” }, “audio_timestamps”: { “type”: “object”, “description”: “Per-character forced-alignment timings for this chunk. Present only when the connection was opened with with_timestamps=true. Times are session-relative seconds, so they are directly comparable across chunks within an utterance.”, “properties”: { “graph_chars”: { “type”: “array”, “description”: “Each character covered by this audio chunk, in order. Includes spaces, punctuation, and any speech tag characters from the original input.”, “items”: { “type”: “string” } }, “graph_times”: { “type”: “array”, “description”: “Parallel array of [start, end] seconds for each entry in graph_chars.”, “items”: { “type”: “array”, “items”: { “type”: “number”, “format”: “double” }, “minItems”: 2, “maxItems”: 2 } } } }, “audio_duration”: { “type”: “number”, “format”: “double”, “description”: “Duration of this audio chunk in seconds. Present only when the connection was opened with with_timestamps=true.” } } }, “example”: { “type”: “audio.delta”, “delta”: “<Base64EncodedAudioData>”, “audio_timestamps”: { “graph_chars”: [“H”, “e”, “l”, “l”, “o”], “graph_times”: [ [0.0, 0.06], [0.06, 0.12], [0.12, 0.18], [0.18, 0.24], [0.24, 0.34] ] }, “audio_duration”: 0.34 } }, { “type”: “audio.done”, “description”: “Audio generation for this utterance is complete. The connection remains open for multi-utterance — send another text.delta to start a new synthesis, or close the connection.”, “schema”: { “type”: “object”, “properties”: { “type”: { “type”: “string”, “description”: “Always audio.done.” }, “trace_id”: { “type”: “string”, “description”: “Unique trace identifier for this utterance. Useful for debugging.” } } }, “example”: { “type”: “audio.done”, “trace_id”: “550e8400-e29b-41d4-a716-446655440000” } }, { “type”: “error”, “description”: “An error occurred during synthesis. The connection may be closed after this message.”, “schema”: { “type”: “object”, “properties”: { “type”: { “type”: “string”, “description”: “Always error.” }, “message”: { “type”: “string”, “description”: “Human-readable error description.” } } }, “example”: { “type”: “error”, “message”: “TTS failed: internal error” } } ],

“exampleFlow”: [ { “direction”: “client”, “type”: “text.delta” }, { “direction”: “client”, “type”: “text.delta” }, { “direction”: “client”, “type”: “text.done” }, { “direction”: “server”, “type”: “audio.delta” }, { “direction”: “server”, “type”: “audio.delta” }, { “direction”: “server”, “type”: “audio.delta” }, { “direction”: “server”, “type”: “audio.done” } ] }


Last updated Oct 08, 2026