Blog

ElevenLabs Text to Speech: API, Pricing and Code (2026)

Unicorn API Team · · 10 min read

ElevenLabs text to speech pipeline turning a text document into an audio waveform through an API

What is ElevenLabs text to speech?

ElevenLabs text to speech is a family of AI voice models that read written text aloud in a natural, human-sounding voice. ElevenLabs, the company behind it, builds speech synthesis software with deep learning. It opened its browser-based text-to-speech platform in January 2023, and its name quickly became shorthand for “AI voice that doesn’t sound like a robot”.

Speech synthesis just means a computer producing spoken audio. Older systems stitched together recorded sound fragments or followed hand-written pronunciation rules, so they sounded flat. Neural models like the ElevenLabs family learn from large amounts of recorded speech. They pick up pacing, emphasis and breathing from the context of the sentence, which is why a line of dialogue sounds like a line of dialogue and not a dictionary entry.

There are two ways to use ElevenLabs text to speech:

  • The ElevenLabs app. You paste text, pick a voice, press generate and download the clip. This works well for one-off voiceovers and for auditioning voices.
  • An API. Your code sends text and gets an audio file back. This is the route to take when narration is part of a product: an article reader, a course platform, an app that voices notifications, a pipeline that dubs hundreds of videos.

This guide covers the API route. On Unicorn API the ElevenLabs models sit next to image, video, music and chat models, so you use one API key and one credit balance for all of them. If you want to hear the voices before writing any code, the audio playground runs the same models in the browser.

A few terms used throughout:

  • Voice ID: a string such as EkK5I93UQWFDigLMpZcX that picks which voice reads your text.
  • Job: an asynchronous request. You submit it, get back an ID, and check on it until the audio is ready.
  • Credit: Unicorn API’s billing unit. Every request has a fixed, known credit cost.

Which ElevenLabs model should you use?

Unicorn API offers three ElevenLabs voice models. Two are classic single-voice text to speech models. The third generates a conversation between several voices in one request.

ModelModel IDPriceBilled byGood fit
Text to Speech Turbo V2.5elevenlabs-text-to-speech-turbo-2-56 creditsper 1,000 charactersDrafts, high volume, app voices, previews
Text to Speech Multilingual V2elevenlabs-text-to-speech-multilingual-v212 creditsper 1,000 charactersFinished narration, audiobooks, ads, non-English scripts
Text to Dialogue V3elevenlabs-text-to-dialogue-v314 creditsper requestTwo or more speakers in one clip

Turbo V2.5: the default for volume

ElevenLabs positions Turbo as its faster, cheaper tier. At 6 credits per 1,000 characters it costs half as much as Multilingual v2, and it takes exactly the same input fields. If you generate a lot of audio, such as article read-aloud, voiced UI messages or rough cuts for editors, start here. Its minimal request doesn’t even require a voice, so a default voice is used when you leave that field out.

Multilingual V2: when the voice is the product

Multilingual v2 is the model to use when people will listen closely: a finished explainer video, a paid course, a podcast intro. It also accepts a language_code field, which helps when the script isn’t in English or when a name or term could be read in more than one language. It costs 12 credits per 1,000 characters.

Text to Dialogue V3: multi-speaker scenes

Text to Dialogue v3 takes a dialogue array where each line has its own text and voice, and it returns one audio file of the whole exchange. It costs a flat 14 credits per request, so you don’t have to stitch separate clips together or line up the timing yourself.

For a wider look at voice models outside the ElevenLabs family, see our roundup of the best AI voice generator options.

Comparison of three ElevenLabs models: Turbo v2.5, Multilingual v2 and Text to Dialogue v3
Turbo for drafts and volume, Multilingual for finished narration, Dialogue for multi-speaker scenes.

How much does ElevenLabs text to speech cost?

On Unicorn API the two single-voice models are billed per started block of 1,000 characters of the text field. The formula is:

credits = rate × ceil(characters_in_text / 1000)

Here ceil means “round up”. A 1,000-character request counts as one block, and a 1,001-character request counts as two. Spaces and punctuation count as characters too.

Credits cost $0.01 each on a monthly plan (Starter $25, Creator $50, Studio $100, Pro $200) and $0.015 each as top-ups, which never expire. Full details are on the pricing page. Here is what typical scripts cost:

