Skip to content
All posts
·8 min read·By Petar

Text to Speech API Python Tutorial (2026): Audexum Quickstart Guide

Learn how to call a text-to-speech API in Python using the requests library. Full code examples for voice selection, WAV output, error handling, and pricing comparison.


Integrating text-to-speech into a Python project takes less than 20 lines of code. This guide walks through everything: authentication, choosing a voice, saving WAV output, handling errors, and picking the right plan for your usage.

All examples use the Audexum TTS API, which supports 43 voices across 33 languages and has a free tier with no credit card required.

Prerequisites

You only need the requests library. No SDK, no framework.

bash
pip install requests

Get a free API key at audexum.com/signup. Keys follow the format sk_live_abc123xyz. The free plan gives you 10,000 characters per month with no card required.

First API Call

The endpoint accepts a JSON body with text, voice_id, and optionally language. It returns raw WAV audio.

python
import requests

API_KEY = "sk_live_abc123xyz"
API_URL = "https://audexum.com/api/v1/tts"

response = requests.post(
    API_URL,
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json={
        "text": "Hello, this is a test of the Audexum text-to-speech API.",
        "voice_id": "en_us_female_01",
    },
)

if response.status_code == 200:
    with open("output.wav", "wb") as f:
        f.write(response.content)
    print("Saved output.wav")
else:
    print(f"Error {response.status_code}: {response.text}")

Run it and you get output.wav in the current directory. That is the complete working implementation.

Selecting a Voice

Audexum has 43 voices across American English, British English, Spanish, French, German, Japanese, Korean, Arabic, Hindi, Bulgarian, Italian, Portuguese, and more. List available voices with a GET request:

python
import requests

API_KEY = "sk_live_abc123xyz"

voices = requests.get(
    "https://audexum.com/api/v1/voices",
    headers={"Authorization": f"Bearer {API_KEY}"},
).json()

for voice in voices:
    print(f"{voice['voice_id']:30s} {voice['language']:10s} {voice['gender']}")

Example output:

text
en_us_female_01                en-US      female
en_us_male_01                  en-US      male
en_gb_female_01                en-GB      female
de_female_01                   de         female
ja_female_01                   ja         female

Pass the voice_id string directly in your synthesis request.

Saving the WAV File

The response body is raw PCM WAV — no base64 decoding needed. Write it to disk with standard file I/O:

python
import requests
from pathlib import Path

def synthesize(text: str, voice_id: str, output_path: str, api_key: str) -> Path:
    response = requests.post(
        "https://audexum.com/api/v1/tts",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        },
        json={"text": text, "voice_id": voice_id},
    )
    response.raise_for_status()
    path = Path(output_path)
    path.write_bytes(response.content)
    return path

# Usage
output = synthesize(
    text="Welcome to our application.",
    voice_id="en_us_female_01",
    output_path="welcome.wav",
    api_key="sk_live_abc123xyz",
)
print(f"Audio saved to {output} ({output.stat().st_size} bytes)")

If you need MP3 instead of WAV, pass "format": "mp3" in the JSON body.

Error Handling

Handle rate limits, invalid voices, and authentication errors explicitly:

python
import requests
from requests.exceptions import RequestException

def safe_synthesize(text: str, voice_id: str, api_key: str) -> bytes | None:
    try:
        response = requests.post(
            "https://audexum.com/api/v1/tts",
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json",
            },
            json={"text": text, "voice_id": voice_id},
            timeout=30,
        )

        if response.status_code == 401:
            raise ValueError("Invalid API key. Check your sk_live_ token.")

        if response.status_code == 402:
            raise RuntimeError("Character quota exceeded. Upgrade your plan or wait for reset.")

        if response.status_code == 422:
            raise ValueError(f"Invalid request: {response.json().get('detail')}")

        response.raise_for_status()
        return response.content

    except RequestException as e:
        print(f"Network error: {e}")
        return None

Status Codes Reference

CodeMeaningAction
200SuccessWrite response body to file
401Bad API keyCheck the Authorization header
402Quota exceededUpgrade plan or wait for monthly reset
422Bad request bodyCheck voice_id and text fields
429Rate limitedRetry with exponential backoff
500Server errorRetry once, then contact support

Batch Processing

For batches of strings, stay under the rate limit with a small delay between requests:

python
import time
import requests
from pathlib import Path

def batch_synthesize(items: list[dict], api_key: str, delay: float = 0.2):
    """
    items: [{"text": "...", "voice_id": "...", "output": "file.wav"}, ...]
    """
    results = []
    for item in items:
        response = requests.post(
            "https://audexum.com/api/v1/tts",
            headers={"Authorization": f"Bearer {api_key}"},
            json={"text": item["text"], "voice_id": item["voice_id"]},
        )
        if response.ok:
            Path(item["output"]).write_bytes(response.content)
            results.append({"file": item["output"], "status": "ok"})
        else:
            results.append({"file": item["output"], "status": response.status_code})
        time.sleep(delay)
    return results

Pricing Comparison

Before committing to a plan, here is how the major TTS APIs compare on price per character:

ProviderFree TierPaid EntryCost per 1M charsCard Required for Free
Audexum10K chars/mo€4 / 100K~€8 (PAYG)No
ElevenLabs10K chars/mo~$5 / 30K~$11Yes (some plans)
OpenAI TTSNonePay-as-you-go~$15Yes
Murf.aiLimited (watermarked)~$19/moVariesYes
Google Cloud TTS1M chars/mo (WaveNet 0)Pay-as-you-go$16 (WaveNet)Yes

Audexum is several times cheaper than ElevenLabs and roughly 2× cheaper than OpenAI TTS at scale. The PAYG option at €8/1M chars is useful for projects with unpredictable volume.

Plan Summary

PlanCharacters/moPriceBest For
Free10,000€0Prototypes, testing
Starter100,000€4Small apps, bots
Pro500,000€12Production apps
Scale2,000,000€30High-volume pipelines
PAYGUnlimited€8/1MBursty or unpredictable load

Next Steps

The full Python implementation fits in under 30 lines. The free tier is enough to build and test a complete integration before you spend anything.

Get your API key at audexum.com/signup and check the API reference for the full list of parameters including speed, pitch, and output format controls.


By Petar, founder of Audexum. Running a bootstrapped TTS SaaS gives you strong opinions about API design.

Start for free — 10,000 characters/month, no credit card.