If you’ve ever built a chatbot, an accessibility feature, or a voice‑enabled game, you know that a natural‑sounding voice can turn a static experience into something engaging and human‑like. Modern TTS engines are no longer limited to robotic monotones – they can capture emotion, intonation, and even mimic a specific speaker’s style.
That’s where ElevenLabs shines. Their API delivers high‑quality neural voices that are easy to integrate, and the pricing model works well for both hobby projects and production apps. In this post we’ll walk through building a simple Python app that sends text to ElevenLabs, receives an audio file, and plays it back. By the end you’ll have a reusable script you can drop into any project.
| What you need | Why |
|---|---|
| Python 3.8+ | The example uses f‑strings and asyncio . |
| pip | To install the required packages. |
| ElevenLabs API key | You’ll need an account; sign up via the affiliate link: https://try.elevenlabs.io/kr07zfuqn1bp |
| A speaker or headphones | To hear the generated audio. |
Keep this token secret – treat it like a password.
pip install httpx python-dotenv pydub
.env file.
ffmpeg installed on your system; on macOS you can use brew install ffmpeg, on Ubuntu sudo apt-get install ffmpeg.)
Create a .env file in your project root:
ELEVENLABS_API_KEY=your_api_key_here
Below is a minimal async function that talks to ElevenLabs. It accepts the text you want spoken, the voice ID (we’ll use the default “Rachel” for now), and returns the path to a saved MP3 file.
import os
import httpx
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("ELEVENLABS_API_KEY")
BASE_URL = "https://api.elevenlabs.io/v1"
async def synthesize(
text: str,
voice_id: str = "EXAVITQu4vr4xnSDxMaL", # default voice (Rachel)
output_path: Path = Path("output.mp3"),
) -> Path:
url = f"{BASE_URL}/text-to-speech/{voice_id}"
headers = {
"xi-api-key": API_KEY,
"Content-Type": "application/json",
}
payload = {
"text": text,
"model_id": "eleven_monolingual_v1",
"voice_settings": {
"stability": 0.75,
"similarity_boost": 0.75,
},
}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, json=payload, headers=headers)
response.raise_for_status()
output_path.write_bytes(response.content)
return output_path
What’s happening?
/text-to-speech/{voice_id}.
model_id selects the neural model; eleven_monolingual_v1 is the most balanced for English.
stability and similarity_boost let you tweak how consistent the voice sounds vs. how expressive it is.
Feel free to experiment – a higher stability makes the voice more monotone, while a higher similarity_boost pushes it toward the reference voice.
from pydub import AudioSegment
from pydub.playback import play
def play_audio(file_path: Path):
audio = AudioSegment.from_file(file_path, format="mp3")
play(audio)
python
import asyncio
from pathlib import Path
async def main():
text = (
"Hello, fellow developer! "
"With ElevenLabs, you can turn any string into a natural‑sounding voice."
)
output_file = Path("speech.mp3")
print("Generating speech…")
await synthesize(text, output_path=output_file)
print(f"Saved to {output_file}")
print("Playing back…")
play_audio(output_file)
if __name__ == "__main__":
asyncio.run(main())
Run the script:
python tts_demo.py
You should hear the phrase spoken in a clear, human‑like voice. 🎉
ElevenLabs also offers voice cloning – you can upload a few minutes of a speaker’s recordings and generate a custom voice ID. The workflow is:
/voices/add endpoint (or via the web UI).
voice_id once the model is ready.
synthesize function above.
Here’s a quick curl example for up a sample (replace YOUR_API_KEY and sample.wav with your values):
curl -X POST "https://api.elevenlabs.io/v1/voices/add" \
-H "xi-api-key: YOUR_API_KEY" \
-F "name=MyCustomVoice" \
-F "files[]=@sample.wav"
The response contains:
{
"voice_id": "abc123def456",
"name": "MyCustomVoice",
"preview_url": "https://..."
}
Now just pass "abc123def456" as the voice_id to synthesize and you’ll hear your voice reading the text. This is a game‑changer for personalized assistants, audiobooks, and dubbing.
ElevenLabs enforces a per‑minute request quota based on your plan. If you exceed it, you’ll receive a 429 Too Many Requests response. A simple retry strategy can keep your app smooth:
import time
async def safe_synthesize(*args, **kwargs):
retries = 3
backoff = 2
for attempt in range(retries):
try:
return await synthesize(*args, **kwargs)
except httpx.HTTPStatusError as exc:
if exc.response.status_code == 429 and attempt < retries - 1:
wait = backoff ** attempt
print(f"Rate limited, sleeping {wait}s…")
time.sleep(wait)
continue
raise
Wrap your calls with await safe_synthesize(...) to automatically back‑off on throttling.
If you want to expose this TTS capability as a micro‑service, Flask or FastAPI work nicely:
from fastapi import FastAPI, Body
from fastapi.responses import FileResponse
app = FastAPI()
@app.post("/speak")
async def speak(text: str = Body(...)):
out_file = await safe_synthesize(text)
return FileResponse(out_file, media_type="audio/mpeg")
Deploy to Render, Fly.io, or any container platform, and you’ll have an HTTP endpoint that turns any string into speech on demand.
| Tip | Reason |
|---|---|
| Cache results | Many apps reuse the same phrases (e.g., “Welcome back”). Store the MP3 locally to avoid unnecessary API calls. |
| Validate input length | The free tier caps requests at 2 000 characters. Trim or split longer texts before sending. |
| Secure the API key | Use secret management (AWS Secrets Manager, GCP Secret Manager) instead of plain .env in production. |
| Monitor usage | ElevenLabs provides usage stats in the dashboard; set alerts if you approach your quota. |
You now have a fully functional Python text‑to‑speech app powered by ElevenLabs. From a quick demo to a cloud‑hosted micro‑service or a custom voice clone, the API is flexible enough to fit most developer workflows.
Give it a spin, experiment with voice settings, and maybe even train a voice that sounds like you. The possibilities are only limited by your imagination (and the API quota).
Ready to bring natural speech to your next project? Try ElevenLabs today with the affiliate link: https://try.elevenlabs.io/kr07zfuqn1bp – you’ll get instant access to the API and a generous free tier to start building right away. Happy coding!