Voice Generation API
Introduction
This API provides access to high-quality text-to-speech synthesis. Generate natural-sounding speech from text in multiple languages with various voice options and audio formats.
Try the Interactive Playground →Example Integrations
Authentication
All API requests require authentication using a Bearer token. Include your API key in the Authorization header of every request:
Authorization: Bearer YOUR_API_KEY
Available Models
The API provides two models optimized for different use cases:
English Model
englishHigh-quality English-only voice synthesis with the best performance for English content.
Multi Model
multiSupport for multiple languages with natural pronunciation and accent handling.
Available Voices
Browse our library of +5,000 stock voices available for text-to-speech generation. Use the filters below to find the perfect voice.
Speech Generation: POST /api/v1/speech
This endpoint generates speech audio from text input. The audio is streamed in real-time as it's being generated.
Request
Send a POST request with a JSON body containing your text and voice configuration.
Required Parameters
| Parameter | Type | Description |
|---|---|---|
transcript | string | The text to convert to speech |
voice.id | string | The ID of the voice to use (see Available Voices) |
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
model_id | string | "english" | Model to use: "english" or "multi" |
output_format.container | string | "mp3" | Audio format: "mp3" or "raw" |
output_format.sample_rate | integer | 44100 | Sample rate in Hz (8000, 16000, 22050, 44100, 48000) |
output_format.bit_rate | integer | 192000 | Bit rate for MP3 (32000-320000) |
output_format.encoding | string | "pcm_s16le" | Encoding for RAW format |
Example Request
{
"model_id": "english",
"transcript": "Hello! Welcome to our text-to-speech API. This is an example of high-quality voice synthesis.",
"voice": {
"id": "voice-id-here"
},
"output_format": {
"container": "mp3",
"sample_rate": 44100,
"bit_rate": 192000
}
}
Response
A successful request streams audio data directly. The Content-Type header will be set based on your chosen format:
audio/mpegfor MP3 formatapplication/octet-streamfor RAW format
Example response headers:
HTTP/1.1 200 OK
Content-Type: audio/mpeg
X-Content-Type-Options: nosniff
Cache-Control: no-cache
X-Accel-Buffering: no
Streaming Audio
The API streams audio in real-time as it's being generated, allowing playback to start before the entire audio is complete. This provides a better user experience with lower latency.
List Voices: POST /api/v1/voices
This endpoint returns a list of available voices with optional filtering. Use it to discover voices before generating speech.
Request Body (All Optional)
| Parameter | Type | Description |
|---|---|---|
limit | integer | Maximum number of voices to return (default: 50, max: 100) |
language | string | Filter by language code (e.g., "en", "de", "es") |
gender | string | Filter by gender: "Male", "Female", "Neutral", "Unspecified" |
model_id | string | Filter by model: "english" or "multi" |
my_voice | boolean | If true, returns only custom voices; if false, only stock voices |
after | string | Cursor for pagination |
Example Request
{
"limit": 50,
"language": "en",
"gender": "Female",
"model_id": "english",
"my_voice": false
}
Example Response
{
"voices": [
{
"voice_id": "abc123",
"name": "Sarah",
"voice_type": "PREDEFINED",
"language": "en",
"gender": "Female",
"accent": "American",
"style": "Conversational",
"description": "Warm and friendly voice perfect for narration"
},
{
"voice_id": "def456",
"name": "James",
"voice_type": "PREDEFINED",
"language": "en",
"gender": "Male",
"accent": "British",
"style": "Professional"
}
],
"next_cursor": "eyJ..."
}
next_cursor value in the after parameter to retrieve the next page of results. The API returns a maximum of 100 voices per request.
Voice Preview: GET /api/v1/preview/<voice_id>
This endpoint returns a preview URL for a specific voice, allowing you to hear a sample before using it for speech generation.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The voice ID to preview (required) |
Example Request
curl -X GET "https://voice.demo.efficientstack.com/api/v1/preview/abc123" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"signed_url": "https://storage.example.com/previews/abc123.mp3?signature=...",
"expires_at": 1699200000
}
The signed_url can be used directly in an audio player or downloaded. The URL typically expires after a certain period indicated by expires_at.
Audio Formats
The API supports multiple audio formats and encoding options to suit different use cases.
MP3 Format
Compressed audio format ideal for streaming and storage efficiency.
| Parameter | Options | Description |
|---|---|---|
sample_rate | 8000, 16000, 22050, 44100, 48000 | Higher rates provide better quality |
bit_rate | 32000 - 320000 | Higher rates provide better quality (192000 recommended) |
RAW Format
Uncompressed audio format for professional audio processing or custom encoding pipelines.
| Encoding | Description |
|---|---|
pcm_s16le | 16-bit signed PCM, little-endian (most common) |
pcm_f32le | 32-bit float PCM, little-endian (high precision) |
pcm_mulaw | μ-law encoding (telephony applications) |
Example: MP3 with High Quality
{
"output_format": {
"container": "mp3",
"sample_rate": 48000,
"bit_rate": 320000
}
}
Example: RAW PCM
{
"output_format": {
"container": "raw",
"sample_rate": 44100,
"encoding": "pcm_s16le"
}
}
Error Handling
When an error occurs, the API returns an appropriate HTTP status code and a JSON error object:
{
"error": {
"message": "Invalid API key provided",
"type": "invalid_request_error",
"code": null
}
}
Common Error Codes
| Status Code | Error Type | Description |
|---|---|---|
400 | Bad Request | Invalid request format or parameters |
401 | Unauthorized | Missing or invalid API key |
402 | Payment Required | Insufficient account balance |
404 | Not Found | Voice ID not found |
500 | Server Error | Internal server error, try again later |
Balance Errors
If your account balance is insufficient for the requested operation, you'll receive a 402 error:
{
"error": {
"message": "Insufficient balance. Required: $0.0025, Available: $0.0010",
"type": "insufficient_balance",
"code": null
}
}
Code Examples
Here are examples of how to use the API in different programming languages.
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://voice.demo.efficientstack.com/api/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def list_voices():
response = requests.post(
f"{BASE_URL}/voices",
headers=headers,
json={
"limit": 50,
"language": "en",
"gender": "Female",
"my_voice": False
}
)
return response.json()
def generate_speech(text, voice_id):
response = requests.post(
f"{BASE_URL}/speech",
headers=headers,
json={
"model_id": "english",
"transcript": text,
"voice": {"id": voice_id},
"output_format": {
"container": "mp3",
"sample_rate": 44100,
"bit_rate": 192000
}
},
stream=True
)
with open("output.mp3", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
return "output.mp3"
def preview_voice(voice_id):
response = requests.get(
f"{BASE_URL}/preview",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"id": voice_id}
)
return response.json()
voices = list_voices()
print(f"Found {len(voices['voices'])} voices")
if voices['voices']:
voice_id = voices['voices'][0]['voice_id']
audio_file = generate_speech("Hello, this is a test!", voice_id)
print(f"Audio saved to {audio_file}")
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://voice.demo.efficientstack.com/api/v1";
const headers = {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
};
async function listVoices() {
const response = await fetch(`${BASE_URL}/voices`, {
method: "POST",
headers: headers,
body: JSON.stringify({
limit: 50,
language: "en",
gender: "Female",
my_voice: false
})
});
return await response.json();
}
async function generateSpeech(text, voiceId) {
const response = await fetch(`${BASE_URL}/speech`, {
method: "POST",
headers: headers,
body: JSON.stringify({
model_id: "english",
transcript: text,
voice: { id: voiceId },
output_format: {
container: "mp3",
sample_rate: 44100,
bit_rate: 192000
}
})
});
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'speech.mp3';
a.click();
return url;
}
async function previewVoice(voiceId) {
const response = await fetch(
`${BASE_URL}/preview/${voiceId}`,
{
headers: { "Authorization": `Bearer ${API_KEY}` }
}
);
return await response.json();
}
async function main() {
const voices = await listVoices();
console.log(`Found ${voices.voices.length} voices`);
if (voices.voices.length > 0) {
const voiceId = voices.voices[0].voice_id;
await generateSpeech("Hello, this is a test!", voiceId);
console.log("Audio generated and downloaded");
}
}
main();
curl -X POST "https://voice.demo.efficientstack.com/api/v1/voices" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"limit": 50,
"language": "en",
"gender": "Female",
"my_voice": false
}'
curl -X POST "https://voice.demo.efficientstack.com/api/v1/speech" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model_id": "english",
"transcript": "Hello, this is a test of the text-to-speech API!",
"voice": {
"id": "voice-id-here"
},
"output_format": {
"container": "mp3",
"sample_rate": 44100,
"bit_rate": 192000
}
}' \
--output speech.mp3
curl -X GET "https://voice.demo.efficientstack.com/api/v1/preview/voice-id-here" \
-H "Authorization: Bearer YOUR_API_KEY"
curl -X POST "https://voice.demo.efficientstack.com/api/v1/speech" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model_id": "multi",
"transcript": "Bonjour! Comment allez-vous?",
"voice": {
"id": "french-voice-id"
}
}' \
--output french_speech.mp3
<?php
$apiKey = "YOUR_API_KEY";
$baseUrl = "https://voice.demo.efficientstack.com/api/v1";
function listVoices($apiKey, $baseUrl) {
$ch = curl_init("$baseUrl/voices");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'limit' => 50,
'language' => 'en',
'gender' => 'Female',
'my_voice' => false
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
function generateSpeech($apiKey, $baseUrl, $text, $voiceId) {
$ch = curl_init("$baseUrl/speech");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'model_id' => 'english',
'transcript' => $text,
'voice' => ['id' => $voiceId],
'output_format' => [
'container' => 'mp3',
'sample_rate' => 44100,
'bit_rate' => 192000
]
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$audioData = curl_exec($ch);
curl_close($ch);
file_put_contents('output.mp3', $audioData);
return 'output.mp3';
}
function previewVoice($apiKey, $baseUrl, $voiceId) {
$ch = curl_init("$baseUrl/preview/" . urlencode($voiceId));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
$voices = listVoices($apiKey, $baseUrl);
echo "Found " . count($voices['voices']) . " voices\n";
if (!empty($voices['voices'])) {
$voiceId = $voices['voices'][0]['voice_id'];
$audioFile = generateSpeech($apiKey, $baseUrl, "Hello, this is a test!", $voiceId);
echo "Audio saved to $audioFile\n";
}
?>