Script lengthBlocksTurbo V2.5Multilingual V2Turbo at plan rateMultilingual at plan rate
500 characters16 credits12 credits$0.06$0.12
1,000 characters16 credits12 credits$0.06$0.12
1,001 characters212 credits24 credits$0.12$0.24
2,400 characters318 credits36 credits$0.18$0.36
10,000 characters1060 credits120 credits$0.60$1.20

At top-up rates, multiply the dollar figures by 1.5. For example, 10,000 characters on Turbo costs $0.90.

To put a plan in perspective: the Starter plan’s 2,500 credits cover 416 full 1,000-character blocks on Turbo, or 208 on Multilingual v2. A Dialogue v3 scene is always 14 credits ($0.14 on a plan), however you split the lines.

Check the price before you run it

You never have to guess. Send the same body you would send to /v1/jobs to the price endpoint and you get the exact credit cost back, without running the job:

curl https://api.unicornapi.net/v1/models/price \
  -H "Authorization: Bearer $UNICORN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "elevenlabs-text-to-speech-multilingual-v2",
    "input": {
      "text": "Welcome back. In this lesson we will set up the project from scratch.",
      "voice": "EkK5I93UQWFDigLMpZcX"
    }
  }'

This is useful in user-facing products: show the cost of a long document before the user confirms, or reject jobs over a budget on the server.

How to call the ElevenLabs text to speech API

Every media model on Unicorn API, including ElevenLabs text to speech, follows the same three-step pattern:

  1. Create a key. Generate one on the API keys page and export it as UNICORN_API_KEY.
  2. Submit a job. POST to /v1/jobs with a model ID and an input object. You get back a job with an id.
  3. Poll for the result. GET /v1/jobs/{id} until status is "succeeded", then read the audio URL from outputs[0].url.

With curl

# 1. Submit the job
curl https://api.unicornapi.net/v1/jobs \
  -H "Authorization: Bearer $UNICORN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "elevenlabs-text-to-speech-turbo-2-5",
    "input": {
      "text": "Your order has shipped and should arrive on Thursday.",
      "voice": "EkK5I93UQWFDigLMpZcX"
    }
  }'

# 2. Poll with the id from the response
curl https://api.unicornapi.net/v1/jobs/JOB_ID \
  -H "Authorization: Bearer $UNICORN_API_KEY"

With Python

This is a complete script. It submits the job, polls until the audio is ready, and saves the file using the extension from the output URL.

import os
import time
from urllib.parse import urlparse

import requests

API = "https://api.unicornapi.net"
HEADERS = {"Authorization": f"Bearer {os.environ['UNICORN_API_KEY']}"}


def synthesize(text, model="elevenlabs-text-to-speech-turbo-2-5", **settings):
    body = {
        "model": model,
        "input": {"text": text, "voice": "EkK5I93UQWFDigLMpZcX", **settings},
    }
    resp = requests.post(f"{API}/v1/jobs", json=body, headers=HEADERS, timeout=30)
    resp.raise_for_status()
    job_id = resp.json()["id"]

    while True:
        resp = requests.get(f"{API}/v1/jobs/{job_id}", headers=HEADERS, timeout=30)
        resp.raise_for_status()
        job = resp.json()
        if job["status"] == "succeeded":
            return job["outputs"][0]["url"]
        if job["status"] == "failed":
            raise RuntimeError(f"Job {job_id} failed: {job}")
        time.sleep(2)


def download(url, basename="speech"):
    ext = os.path.splitext(urlparse(url).path)[1] or ".audio"
    path = basename + ext
    with requests.get(url, stream=True, timeout=60) as r:
        r.raise_for_status()
        with open(path, "wb") as f:
            for part in r.iter_content(chunk_size=8192):
                f.write(part)
    return path


if __name__ == "__main__":
    url = synthesize("Your order has shipped and should arrive on Thursday.")
    print("Saved", download(url))

With JavaScript (Node 18+)

const API = "https://api.unicornapi.net";
const headers = {
  Authorization: `Bearer ${process.env.UNICORN_API_KEY}`,
  "Content-Type": "application/json",
};

async function synthesize(text) {
  const res = await fetch(`${API}/v1/jobs`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: "elevenlabs-text-to-speech-multilingual-v2",
      input: { text, voice: "EkK5I93UQWFDigLMpZcX" },
    }),
  });
  if (!res.ok) throw new Error(`Submit failed: ${res.status}`);
  const { id } = await res.json();

  while (true) {
    const poll = await fetch(`${API}/v1/jobs/${id}`, { headers });
    const job = await poll.json();
    if (job.status === "succeeded") return job.outputs[0].url;
    if (job.status === "failed") throw new Error(`Job ${id} failed`);
    await new Promise((r) => setTimeout(r, 2000));
  }
}

