Eleven v4
curl --request POST \
--url https://api.snapgen.org/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": "<string>",
"voice": "<string>",
"response_format": "<string>",
"speed": 123,
"language": "<string>",
"stability": 123,
"similarity_boost": 123,
"style": 123,
"use_speaker_boost": true,
"seed": 123,
"previous_text": "<string>",
"next_text": "<string>",
"apply_text_normalization": "<string>"
}
'import requests
url = "https://api.snapgen.org/v1/audio/speech"
payload = {
"model": "<string>",
"input": "<string>",
"voice": "<string>",
"response_format": "<string>",
"speed": 123,
"language": "<string>",
"stability": 123,
"similarity_boost": 123,
"style": 123,
"use_speaker_boost": True,
"seed": 123,
"previous_text": "<string>",
"next_text": "<string>",
"apply_text_normalization": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
input: '<string>',
voice: '<string>',
response_format: '<string>',
speed: 123,
language: '<string>',
stability: 123,
similarity_boost: 123,
style: 123,
use_speaker_boost: true,
seed: 123,
previous_text: '<string>',
next_text: '<string>',
apply_text_normalization: '<string>'
})
};
fetch('https://api.snapgen.org/v1/audio/speech', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.snapgen.org/v1/audio/speech",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'input' => '<string>',
'voice' => '<string>',
'response_format' => '<string>',
'speed' => 123,
'language' => '<string>',
'stability' => 123,
'similarity_boost' => 123,
'style' => 123,
'use_speaker_boost' => true,
'seed' => 123,
'previous_text' => '<string>',
'next_text' => '<string>',
'apply_text_normalization' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.snapgen.org/v1/audio/speech"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": \"<string>\",\n \"voice\": \"<string>\",\n \"response_format\": \"<string>\",\n \"speed\": 123,\n \"language\": \"<string>\",\n \"stability\": 123,\n \"similarity_boost\": 123,\n \"style\": 123,\n \"use_speaker_boost\": true,\n \"seed\": 123,\n \"previous_text\": \"<string>\",\n \"next_text\": \"<string>\",\n \"apply_text_normalization\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.snapgen.org/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": \"<string>\",\n \"voice\": \"<string>\",\n \"response_format\": \"<string>\",\n \"speed\": 123,\n \"language\": \"<string>\",\n \"stability\": 123,\n \"similarity_boost\": 123,\n \"style\": 123,\n \"use_speaker_boost\": true,\n \"seed\": 123,\n \"previous_text\": \"<string>\",\n \"next_text\": \"<string>\",\n \"apply_text_normalization\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snapgen.org/v1/audio/speech")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"input\": \"<string>\",\n \"voice\": \"<string>\",\n \"response_format\": \"<string>\",\n \"speed\": 123,\n \"language\": \"<string>\",\n \"stability\": 123,\n \"similarity_boost\": 123,\n \"style\": 123,\n \"use_speaker_boost\": true,\n \"seed\": 123,\n \"previous_text\": \"<string>\",\n \"next_text\": \"<string>\",\n \"apply_text_normalization\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyElevenLabs Speech
Eleven v4
ElevenLabs Eleven v4 text to speech through the OpenAI-compatible speech endpoint. $0.12 per 1,000 characters.
POST
/
v1
/
audio
/
speech
Eleven v4
curl --request POST \
--url https://api.snapgen.org/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": "<string>",
"voice": "<string>",
"response_format": "<string>",
"speed": 123,
"language": "<string>",
"stability": 123,
"similarity_boost": 123,
"style": 123,
"use_speaker_boost": true,
"seed": 123,
"previous_text": "<string>",
"next_text": "<string>",
"apply_text_normalization": "<string>"
}
'import requests
url = "https://api.snapgen.org/v1/audio/speech"
payload = {
"model": "<string>",
"input": "<string>",
"voice": "<string>",
"response_format": "<string>",
"speed": 123,
"language": "<string>",
"stability": 123,
"similarity_boost": 123,
"style": 123,
"use_speaker_boost": True,
"seed": 123,
"previous_text": "<string>",
"next_text": "<string>",
"apply_text_normalization": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
input: '<string>',
voice: '<string>',
response_format: '<string>',
speed: 123,
language: '<string>',
stability: 123,
similarity_boost: 123,
style: 123,
use_speaker_boost: true,
seed: 123,
previous_text: '<string>',
next_text: '<string>',
apply_text_normalization: '<string>'
})
};
fetch('https://api.snapgen.org/v1/audio/speech', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.snapgen.org/v1/audio/speech",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'input' => '<string>',
'voice' => '<string>',
'response_format' => '<string>',
'speed' => 123,
'language' => '<string>',
'stability' => 123,
'similarity_boost' => 123,
'style' => 123,
'use_speaker_boost' => true,
'seed' => 123,
'previous_text' => '<string>',
'next_text' => '<string>',
'apply_text_normalization' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.snapgen.org/v1/audio/speech"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": \"<string>\",\n \"voice\": \"<string>\",\n \"response_format\": \"<string>\",\n \"speed\": 123,\n \"language\": \"<string>\",\n \"stability\": 123,\n \"similarity_boost\": 123,\n \"style\": 123,\n \"use_speaker_boost\": true,\n \"seed\": 123,\n \"previous_text\": \"<string>\",\n \"next_text\": \"<string>\",\n \"apply_text_normalization\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.snapgen.org/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": \"<string>\",\n \"voice\": \"<string>\",\n \"response_format\": \"<string>\",\n \"speed\": 123,\n \"language\": \"<string>\",\n \"stability\": 123,\n \"similarity_boost\": 123,\n \"style\": 123,\n \"use_speaker_boost\": true,\n \"seed\": 123,\n \"previous_text\": \"<string>\",\n \"next_text\": \"<string>\",\n \"apply_text_normalization\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snapgen.org/v1/audio/speech")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"input\": \"<string>\",\n \"voice\": \"<string>\",\n \"response_format\": \"<string>\",\n \"speed\": 123,\n \"language\": \"<string>\",\n \"stability\": 123,\n \"similarity_boost\": 123,\n \"style\": 123,\n \"use_speaker_boost\": true,\n \"seed\": 123,\n \"previous_text\": \"<string>\",\n \"next_text\": \"<string>\",\n \"apply_text_normalization\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyeleven-v4 runs ElevenLabs Eleven v4 text to speech on the OpenAI-compatible speech endpoint. Send up to 10,000 characters with one of 21 premade voices and receive the audio file in the response. Use it with the official OpenAI SDKs by changing only the base URL, the model, and the voice.
| Property | Value |
|---|---|
| Model ID | eleven-v4 |
| Endpoint | POST /v1/audio/speech (synchronous) |
| Output | Audio bytes: MP3 (default), Opus, PCM, or WAV |
| Voices | 21 ElevenLabs premade voices, by ID or first name |
| Limits | Up to 10,000 characters per request |
| Billed on | Characters of input |
| Price | $0.12 per 1,000 characters (12 credits) |
Choose a speech model
All four speech models share the endpoint, the fields, and the voices. They differ in the upstream model, the character limit, and the price.| Model | Characters per request | Price per 1,000 characters |
|---|---|---|
eleven-v4 | 10,000 | $0.12 |
eleven-v3 | 5,000 | $0.12 |
eleven-multilingual-v2 | 10,000 | $0.12 |
eleven-flash-v2.5 | 40,000 | $0.06 |
eleven-v4-dialogue.
string
required
Set to
eleven-v4.string
required
The text to speak, up to 10,000 characters. Newlines are allowed; blank text
and other control characters are rejected. Each character is billed.
string
required
A voice ID or first name from the
voice list, for example
JBFqnCBsd6RMkjVDRZzb or George. Names are case-insensitive.string
default:"mp3"
mp3, opus, pcm, or wav. See
Output formats.number
Speaking speed, from
0.7 to 1.2.string
An ISO 639 language code of two or three lowercase letters, such as
en or
de. The provider rejects a code the model doesn’t support.number
From
0 to 1. Lower values give a broader emotional range; higher values
sound more consistent.number
From
0 to 1. How closely the output follows the original voice.number
From
0 to 1. Exaggerates the voice’s speaking style.boolean
Boosts similarity to the original speaker.
integer
From
0 to 4294967295. Makes repeated requests more repeatable, without
guaranteeing identical audio.string
Up to 5,000 characters that come before
input, for continuity across
requests. Not billed.string
Up to 5,000 characters that follow
input, for continuity across requests.
Not billed.string
auto, on, or off: whether numbers, dates, and similar text are spelled
out before speaking.Request
curl https://api.snapgen.org/v1/audio/speech \
-H "Authorization: Bearer $SNAPGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "eleven-v4",
"input": "Welcome back! Today we explore the northern lights.",
"voice": "JBFqnCBsd6RMkjVDRZzb",
"response_format": "mp3"
}' \
--output speech.mp3
Content-Type that matches
response_format (audio/mpeg for MP3).
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["SNAPGEN_API_KEY"],
base_url="https://api.snapgen.org/v1",
)
with client.audio.speech.with_streaming_response.create(
model="eleven-v4",
voice="George",
input="Welcome back! Today we explore the northern lights.",
response_format="mp3",
) as response:
response.stream_to_file("speech.mp3")
const fs = require("node:fs");
const OpenAI = require("openai");
async function main() {
const client = new OpenAI({
apiKey: process.env.SNAPGEN_API_KEY,
baseURL: "https://api.snapgen.org/v1",
});
const response = await client.audio.speech.create({
model: "eleven-v4",
voice: "George",
input: "Welcome back! Today we explore the northern lights.",
response_format: "mp3",
});
fs.writeFileSync("speech.mp3", Buffer.from(await response.arrayBuffer()));
}
main();
Longer text
A request takes up to 10,000 characters. For a longer script, split it at sentence or paragraph boundaries and send one request per part. Pass the neighboring text asprevious_text and next_text so each part flows into
the next; that context isn’t billed. Keep voice, seed, and the voice
settings the same for every part.
Price examples
| Text | Price |
|---|---|
| 100 characters | $0.012 |
| 1,000 characters | $0.12 |
| 10,000 characters | $1.20 |
Synchronous audio endpoints reject
Idempotency-Key. If a request times
out, check your Console request logs before you retry. See
Text to speech for the response headers and
errors.