Text-to-Speech
API Documentation
Convert written text into expressive, natural-sounding speech across multiple engines โ Google TTS, pyttsx3, Microsoft Edge Neural, and adaptive formats. Built for developers.
Overview
The Text-to-Speech API converts written text into natural-sounding speech audio using multiple backend engines including Google Text-to-Speech, pyttsx3, and Microsoft Edge Neural. This service supports multiple languages, voices, and audio formats to meet various application needs. Each request returns a downloadable audio URL with metadata.
Endpoints
POST /api/v1/tts/generateGET /api/v1/tts/voicesGET /api/v1/tts/healthRequest Format
Headers
Content-Type: application/json
X-API-Key: your_api_key_here
X-API-Secret: YOUR_API_SECRET
Request Body
{
"text": "Hello, this is a sample text to convert to speech",
"voice": "en-US-Wavenet-A",
"speed": 1.0,
"format": "mp3"
}
Response Format
Success Response (200)
{
"success": true,
"audio_url": "https://api.example.com/audio/tts_123456.mp3",
"duration": 3.45,
"size_bytes": 55232,
"format": "mp3",
"voice_used": "en-US-Wavenet-A"
}
Error Response (400/500)
{
"success": false,
"error": "Text is too long. Maximum 5000 characters allowed.",
"error_code": "TEXT_TOO_LONG"
}
Voice Options
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
text | string | Yes | - | The text to convert to speech |
voice | string | No | System default | Voice selection (e.g., "en-US-Wavenet-A") |
speed | number | No | 1.0 | Speech speed multiplier (0.5-2.0) |
pitch | number | No | 0 | Voice pitch adjustment (-10 to +10) |
volume | number | No | 1.0 | Volume level (0.0-1.0) |
format | string | No | mp3 | Output audio format |
Code Examples
Python
import requests
url = "/api/v1/tts/generate"
headers = {
"Content-Type": "application/json",
"X-API-Key": "your_api_key_here"
}
data = {
"text": "Hello, world!",
"voice": "en-US-Wavenet-A",
"format": "mp3"
}
response = requests.post(url, json=data, headers=headers)
result = response.json()
if result["success"]:
print(f"Audio URL: {result['audio_url']}")
print(f"Duration: {result['duration']} seconds")
JavaScript
const response = await fetch('/api/v1/tts/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key_here'
},
body: JSON.stringify({
text: 'Hello, world!',
voice: 'en-US-Wavenet-A',
format: 'mp3'
})
});
const result = await response.json();
if (result.success) {
console.log('Audio URL:', result.audio_url);
console.log('Duration:', result.duration, 'seconds');
}
cURL
curl -X POST "/api/v1/tts/generate" \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{
"text": "Hello, world!",
"voice": "en-US-Wavenet-A",
"format": "mp3"
}'
Python SDK (Recommended)
Installation
# Install required package
pip install requests
โ ๏ธ API Configuration Required
# Before using the SDK, you need to configure your API credentials:
# 1. Get your API Key and Secret from your dashboard
# 2. Set them as environment variables or replace the placeholders below
# 3. Update the server URL to point to your TTS service
#
# Recommended: use environment variables (never commit real secrets):
import os
BASE_URL = os.environ.get("BASE_URL", "https://odivora.com")
TTS_API_KEY = os.environ.get("TTS_API_KEY", "your_api_key_from_dashboard")
TTS_API_SECRET = os.environ.get("TTS_API_SECRET", "your_api_secret_from_dashboard")
Complete SDK Class
import requests
import json
import time
from datetime import datetime
class TTSClient:
"""Complete TTS Python SDK with error handling and Unicode support"""
def __init__(self, base_url, api_key, api_secret):
self.base_url = base_url
self.api_key = api_key
self.api_secret = api_secret
self.headers = {
"Content-Type": "application/json",
"X-API-Key": api_key,
"X-API-Secret": api_secret
}
self.session = requests.Session()
self.session.headers.update(self.headers)
def health_check(self):
"""Check TTS service health"""
try:
response = self.session.get(f"{self.base_url}/api/v1/tts/health", timeout=10)
if response.status_code == 200:
return response.json()
else:
return {"success": False, "error": f"HTTP {response.status_code}"}
except Exception as e:
return {"success": False, "error": str(e)}
def get_voices(self):
"""Get available voices"""
try:
response = self.session.get(f"{self.base_url}/api/v1/tts/voices", timeout=10)
if response.status_code == 200:
return response.json()
else:
return {"success": False, "error": f"HTTP {response.status_code}"}
except Exception as e:
return {"success": False, "error": str(e)}
def generate_speech(self, text, voice=None, speed=1.0, format="mp3"):
"""Generate speech from text"""
try:
payload = {
"text": text,
"format": format
}
if voice:
payload["voice"] = voice
if speed != 1.0:
payload["speed"] = speed
response = self.session.post(f"{self.base_url}/api/v1/tts/generate",
json=payload, timeout=30)
if response.status_code == 200:
# Return binary audio data
return {
"success": True,
"audio_data": response.content,
"content_type": response.headers.get('content-type', ''),
"size_bytes": len(response.content)
}
elif response.status_code == 429:
return {"success": False, "error": "Rate limited - please wait"}
else:
return {"success": False, "error": f"HTTP {response.status_code}"}
except Exception as e:
return {"success": False, "error": str(e)}
def generate_speech_to_file(self, text, filename, voice=None, speed=1.0, format="mp3"):
"""Generate speech and save to file"""
result = self.generate_speech(text, voice, speed, format)
if result["success"]:
with open(filename, 'wb') as f:
f.write(result["audio_data"])
return {
"success": True,
"filename": filename,
"size_bytes": result["size_bytes"]
}
else:
return result
Usage Example
# Initialize TTS Client
# REPLACE THESE VALUES WITH YOUR ACTUAL API CREDENTIALS
tts = TTSClient(
base_url="BASE_URL", # e.g., "https://odivora.com"
api_key="TTS_API_KEY", # Your API key from dashboard
api_secret="TTS_API_SECRET" # Your API secret from dashboard
)
# Check service health
health = tts.health_check()
if health["success"]:
print(f"Service Status: {health['status']}")
print(f"Active Backends: {list(health['tts_backends'].keys())}")
# Get available voices
voices = tts.get_voices()
if voices["success"]:
print("Available voices:")
for backend, voice_list in voices["voices"].items():
if isinstance(voice_list, list):
print(f" {backend}: {len(voice_list)} voices")
# Generate speech and save to file
result = tts.generate_speech_to_file(
text="Hello, this is a test of the TTS service!",
filename="output.mp3",
voice="Microsoft David Desktop - English (United States)",
speed=1.2
)
if result["success"]:
print(f"Audio generated successfully!")
print(f"File: {result['filename']}")
print(f"Size: {result['size_bytes']} bytes")
else:
print(f"Error: {result['error']}")
# Generate speech with different parameters
test_cases = [
{"text": "Basic test", "voice": None},
{"text": "Fast speech", "speed": 1.5},
{"text": "Slow speech", "speed": 0.8}
]
for i, test in enumerate(test_cases, 1):
result = tts.generate_speech_to_file(
text=test["text"],
filename=f"test_{i}.mp3",
voice=test.get("voice"),
speed=test.get("speed", 1.0)
)
if result["success"]:
print(f"Test {i}: SUCCESS - {result['size_bytes']} bytes")
else:
print(f"Test {i}: FAILED - {result['error']}")
# Add delay to avoid rate limiting
time.sleep(1)
๐ Complete Working Example
# Complete TTS SDK Working Example
# Save this as: tts_example.py
import requests
import time
# ========================================
# CONFIGURATION - SET YOUR CREDENTIALS HERE
# Only edit the three values below. Secrets
# must live here at the top of the file,
# never inline inside the rest of the code.
# ========================================
BASE_URL = "https://odivora.com" # REPLACE: Your TTS server URL
TTS_API_KEY = "your_api_key_here" # REPLACE: Your API key from dashboard
TTS_API_SECRET = "your_api_secret_here" # REPLACE: Your API secret from dashboard
# (Recommended for production) Load credentials from environment variables:
# import os
# BASE_URL = os.environ.get("BASE_URL", BASE_URL)
# TTS_API_KEY = os.environ.get("TTS_API_KEY", TTS_API_KEY)
# TTS_API_SECRET = os.environ.get("TTS_API_SECRET", TTS_API_SECRET)
# Fail fast if the placeholders above were not replaced
if TTS_API_KEY == "your_api_key_here":
raise SystemExit(
"Set your API key, secret, and server URL in the CONFIGURATION "
"section at the top of this file before running."
)
class TTSClient:
"""Complete TTS Python SDK with error handling and Unicode support"""
def __init__(self, base_url, api_key, api_secret):
self.base_url = base_url
self.api_key = api_key
self.api_secret = api_secret
self.headers = {
"Content-Type": "application/json",
"X-API-Key": api_key,
"X-API-Secret": api_secret
}
self.session = requests.Session()
self.session.headers.update(self.headers)
def health_check(self):
"""Check TTS service health"""
try:
response = self.session.get(f"{self.base_url}/api/v1/tts/health", timeout=10)
if response.status_code == 200:
return response.json()
else:
return {"success": False, "error": f"HTTP {response.status_code}"}
except Exception as e:
return {"success": False, "error": str(e)}
def get_voices(self):
"""Get available voices"""
try:
response = self.session.get(f"{self.base_url}/api/v1/tts/voices", timeout=10)
if response.status_code == 200:
return response.json()
else:
return {"success": False, "error": f"HTTP {response.status_code}"}
except Exception as e:
return {"success": False, "error": str(e)}
def generate_speech_to_file(self, text, filename, voice=None, speed=1.0, format="mp3"):
"""Generate speech and save to file"""
try:
payload = {"text": text, "format": format}
if voice: payload["voice"] = voice
if speed != 1.0: payload["speed"] = speed
response = self.session.post(f"{self.base_url}/api/v1/tts/generate",
json=payload, timeout=30)
if response.status_code == 200:
with open(filename, 'wb') as f:
f.write(response.content)
return {
"success": True,
"filename": filename,
"size_bytes": len(response.content)
}
else:
return {"success": False, "error": f"HTTP {response.status_code}"}
except Exception as e:
return {"success": False, "error": str(e)}
# ========================================
# STEP 1: INITIALIZE THE CLIENT
# Credentials are read from the
# CONFIGURATION block at the top.
# ========================================
tts = TTSClient(
base_url=BASE_URL,
api_key=TTS_API_KEY,
api_secret=TTS_API_SECRET
)
# ========================================
# STEP 2: RUN THE TESTS
# ========================================
print("๐ค Testing TTS Service...")
# Test health check
print("\n1. Health Check:")
health = tts.health_check()
if health.get("success") or health.get("status") == "healthy":
print(f" โ
Service Status: {health.get('status')}")
print(f" โ
Active Backends: {list(health.get('tts_backends', {}).keys())}")
else:
print(f" โ Health Check Failed: {health.get('error')}")
exit(1)
# Test voices
print("\n2. Available Voices:")
voices = tts.get_voices()
if voices.get("success"):
for backend, voice_list in voices["voices"].items():
if isinstance(voice_list, list) and len(voice_list) > 0:
print(f" โ
{backend}: {len(voice_list)} voices")
for voice in voice_list[:2]: # Show first 2
print(f" - {voice}")
else:
print(f" โ
{backend}: Available")
else:
print(f" โ Voices Check Failed: {voices.get('error')}")
exit(1)
# Test speech generation
print("\n3. Speech Generation:")
test_cases = [
{"text": "Hello! This is a test of the TTS service.", "filename": "test_basic.mp3"},
{"text": "This is a faster speech test.", "filename": "test_fast.mp3", "speed": 1.3},
{"text": "This is a slower speech test.", "filename": "test_slow.mp3", "speed": 0.8}
]
for i, test in enumerate(test_cases, 1):
print(f"\n Test {i}: {test['text'][:30]}...")
result = tts.generate_speech_to_file(
text=test["text"],
filename=test["filename"],
speed=test.get("speed", 1.0)
)
if result["success"]:
print(f" โ
SUCCESS: Generated {result['filename']} ({result['size_bytes']} bytes)")
else:
print(f" โ FAILED: {result['error']}")
# Add delay to avoid rate limiting
if i < len(test_cases):
time.sleep(1)
print("\n๐ All tests completed! Check the generated MP3 files.")
print("\n๐ Generated files:")
for test in test_cases:
print(f" - {test['filename']}")
SDK Features
Comprehensive error handling with detailed messages
Automatic handling of rate limits with retry logic
Full Unicode text support with safe encoding
Direct file saving with proper binary handling
Supported Formats
Backend Format Support
โ Universal Format Support: All backends now support MP3, WAV, and OGG formats through automatic conversion using FFmpeg. Request any format and get the desired output.
Limitations
Quick Start
1. Get API Key
Generate from your profile section
2. Make Request
POST text + voice params
3. Get Audio
Stream or download via URL