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 32 languages and has a free tier with no credit card required.
Prerequisites
You only need the requests library. No SDK, no framework.
pip install requestsGet a free API key at audexum.com/signup. Keys follow the format sk_live_abc123xyz. The free plan gives you 2,000 free credits + 250 a day 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.
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:
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:
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 femalePass 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:
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:
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 NoneStatus Codes Reference
Batch Processing
For batches of strings, stay under the rate limit with a small delay between requests:
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 resultsPricing Comparison
Before committing to a plan, here is how the major TTS APIs compare on price per character:
Audexum plan subscribers get effective rates from €9.93/1M (Business) to €24.17/1M (Pro). The PAYG option at €28/1M credits is useful for projects with unpredictable volume and one-time credit packs never expire.
Plan Summary
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.
- Related: Cheapest text-to-speech API in 2026
- Related: ElevenLabs alternative with a free tier
- Related: TTS API for Discord bots
By Petar, founder of Audexum. Running a bootstrapped TTS SaaS gives you strong opinions about API design.