real-time neural synthesis

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.

Try it now Back to API Hub

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

๐ŸŽ™๏ธ Generate SpeechPOST /api/v1/tts/generate
๐ŸŽš๏ธ Get VoicesGET /api/v1/tts/voices
๐Ÿ’š Health CheckGET /api/v1/tts/health

Request 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

ParameterTypeRequiredDefaultDescription
textstringYes-The text to convert to speech
voicestringNoSystem defaultVoice selection (e.g., "en-US-Wavenet-A")
speednumberNo1.0Speech speed multiplier (0.5-2.0)
pitchnumberNo0Voice pitch adjustment (-10 to +10)
volumenumberNo1.0Volume level (0.0-1.0)
formatstringNomp3Output 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)

Use our complete Python SDK for easy integration with error handling, rate limiting, and Unicode support.

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

Error Handling

Comprehensive error handling with detailed messages

Rate Limiting

Automatic handling of rate limits with retry logic

Unicode Support

Full Unicode text support with safe encoding

File Operations

Direct file saving with proper binary handling

Supported Formats

All formats are supported across all backends via automatic conversion.
MP3
High quality
WAV
Uncompressed
OGG
Compressed

Backend Format Support

gTTS
MP3 WAV OGG
pyttsx3
MP3 WAV OGG
Edge Neural
MP3 WAV OGG

โœ“ 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

Max text length: 15,000 characters
Rate limit: 8 requests per minute
Audio not retained persistently โ€” download immediately
Voice & language compatibility varies per engine
Backend availability depends on engine status

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