synthesize("Welcome to the course. Let's get started.").then(console.log);

If you work in Cursor, Claude Code or another coding agent, you can also call these models through MCP. The setup is on the agents page, and request details for every field are in the API documentation.

Voice settings: stability, similarity, style and speed

Turbo v2.5 and Multilingual v2 accept the same set of tuning fields. You can leave all of them out and get sensible defaults, but knowing what each one does saves a lot of regeneration.

  • voice: the voice ID. This has the biggest effect on the result. Audition voices in the playground before you settle on one.
  • stability: how consistent the delivery stays from one line to the next. Higher values sound steadier and more even, which suits narration and support messages. Lower values sound more expressive but also more variable between takes.
  • similarity_boost: how closely the output follows the character of the original voice. Push it too high and you can amplify artefacts in the source voice. Pull it too low and the voice drifts.
  • style: exaggerates the voice’s natural speaking style. Useful for character work and ads, but usually best kept low for long-form reading.
  • speed: speaking rate. Small changes go a long way, so adjust it in small steps.
  • language_code: tells the model which language the text is in. Set it whenever the script isn’t English, or when it mixes languages.
  • previous_text and next_text: the text that comes before and after this request. They give the model context so intonation flows across clips when you split a long script. Pricing is based on the text field.
  • timestamps: asks for timing data along with the audio, which helps with captions and highlighting words as they are read.

Accepted ranges for each field are in the documentation. A practical way to tune: pick one representative paragraph, generate it on Turbo with three or four stability values, choose the best, then adjust style the same way. Once you have a winning combination, render the final script on Multilingual v2 if it needs the extra polish.

Text matters as much as settings. ElevenLabs text to speech reads punctuation as cues: commas give short pauses, full stops give longer ones, and question marks lift the intonation. Write numbers, dates and abbreviations the way you want them spoken (“twenty twenty-six” or “2026”, “Dr.” or “Doctor”) and test anything unusual.

Diagram of a long script split into chunks with previous_text and next_text context passed between them
Split long scripts at sentence boundaries and pass neighbouring text for smooth joins.

Worked example: narrating a product video script

Say you have a 2,400-character script for a product explainer, and you want a clean narration plus a short two-voice exchange at the end.

1. Split the script at sentence boundaries

You could send the whole script in one request, and for 2,400 characters that works. In practice, long scripts are easier to manage in chunks: if one sentence comes out wrong, you regenerate a 900-character clip and not the whole thing. Because pricing rounds up per request, keep each chunk close to, but not over, 1,000 characters. Three chunks of about 800 characters cost the same as one 2,400-character request. Six chunks of 400 characters cost twice as much.

import re


def chunk(text, limit=1000):
    sentences = re.split(r"(?<=[.!?])\s+", text.strip())
    chunks, current = [], ""
    for s in sentences:
        candidate = f"{current} {s}".strip()
        if len(candidate) > limit and current:
            chunks.append(current)
            current = s
        else:
            current = candidate
    if current:
        chunks.append(current)
    return chunks

2. Render each chunk with context

Pass the neighbouring chunks as previous_text and next_text so the voice doesn’t reset its tone at every join. This uses the synthesize function from the earlier section:

script = open("explainer.txt").read()
parts = chunk(script)
urls = []

for i, part in enumerate(parts):
    context = {}
    if i > 0:
        context["previous_text"] = parts[i - 1]
    if i < len(parts) - 1:
        context["next_text"] = parts[i + 1]
    urls.append(synthesize(
        part,
        model="elevenlabs-text-to-speech-multilingual-v2",
        stability=0.5,
        **context,
    ))

for i, url in enumerate(urls):
    print("Saved", download(url, basename=f"narration_{i:02d}"))

Cost: three chunks × 12 credits = 36 credits on Multilingual v2, or $0.36 on a monthly plan. A draft pass on Turbo costs 18 credits. Since the jobs are independent, you can submit them all at once and poll in parallel to save time.

3. Add a two-voice closing scene

For the closing exchange, one Dialogue v3 request covers every line:

