DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

Build an Audiobook Generator Using ElevenLabs API

Overview

Ever wanted to turn a novel, a technical manual, or a collection of blog posts into a sleek, on‑the‑go audiobook? With modern voice‑AI services you can do it in a few lines of code. In this article we’ll walk through building a simple audiobook generator that pulls text from a file, sends it to the ElevenLabs API for high‑quality text‑to‑speech, and stitches the resulting audio chunks together into a single MP3 file ready for playback.

The focus is on the practical bits—getting your API key, making HTTP calls, handling rate limits, and merging audio—so you can copy‑paste the snippets, adapt them to your own project, and ship a usable product in under an hour.

Quick link: Grab your ElevenLabs API key here → https://try.elevenlabs.io/kr07zfuqn1bp


Prerequisites

What you need Why
Python 3.8+ Core language for the demo.
ffmpeg installed and on your PATH Used to concatenate MP3 segments.
ElevenLabs account (free tier works) Provides the TTS endpoint.
A text file containing the content you want to narrate The source material.

You can install the required Python packages with:

pip install requests tqdm pydub
Enter fullscreen mode Exit fullscreen mode

pydub is a thin wrapper around ffmpeg that makes audio concatenation painless.


Getting an API Key

  1. Sign up at ElevenLabs using the affiliate link: https://try.elevenlabs.io/kr07zfuqn1bp.
  2. After confirming your email, go to Dashboard → API Keys and click Create new key.
  3. Copy the key; you’ll need it as an environment variable:
export ELEVENLABS_API_KEY="your_secret_key_here"
Enter fullscreen mode Exit fullscreen mode

Tip: Keep the key out of source control. Use a .env file or your CI’s secret store.


Setting Up the Project

Create a new folder and a minimal script:

audiobook/
├─ main.py
├─ book.txt
└─ requirements.txt
Enter fullscreen mode Exit fullscreen mode

book.txt should contain the raw text you want to convert. For large works, consider splitting chapters into separate files—our script will handle both cases.


Converting Text to Speech

ElevenLabs’ TTS endpoint expects a POST with JSON payload. Here’s a Python wrapper that sends a chunk of text and returns the MP3 bytes:

# main.py
import os
import requests
from tqdm import tqdm

API_KEY = os.getenv("ELEVENLABS_API_KEY")
VOICE_ID = "EXAVITQu4vr4xnSDxMaL"   # Default “Rachel” voice; replace with your own if desired
BASE_URL = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}"

def synthesize(text: str) -> bytes:
    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.85,
        },
    }
    response = requests.post(BASE_URL, json=payload, headers=headers)
    response.raise_for_status()
    return response.content
Enter fullscreen mode Exit fullscreen mode

Chunking the Input

ElevenLabs imposes a ~5 KB limit per request. A simple way to stay under the limit is to split the source text into sentences or paragraphs:

import re

def chunk_text(text: str, max_chars: int = 1500) -> list[str]:
    # Split on double line breaks (paragraphs) first
    paragraphs = re.split(r"\n\s*\n", text)
    chunks = []
    current = ""

    for para in paragraphs:
        if len(current) + len(para) + 1 <= max_chars:
            current += para + "\n\n"
        else:
            chunks.append(current.strip())
            current = para + "\n\n"
    if current:
        chunks.append(current.strip())
    return chunks
Enter fullscreen mode Exit fullscreen mode

Running the Synthesis Loop

from pydub import AudioSegment

def generate_audiobook(input_path: str, output_path: str):
    with open(input_path, "r", encoding="utf-8") as f:
        raw_text = f.read()

    chunks = chunk_text(raw_text)
    audio_segments = []

    for i, chunk in enumerate(tqdm(chunks, desc="Synthesizing")):
        mp3_data = synthesize(chunk)
        segment = AudioSegment.from_file(io.BytesIO(mp3_data), format="mp3")
        audio_segments.append(segment)

    # Concatenate all segments
    final_audio = sum(audio_segments)
    final_audio.export(output_path, format="mp3")
    print(f"\n✅ Audiobook saved to {output_path}")

if __name__ == "__main__":
    generate_audiobook("book.txt", "output_audiobook.mp3")
Enter fullscreen mode Exit fullscreen mode

Running python main.py will produce output_audiobook.mp3 in the project root.


A Quick curl Alternative

If you prefer a shell script or need to test the endpoint manually, here’s a minimal curl call:

curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/EXAVITQu4vr4xnSDxMaL" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "text": "Hello, world! This is a test of ElevenLabs TTS.",
        "model_id": "eleven_monolingual_v1",
        "voice_settings": {"stability":0.75,"similarity_boost":0.85}
      }' \
  --output hello.mp3
Enter fullscreen mode Exit fullscreen mode

Replace the text field with any snippet you like. The response is saved as hello.mp3.


Handling Large Books & Rate Limits

ElevenLabs allows 10 requests per second on the free tier. To stay polite:

  • Throttle your loop with a small time.sleep(0.2) after each request.
  • Use the Retry-After header if you receive a 429 Too Many Requests response.
  • Store each chunk’s MP3 on disk (chunk_001.mp3, chunk_002.mp3, …) so you can resume after a crash without re‑synthesizing everything.
import time

def safe_synthesize(text):
    while True:
        try:
            return synthesize(text)
        except requests.HTTPError as e:
            if e.response.status_code == 429:
                wait = int(e.response.headers.get("Retry-After", "1"))
                print(f"Rate limited – sleeping {wait}s")
                time.sleep(wait)
            else:
                raise
Enter fullscreen mode Exit fullscreen mode

Swap synthesize(chunk) with safe_synthesize(chunk) in the loop above.


Going Beyond: Custom Voices

ElevenLabs lets you clone a voice from a few minutes of audio. Once you have a voice ID, just replace the VOICE_ID constant in the script. The same API call works, delivering a narrator that sounds like you, your favorite podcast host, or a brand mascot.

For more details on voice cloning, check the ElevenLabs docs: https://try.elevenlabs.io/kr07zfuqn1bp


Wrap‑up

You now have a fully functional audiobook generator:

  1. Read raw text.
  2. Chunk it to respect API limits.
  3. Send each chunk to ElevenLabs for natural‑sounding speech.
  4. Merge the MP3 fragments into one seamless file.

From here you can add chapter markers, generate accompanying metadata (ID3 tags), or even build a tiny web UI where users upload PDFs and receive a downloadable MP3.


Call to Action

Ready to give your readers a new way to consume your content? Grab your ElevenLabs API key, spin up the script, and start generating audiobooks today. The voice‑AI platform behind the scenes is fast, affordable, and developer‑friendly—perfect for hobby projects and production‑grade services alike.

Try ElevenLabs now: https://try.elevenlabs.io/kr07zfuqn1bp 🚀

Top comments (0)