Best Practices

Optimize your API usage for better performance, reliability, and cost efficiency.

Text Optimization

Prepare your text for the best audio quality:

✅ Do

  • Use proper punctuation for natural pauses
  • Add commas where you want brief pauses
  • Use periods for complete sentence breaks
  • Spell out numbers contextually ("twenty dollars" vs "20")
  • Expand abbreviations if pronunciation matters

❌ Avoid

  • Very long sentences without punctuation
  • Excessive special characters or symbols
  • Multiple consecutive spaces or newlines
  • HTML or markup in your text
python
# Clean text before sending
import re

def prepare_text(text):
    # Remove HTML tags
    text = re.sub(r'<[^>]+>', '', text)
    # Normalize whitespace
    text = ' '.join(text.split())
    # Ensure ending punctuation
    if not text.endswith(('.', '!', '?')):
        text += '.'
    return text

Chunking Long Text

For text longer than 5,000 characters, split it intelligently:

python
def chunk_text(text, max_chars=4500):
    """Split text at sentence boundaries."""
    sentences = text.replace('! ', '!|').replace('. ', '.|').replace('? ', '?|').split('|')
    
    chunks = []
    current_chunk = ""
    
    for sentence in sentences:
        if len(current_chunk) + len(sentence) < max_chars:
            current_chunk += sentence + " "
        else:
            if current_chunk:
                chunks.append(current_chunk.strip())
            current_chunk = sentence + " "
    
    if current_chunk:
        chunks.append(current_chunk.strip())
    
    return chunks

# Generate audio for each chunk
chunks = chunk_text(long_article)
for i, chunk in enumerate(chunks):
    audio = generate_tts(chunk)
    save_audio(audio, f"part_{i+1}.mp3")
💡 Tip

Always split at sentence boundaries, not mid-sentence. This ensures natural audio flow and avoids cut-off words.

Voice Selection

Choose the right voice for your use case:

Use CaseRecommended Voice TypeExample
Audiobooks Narrative, warm tone Peter, Sarah
E-learning Clear, professional Alice, James
IVR/Phone Neutral, professional Rachel, Thomas
Marketing Energetic, engaging Emma, Michael
Accessibility Clear, moderate pace Any voice at speed 0.9
python
# Preview voices before committing
voices = client.list_voices(language="en-US")

# Filter by use case
narrative_voices = [v for v in voices if "narrative" in v.get("tags", [])]
professional_voices = [v for v in voices if "professional" in v.get("tags", [])]

Caching Strategy

Cache generated audio to reduce API calls and costs:

python
import hashlib
import os

def get_cache_key(text, voice_id, speed=1.0):
    """Generate unique cache key for TTS request."""
    content = f"{text}:{voice_id}:{speed}"
    return hashlib.md5(content.encode()).hexdigest()

def get_or_generate_audio(text, voice_id, speed=1.0):
    """Check cache first, generate if not found."""
    cache_key = get_cache_key(text, voice_id, speed)
    cache_path = f"cache/{cache_key}.mp3"
    
    # Return cached audio if exists
    if os.path.exists(cache_path):
        with open(cache_path, 'rb') as f:
            return f.read()
    
    # Generate new audio
    audio = generate_tts(text, voice_id, speed)
    
    # Save to cache
    os.makedirs('cache', exist_ok=True)
    with open(cache_path, 'wb') as f:
        f.write(audio)
    
    return audio
💡 When to Cache
  • Static content (welcome messages, prompts)
  • Frequently requested phrases
  • Repeated UI elements

Error Handling

Build resilient applications with proper error handling:

python
import time
import random

def generate_with_retry(text, voice_id, max_retries=3):
    """Generate TTS with exponential backoff retry."""
    for attempt in range(max_retries):
        try:
            response = requests.post(API_URL, json={
                "text": text,
                "voice_id": voice_id
            }, headers={"X-API-Key": API_KEY}, timeout=30)
            
            if response.status_code == 200:
                return response.content
            
            if response.status_code == 429:
                # Rate limited - respect Retry-After header
                retry_after = int(response.headers.get("Retry-After", 60))
                time.sleep(retry_after)
                continue
            
            if response.status_code >= 500:
                # Server error - exponential backoff
                wait = (2 ** attempt) + random.uniform(0, 1)
                time.sleep(wait)
                continue
            
            # Client error - don't retry
            response.raise_for_status()
            
        except requests.exceptions.Timeout:
            if attempt == max_retries - 1:
                raise
            time.sleep(2 ** attempt)
    
    raise Exception("Max retries exceeded")

Rate Limit Management

Stay within limits to ensure uninterrupted service:

python
import time
from collections import deque

class RateLimiter:
    """Simple rate limiter for API calls."""
    
    def __init__(self, max_per_minute=60):
        self.max_per_minute = max_per_minute
        self.requests = deque()
    
    def wait_if_needed(self):
        now = time.time()
        minute_ago = now - 60
        
        # Remove old requests
        while self.requests and self.requests[0] < minute_ago:
            self.requests.popleft()
        
        # Wait if at limit
        if len(self.requests) >= self.max_per_minute:
            sleep_time = self.requests[0] - minute_ago + 0.1
            time.sleep(sleep_time)
        
        self.requests.append(now)

# Usage
rate_limiter = RateLimiter(max_per_minute=60)

for text in texts_to_convert:
    rate_limiter.wait_if_needed()
    audio = generate_tts(text)

Cost Optimization

Minimize character usage without sacrificing quality:

TipSavingsExample
Remove redundant whitespace 5-10% "Hello world""Hello world"
Cache static content 50-90% Pre-generate welcome messages
Use appropriate model Variable Use aura-lite for IVR prompts
Batch similar requests 10-20% Generate all chapters at once
python
# Track your usage
def check_usage():
    response = requests.get(
        "https://yourvoic.com/api/v1/usage",
        headers={"X-API-Key": API_KEY}
    )
    usage = response.json()
    
    chars_used = usage["characters_used"]
    chars_limit = usage["characters_limit"]
    percent_used = (chars_used / chars_limit) * 100
    
    print(f"Usage: {chars_used:,} / {chars_limit:,} ({percent_used:.1f}%)")
    
    if percent_used > 80:
        print("⚠️ Warning: Approaching character limit!")

Security

Protect your API keys and user data:

  • Never expose keys - Store in environment variables, not code
  • Use server-side calls - Never call API from client-side JavaScript
  • Rotate keys regularly - Update API keys every 90 days
  • Monitor usage - Set up alerts for unusual activity
  • Limit permissions - Use read-only keys where possible
python
import os
from dotenv import load_dotenv

# Load from .env file (never commit this file!)
load_dotenv()

API_KEY = os.getenv("YOURVOIC_API_KEY")

if not API_KEY:
    raise ValueError("YOURVOIC_API_KEY environment variable not set")