curl https://api.unicornapi.net/v1/jobs \
  -H "Authorization: Bearer $UNICORN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "elevenlabs-text-to-dialogue-v3",
    "input": {
      "dialogue": [
        {"text": "So it really took five minutes to set up?", "voice": "EkK5I93UQWFDigLMpZcX"},
        {"text": "Five minutes, and most of that was choosing a voice.", "voice": "YOUR_SECOND_VOICE_ID"}
      ]
    }
  }'

Replace YOUR_SECOND_VOICE_ID with a second voice from the catalogue. That’s 14 credits for the whole scene. If you want a music bed underneath, Ai Music API Sounds generates a track for 2.5 credits through the same jobs endpoint. Our Suno AI song guide covers prompting for music, and the ElevenLabs sound effects post covers effects. The full production comes to about 53 credits (36 + 14 + 2.5, rounded up per request), all on one bill.

Common mistakes with ElevenLabs text to speech

  • Going just over 1,000 characters. A 1,050-character request costs two blocks. Trim a sentence or move it into the next chunk.
  • Chunking too finely. Sending one sentence per request multiplies the cost, because each request rounds up to a full block. Pack chunks close to 1,000 characters.
  • Forgetting context fields. Without previous_text and next_text, chunks can start with a “new paragraph” tone that sounds choppy when joined.
  • Tuning on the expensive model. Find your settings on Turbo at half the price, then render the final take on Multilingual v2 if it needs it.
  • Changing voices mid-project. Store the voice ID and settings with each project, so regenerating one paragraph six weeks later still matches the rest.
  • Hot-linking the output URL. Download each file into your own storage as soon as the job succeeds, and serve it from there.
  • Polling without a failure branch. Always handle the failed status, and add a timeout so a stuck loop doesn’t run forever.
  • Skipping language_code. For non-English or mixed-language scripts, set it explicitly rather than hoping the model guesses right.
  • Cloning voices without permission. ElevenLabs voice cloning is powerful, which is exactly why you need clear consent from the person whose voice it is.

ElevenLabs text to speech is easiest to work with when you treat it like any other build step: a fixed voice, fixed settings, predictable per-request costs and files you own. When you’re ready, create a key, test a paragraph in the playground, and browse the model catalogue for the image, video and music models that run on the same credits.

Frequently asked questions

Is ElevenLabs text to speech free?

ElevenLabs runs a limited free tier in its own app, which works for testing voices by hand. For production use through an API you pay per character. On Unicorn API, Turbo v2.5 costs 6 credits per 1,000 characters and Multilingual v2 costs 12, so a short 1,000-character clip costs 6 or 12 cents on a monthly plan. You can also check the exact price of any request before running it.

How much does the ElevenLabs text to speech API cost?

On Unicorn API the cost depends on the model and the length of the text field. Turbo v2.5 is 6 credits per started block of 1,000 characters and Multilingual v2 is 12. Text to Dialogue v3 is a flat 14 credits per request. Credits cost $0.01 each on monthly plans and $0.015 as top-ups, which never expire. POST /v1/models/price returns the exact cost first.

What is the difference between ElevenLabs Turbo v2.5 and Multilingual v2?

Both take the same input fields: text, voice, stability, similarity_boost, style, speed, language_code, timestamps, and the previous_text and next_text context fields. ElevenLabs positions Turbo v2.5 as the faster, cheaper tier and Multilingual v2 as the quality-first model for finished narration. On Unicorn API, Turbo costs half as much: 6 credits per 1,000 characters against 12. Test both on the same script before you decide.

Can I use ElevenLabs voice cloning through Unicorn API?

Voice cloning, where you upload samples of a real voice to create a custom one, happens inside ElevenLabs' own app. Unicorn API's text to speech models take a voice field that selects a voice by its ID. Before you build a workflow around a custom voice, check the documentation to see which voice IDs are accepted. Only clone voices you have clear permission to use.

How do I download audio generated with ElevenLabs text to speech?

In the ElevenLabs app, a download button appears on the finished clip. Through the API, you poll GET /v1/jobs/{id} until the status is succeeded, then read the file URL from outputs[0].url and fetch it with any HTTP client. Copy the file into your own storage as soon as it is ready, so your product never depends on that URL staying live.

Can ElevenLabs generate a conversation with multiple voices?

Yes. The Text to Dialogue V3 model takes a dialogue array in which each line has its own text and voice, and it returns one audio file of the whole exchange. On Unicorn API it costs a flat 14 credits per request, so it works well for podcast-style segments, ad scripts with two speakers, or game scenes, without stitching separate clips together.