Error Handling
Understanding and handling errors from the Text-to-Speech API.
HTTP Status Codes
| Code | Description | Common Cause |
| 200 | Success | Request completed successfully |
| 400 | Bad Request | Invalid parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 402 | Payment Required | Insufficient credits |
| 403 | Forbidden | Valid key but insufficient permissions |
| 404 | Not Found | Resource or endpoint not found |
| 413 | Payload Too Large | Text exceeds 5,000 characters |
| 422 | Unprocessable | Valid request but failed validation |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server-side issue |
| 503 | Service Unavailable | Temporary overload |
Error Response Format
{
"success": false,
"error": {
"code": "INVALID_VOICE",
"message": "Voice 'InvalidVoice' not found.",
"category": "validation",
"resolution": "Use /v1/voices endpoint to get valid voice names",
"details": {
"provided": "InvalidVoice",
"suggestions": ["Peter", "Emma", "James"]
}
},
"request_id": "req_abc123xyz",
"timestamp": 1699820400.123
}
| Field | Description |
success | Always false for error responses |
error.code | Machine-readable error code for programmatic handling |
error.message | Human-readable description of the error |
error.category | Error category (authentication, validation, rate_limit, etc.) |
error.resolution | Suggested steps to resolve the issue |
request_id | Unique ID for tracking this request (useful for support) |
Common Error Codes
Authentication Errors
| Error Code | Description | Solution |
MISSING_API_KEY | No API key provided | Add X-API-Key header |
INVALID_API_KEY | API key not recognized | Verify your API key |
API_KEY_EXPIRED | API key has expired | Generate a new API key from dashboard |
API_KEY_REVOKED | API key has been revoked | Contact support or generate new key |
API_KEY_DISABLED | API key has been disabled | Contact support |
Validation Errors
| Error Code | Description | Solution |
MISSING_TEXT | No text provided | Include text in request body |
TEXT_TOO_LONG | Text exceeds 5,000 characters | Split into multiple requests |
INVALID_VOICE | Voice not found | Use valid voice name from /v1/voices |
INVALID_LANGUAGE | Language not supported | Use valid language code from /v1/languages |
INVALID_MODEL | Model not found | Use: aura-lite, aura-prime, aura-max, rapid-flash, rapid-max |
INVALID_SPEED | Speed out of range | Use value between 0.5 and 2.0 |
INVALID_PITCH | Pitch out of range | Use value between 0.5 and 2.0 |
INVALID_FORMAT | Output format not supported | Use mp3 or wav |
Credit Errors
| Error Code | Description | Solution |
INSUFFICIENT_CREDITS | Not enough credits | Add credits to account |
CREDIT_CHECK_FAILED | Unable to verify credits | Retry request |
Rate Limit Errors
| Error Code | Description | Solution |
RATE_LIMIT_EXCEEDED | Too many requests | Wait and retry with backoff |
CONCURRENT_LIMIT | Too many concurrent requests | Wait for requests to complete |
Model-Specific Errors
| Error Code | Description | Solution |
LANGUAGE_NOT_SUPPORTED | Language not supported by model | Use different model (rapid-flash has 18 languages, rapid-max has 41) |
EXPRESSION_NOT_SUPPORTED | Expression tags not supported | Use Aura model for expressions |
Permission Errors
| Error Code | Description | Solution |
MODEL_ACCESS_DENIED | Your plan doesn't include this model | Upgrade to a plan with access to this model |
VOICE_ACCESS_DENIED | Premium voice not available on your plan | Upgrade to access premium voices |
FEATURE_DISABLED | Feature not enabled for your account | Contact support to enable this feature |
Retry Strategy
Different errors require different retry approaches:
| Error Type | Should Retry? | Strategy |
| 400 Validation |
❌ No |
Fix the request parameters |
| 401 Auth |
❌ No |
Check/refresh API key |
| 402 Payment |
❌ No |
Add credits to account |
| 403 Permission |
❌ No |
Upgrade plan or contact support |
| 429 Rate Limit |
✅ Yes |
Wait for Retry-After header duration |
| 500 Server |
✅ Yes |
Exponential backoff (1s, 2s, 4s...) |
| 503 Unavailable |
✅ Yes |
Wait and retry with backoff |
💡 Exponential Backoff
For server errors, use exponential backoff: wait 1s, then 2s, then 4s, etc. Add random jitter (0-1s) to prevent thundering herd issues when many clients retry simultaneously.
Error Handling Example
import requests
import time
def generate_speech_with_retry(text, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.post(
"https://yourvoic.com/api/v1/tts/generate",
headers={"X-API-Key": "your_api_key"},
json={
"text": text,
"voice": "Peter",
"language": "en-US"
}
)
if response.status_code == 200:
return response.content
# Parse error response
error = response.json().get('error', {})
error_code = error.get('code', '')
# Don't retry these errors
non_retryable = [
'INVALID_VOICE', 'INVALID_LANGUAGE', 'INVALID_MODEL',
'TEXT_TOO_LONG', 'INVALID_API_KEY', 'INSUFFICIENT_CREDITS'
]
if error_code in non_retryable:
raise Exception(f"Non-retryable error: {error_code} - {error.get('message')}")
# Retry with exponential backoff for rate limits
if response.status_code == 429:
wait_time = (2 ** attempt) + 1
print(f"Rate limited. Retrying in {wait_time}s...")
time.sleep(wait_time)
continue
# Retry server errors
if response.status_code >= 500:
wait_time = 2 ** attempt
print(f"Server error. Retrying in {wait_time}s...")
time.sleep(wait_time)
continue
raise Exception(f"Request failed: {error}")
except requests.RequestException as e:
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
continue
raise
raise Exception("Max retries exceeded")
# Usage
try:
audio = generate_speech_with_retry("Hello, world!")
with open("output.mp3", "wb") as f:
f.write(audio)
except Exception as e:
print(f"Error: {e}")
JavaScript Example
async function generateTTSWithRetry(text, maxRetries = 3) {
const url = 'https://yourvoic.com/api/v1/tts/generate';
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key'
},
body: JSON.stringify({
text: text,
voice: 'Peter',
language: 'en-US'
})
});
if (response.ok) {
return await response.blob();
}
const error = await response.json();
const errorCode = error.error?.code;
// Don't retry these errors
const nonRetryable = [
'INVALID_VOICE', 'INVALID_LANGUAGE', 'INVALID_MODEL',
'TEXT_TOO_LONG', 'INVALID_API_KEY', 'INSUFFICIENT_CREDITS'
];
if (nonRetryable.includes(errorCode)) {
throw new Error(`Non-retryable: ${errorCode} - ${error.error?.message}`);
}
// Retry rate limits with backoff
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || (2 ** attempt);
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
// Retry server errors
if (response.status >= 500) {
const waitTime = Math.pow(2, attempt) * 1000;
console.log(`Server error. Retrying in ${waitTime}ms...`);
await new Promise(r => setTimeout(r, waitTime));
continue;
}
throw new Error(`Request failed: ${errorCode}`);
} catch (e) {
if (attempt === maxRetries - 1) throw e;
}
}
throw new Error('Max retries exceeded');
}
// Usage
generateTTSWithRetry("Hello, world!")
.then(blob => {
const url = URL.createObjectURL(blob);
const audio = new Audio(url);
audio.play();
})
.catch(e => console.error('Error:', e));
Debugging Tips
- Save the request_id - Include it when contacting support for faster resolution
- Check response headers - Rate limit headers show remaining quota
- Validate locally - Check text length and parameters before making API calls
- Use the health endpoint - Check
/v1/health to verify API availability
- Log full responses - The resolution field often contains the fix
# Check API health status
curl -s https://yourvoic.com/api/v1/health | jq
# Test your API key
curl -s -H "X-API-Key: your_key" \
https://yourvoic.com/api/v1/usage | jq
Best Practices
- Validate input - Check text length and parameters before sending
- Handle rate limits - Implement exponential backoff
- Monitor credits - Check balance before large batches
- Log errors - Keep track of error codes for debugging
- Test edge cases - Handle empty text, special characters, long content