Text-to-SpeechREST API

Generate speech

Learn how to use and integrate the Soniox Text-to-Speech REST API.

Overview

The Soniox REST API provides request/response Text-to-Speech over HTTP. Send text and generation options in a single POST /tts call and receive the generated audio in the response body.

REST is the right fit for:

  • Server-side generation → Render audio on a backend and store or serve the result.
  • Batch jobs → Pre-render prompts, menus, notifications, or static narration.
  • Non-interactive flows → Anywhere a single request-per-utterance model is simpler than managing a live WebSocket.

For low-latency, interactive, or LLM-driven use cases where audio must start playing before the full text is ready, use the real-time WebSocket API instead.


Endpoint

POST https://tts-rt.soniox.com/tts

Required request headers:

  • Content-Type: application/json
  • Authorization: Bearer <SONIOX_API_KEY|SONIOX_TEMPORARY_API_KEY>

See the Generate speech API reference for the full request schema, parameters, and error codes.


Response

On success, the response body contains raw audio bytes for the generated speech. The Content-Type header reflects the requested audio_format:

audio_formatContent-Type
pcm_f32le, pcm_s16le, pcm_mulaw, pcm_alawaudio/pcm
wavaudio/wav
mp3audio/mpeg
aacaudio/aac
opusaudio/opus
flacaudio/flac

For supported sample rates and bitrates per format, see audio formats.


Error handling

If an error occurs before audio streaming begins, the server returns a standard JSON error body with error_code, error_type, error_message, more_info, and request_id. Branch your client on error_type (stable across releases), not on error_message (human-readable, may change). Log the request_id so it can be passed to [email protected] when needed.

Once audio streaming has started, errors cannot be delivered to the client.

For the per-endpoint list of error codes and messages, see the Generate speech API reference. For the full catalog of error_type values across all Soniox APIs, see the Errors reference.


Code example

Prerequisite: Complete the steps in Get started.

See on GitHub: soniox_sdk_rest.py.

import argparse
import os
from pathlib import Path
from typing import Any

from soniox import SonioxClient
from soniox.errors import SonioxAPIError
from soniox.utils import output_file_for_audio_format

VALID_SAMPLE_RATES = [8000, 16000, 24000, 44100, 48000]
VALID_BITRATES = [32000, 64000, 96000, 128000, 192000, 256000, 320000]
VALID_AUDIO_FORMATS = [
    "pcm_f32le",
    "pcm_s16le",
    "pcm_mulaw",
    "pcm_alaw",
    "wav",
    "aac",
    "mp3",
    "opus",
    "flac",
]


def get_config(
    *,
    text: str,
    model: str,
    language: str,
    voice: str,
    audio_format: str,
    sample_rate: int | None,
    bitrate: int | None,
) -> dict[str, Any]:
    config: dict[str, Any] = {
        # Select the model to use.
        # See: docs.soniox.com/tts/models
        "model": model,
        #
        # Set the language of the input text.
        # See: docs.soniox.com/tts/concepts/supported-languages
        "language": language,
        #
        # Select the voice to use.
        # See: docs.soniox.com/tts/concepts/voices
        "voice": voice,
        #
        # Audio format.
        # See: docs.soniox.com/tts/concepts/audio-formats
        "audio_format": audio_format,
        #
        # Input text.
        "text": text,
    }

    if sample_rate is not None:
        config["sample_rate"] = sample_rate
    if bitrate is not None:
        config["bitrate"] = bitrate

    return config


def generate_speech(
    client: SonioxClient,
    config: dict[str, Any],
    output_path: str | None,
) -> None:
    destination = (
        Path(output_path)
        if output_path
        else output_file_for_audio_format(config["audio_format"], "tts_async")
    )

    print("Generating speech...")
    written = client.tts.generate_to_file(destination, **config)
    print(f"Wrote {written} bytes to {destination.resolve()}")


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--text",
        default=(
            "Soniox Text-to-Speech turns written text into natural, expressive audio "
            "with high accuracy. It is designed for conversational agents, narration, "
            "and accessible experiences, with low latency and high-quality voices."
        ),
        help="Text to generate into speech.",
    )
    parser.add_argument("--model", default="tts-rt-v2")
    parser.add_argument("--language", default="en")
    parser.add_argument("--voice", default="Adrian")
    parser.add_argument("--audio_format", default="wav")
    parser.add_argument("--sample_rate", type=int)
    parser.add_argument("--bitrate", type=int)
    parser.add_argument(
        "--output_path",
        help="Optional output file path. If omitted, a timestamped path is generated.",
    )
    args = parser.parse_args()

    if args.audio_format not in VALID_AUDIO_FORMATS:
        raise ValueError(f"audio_format must be one of {VALID_AUDIO_FORMATS}")
    if args.sample_rate is not None and args.sample_rate not in VALID_SAMPLE_RATES:
        raise ValueError(f"sample_rate must be None or one of {VALID_SAMPLE_RATES}")
    if args.bitrate is not None and args.bitrate not in VALID_BITRATES:
        raise ValueError(f"bitrate must be None or one of {VALID_BITRATES}")

    api_key = os.environ.get("SONIOX_API_KEY")
    if not api_key:
        raise RuntimeError(
            "Missing SONIOX_API_KEY.\n"
            "1. Get your API key at https://console.soniox.com\n"
            "2. Run: export SONIOX_API_KEY=<YOUR_API_KEY>"
        )

    client = SonioxClient(api_key=api_key)
    config = get_config(
        text=args.text,
        model=args.model,
        language=args.language,
        voice=args.voice,
        audio_format=args.audio_format,
        sample_rate=args.sample_rate,
        bitrate=args.bitrate,
    )
    try:
        generate_speech(client, config, args.output_path)
    except SonioxAPIError as exc:
        print("Soniox API error:", exc)
        if exc.request_id:
            print("  request_id:", exc.request_id)
    finally:
        client.close()

if __name__ == "__main__":
    main()

Terminal
# Generate speech with default settings (wav output)
python soniox_sdk_rest.py --text "Hello from Soniox REST Text-to-Speech."

# Generate raw PCM output
python soniox_sdk_rest.py --audio_format pcm_s16le --sample_rate 24000 --output_path tts-output.pcm

On this page