Skip to main content

Soniox Python SDK

The SDK exposes two clients: SonioxClient (sync) and AsyncSonioxClient (async). Each client supports:

  • STT over REST (client.stt) and realtime WebSocket (client.realtime.stt)
  • TTS over REST (client.tts) and realtime WebSocket (client.realtime.tts)
  • voice cloning (client.voices) - clone a voice from a reference clip and use it in TTS
  • usage and cost (client.usage, client.usage_logs) - daily spend per model, and per-request logs
  • auth, file uploads, model listing, webhooks, and typed request/response models

Install

pip install soniox
# or if using uv
uv add soniox
export SONIOX_API_KEY=<your-key>

Get your API key from the Soniox Console and inject it once per shell session. Both clients read SONIOX_API_KEY by default, but you can override it per-client if needed.

Avoid Python 3.13.6 - it has a regression in ssl that hangs realtime STT/TTS (CPython issue #137583). Use any other 3.10-3.13.x.

Quick run (STT + TTS, REST + realtime)

  1. REST STT transcription: transcribe a local file end-to-end in one call. Full example: examples/soniox_client/api_example.py.
from soniox import SonioxClient

client = SonioxClient()
transcript = client.stt.transcribe_and_wait_with_tokens(
    file="path/to/audio.mp3",                # local file
    # audio_url="https://example.com/audio.mp3",  # or remote URL
    delete_after=True,                        # auto-cleanup file + transcription
)
print(transcript.text)
client.close()
  1. REST TTS generation: convert text to an audio file.
from soniox import SonioxClient
from soniox.utils import output_file_for_audio_format

client = SonioxClient()
output_file = output_file_for_audio_format("wav", "tts_sync_output")
written = client.tts.generate_to_file(
    output_file,
    text="Hello from Soniox Python SDK Text-to-Speech.",
    model="tts-rt-v2",
    language="en",
    voice="Adrian",
    audio_format="wav",
)
print(f"Wrote {written} bytes to {output_file.resolve()}")
client.close()

Run the full example at examples/soniox_client/tts_api_example.py or async version at examples/async_soniox_client/tts_api_example.py.

The voice above is a built-in (shared) voice name. To browse a model's shared voices, filtered by gender, age, accent, use case or style:

for v in client.voices.list_all_shared("tts-rt-v2", gender="female", style=["calm"]):
    print(v.id, v.accent, v.description)

Use client.voices.list_shared(...) for a single page with an explicit cursor.

You can also clone a voice from a reference audio clip and pass the returned voice id as voice:

voice = client.voices.create("reference.wav", name="my-cloned-voice")
# Cloning runs asynchronously; poll client.voices.get(voice.id) until a model
# reports status "ready", then synthesize with voice=voice.id.

See the voice cloning guide for details.

Output settings that are not identity - speed, reduce_silence, sample rate, bitrate - go on CreateTtsConfig:

from soniox.types import CreateTtsConfig

client.tts.generate(
    text="Hello.",
    voice="Adrian",
    model="tts-rt-v2",
    language="en",
    config=CreateTtsConfig(speed=1.1, reduce_silence=True),
)

reduce_silence shortens the pauses between words and is only accepted by models whose supports_silence_reduction is true in client.tts_models.list().

  1. Realtime STT streaming: open client.realtime.stt.connect, call session.send_byte_chunk or session.send_bytes, then iterate session.receive_events() to render tokens:
from soniox import SonioxClient
from soniox.types import RealtimeSTTConfig, Token
from soniox.utils import render_tokens, throttle_audio, start_audio_thread

DEMO_FILE = "path_to_your_audio_file"

client = SonioxClient()
config = RealtimeSTTConfig(model="stt-rt-v5", audio_format="mp3")
final_tokens: list[Token] = []
non_final_tokens: list[Token] = []

def realtime():
    with client.realtime.stt.connect(config=config) as session:
        start_audio_thread(session, throttle_audio(DEMO_FILE, delay_seconds=0.1))
        for event in session.receive_events():
            for token in event.tokens:
                if token.is_final:
                    final_tokens.append(token)
                else:
                    non_final_tokens.append(token)
            print(render_tokens(final_tokens, non_final_tokens))
            non_final_tokens.clear()

realtime()
client.close()

See examples/soniox_client/realtime_example.py for the full flow.

  1. Realtime TTS streaming: send text chunks and write audio to a file as it arrives.
from uuid import uuid4

from soniox import SonioxClient
from soniox.types import RealtimeTTSConfig
from soniox.utils import output_file_for_audio_format

client = SonioxClient()
config = RealtimeTTSConfig(
    stream_id=f"sync-{uuid4()}",
    model="tts-rt-v2",
    language="en",
    voice="Adrian",
    audio_format="wav",
)

output_file = output_file_for_audio_format("wav", "tts_realtime_output")
bytes_written = 0
with client.realtime.tts.connect(config=config) as session, output_file.open("wb") as f:
    session.send_text_chunks(
        ["Hello from realtime TTS. ", "This is the final chunk."],
        text_end=True,
    )
    for chunk in session.receive_audio_chunks():
        f.write(chunk)
        bytes_written += len(chunk)

print(f"Wrote {bytes_written} bytes to {output_file.resolve()}")

Run the full example at examples/soniox_client/tts_realtime_example.py or async version at examples/async_soniox_client/tts_realtime_example.py.

Usage and cost

client.usage.summary() returns daily cost and activity for the project, rolled up per model and across all models. start_time is inclusive, end_time exclusive, both ISO 8601 UTC, and the window may span at most 366 days.

summary = client.usage.summary(
    start_time="2026-04-01T00:00:00Z",
    end_time="2026-05-01T00:00:00Z",
)
print(summary.total.total_cost_usd)
for entry in summary.models:
    print(entry.model, entry.total_cost_usd)

Each entry carries a days list plus per-day lists (cost_usd, num_requests, ...) aligned to it by index. For per-request records instead, use client.usage_logs.list() / list_all().

client.concurrency_limits covers concurrency: get() for current counts and configured limits, history() for past peaks aggregated per minute (60), hour (3600), or day (86400).

history = client.concurrency_limits.history(
    "2026-04-28T09:00:00Z",
    "2026-04-28T10:00:00Z",
    period_sec=60,
    kind="tts",
)
peak = max(entry.sample_max for entry in history.entries)

Repository layout

  • src/soniox/ – sdk code (clients, http namespaces, real-time/session helpers, types, utils).
  • examples/soniox_client & examples/async_soniox_client – runnable STT and TTS examples for sync and async clients.
  • docs/ – markdown reference (async_client.md, realtime_client.md, types.md, utils.md, errors.md) generated by scripts/generate_docs.py.
  • assets/ – sample audio referenced by the examples.

Development

uv install --with dev

This pulls in ruff, pyright, pytest, etc., so you can lint, type-check, test, and regenerate docs locally.

Docs

source .venv/bin/activate
python3 scripts/generate_docs.py

Docs are output to /docs directory.

Resources

Metadata

Release files for soniox 2.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for soniox 2.10.0
File Size Uploaded
soniox-2.10.0.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for soniox 2.10.0
File Interpreter ABI Platform
soniox-2.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / soniox-2.10.0.tar.gz

Download URL soniox-2.10.0.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
7807be59411213ed302803aca7893094717d2f50adcf4d83627d03f21fe6bc32
BLAKE2b-256 checksum
How to use checksums
f532102afbab5d4c5f506d8fb3e2c4ce4c5b974a9270bbf7d95d31e08258df54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.9

Release files / soniox-2.10.0-py3-none-any.whl

Download URL soniox-2.10.0-py3-none-any.whl
Size 75.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c4f777432d64c249cd3d29d27a6c8380b2374fa02819c6fab6640f0c2b3ec983
BLAKE2b-256 checksum
How to use checksums
9e3e54036ec5f2ed632bf760a9b776364506ac369a3df3d62933df2ae892d6c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.9

Release history Release notifications | RSS feed

This release

2.10.0 This release

2 release files

2.9.0

2 release files

2.8.0

2 release files

2.7.0

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.2

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.10.1

2 release files

1.10.0

2 release files

1.9.0

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.5.0

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page