API Documentation

Generate speech, manage voices, and track usage programmatically.

Quick Start

  1. 1. Create an API key in the Developers dashboard
  2. 2. List voices to find a voice ID
  3. 3. Send a POST request to generate speech
  4. 4. Poll the generation endpoint until complete

Base URL

https://elocute-api.onrender.com/v1

Response Format

All responses are returned in JSON format.

json
// Success
{
  "id": "generation-uuid",
  "status": "processing"
}

// Error
{
  "error": "error_code",
  "message": "Human readable error message"
}

Authentication

All API requests require an API key. Create one in the Developers dashboard.

X-API-Key header (recommended)

X-API-Key: sk_live_your_api_key_here

Authorization header

Authorization: Bearer sk_live_your_api_key_here

Keep your keys secure

Never expose API keys in client-side code or public repositories. If a key is compromised, revoke it immediately from the dashboard.

Endpoints

POST/v1/tts

Generate speech from text using a specified voice.

Request Body

textrequired
string

Text to convert to speech (max 40,000 characters)

voice_idrequired
string

UUID of the voice to use

Response

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "processing"
}
GET/v1/generations/:id

Check the status of a generation request.

Response

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "audio_url": "https://cdn.elocute.net/audio/example.wav",
  "audio_duration": 5.2,
  "char_count": 100,
  "created_at": "2026-01-15T10:30:00Z",
  "completed_at": "2026-01-15T10:30:15Z"
}
GET/v1/voices

List all available voices (preset voices and your custom voices).

Response

json
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Rachel",
    "description": "American female, warm and friendly",
    "voice_type": "preset",
    "category": "American",
    "preview_url": "https://cdn.elocute.net/presets/preview.wav"
  }
]
GET/v1/voices/:id

Get details for a specific voice.

Response

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Rachel",
  "description": "American female, warm and friendly",
  "voice_type": "preset",
  "category": "American",
  "preview_url": "https://cdn.elocute.net/presets/preview.wav"
}
GET/v1/usage

Get your current usage statistics.

Response

json
{
  "chars_used_this_month": 500,
  "monthly_char_limit": 100000,
  "percentage_used": 0.5,
  "subscription_tier": "pro"
}

Code Examples

cURL

bash
# Generate speech
curl -X POST https://elocute-api.onrender.com/v1/tts \
  -H "X-API-Key: sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello, world! This is a test.",
    "voice_id": "550e8400-e29b-41d4-a716-446655440000"
  }'

# Check generation status
curl https://elocute-api.onrender.com/v1/generations/GENERATION_ID \
  -H "X-API-Key: sk_live_your_api_key"

# List voices
curl https://elocute-api.onrender.com/v1/voices \
  -H "X-API-Key: sk_live_your_api_key"

Python

python
import requests
import time

API_KEY = "sk_live_your_api_key"
BASE_URL = "https://elocute-api.onrender.com/v1"

headers = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}

# List available voices
voices = requests.get(f"{BASE_URL}/voices", headers=headers).json()
print(f"Found {len(voices)} voices")

# Generate speech
response = requests.post(
    f"{BASE_URL}/tts",
    headers=headers,
    json={
        "text": "Hello, world! This is a test.",
        "voice_id": voices[0]["id"]
    }
)
generation = response.json()
print(f"Generation started: {generation['id']}")

# Poll for completion
while True:
    status = requests.get(
        f"{BASE_URL}/generations/{generation['id']}",
        headers=headers
    ).json()

    if status["status"] == "completed":
        print(f"Audio URL: {status['audio_url']}")
        break
    elif status["status"] == "failed":
        print(f"Error: {status.get('error_message')}")
        break

    time.sleep(2)

JavaScript / TypeScript

typescript
const API_KEY = "sk_live_your_api_key";
const BASE_URL = "https://elocute-api.onrender.com/v1";

const headers = {
  "X-API-Key": API_KEY,
  "Content-Type": "application/json"
};

// List available voices
async function listVoices() {
  const response = await fetch(`${BASE_URL}/voices`, { headers });
  return response.json();
}

// Generate speech
async function generateSpeech(text: string, voiceId: string) {
  const response = await fetch(`${BASE_URL}/tts`, {
    method: "POST",
    headers,
    body: JSON.stringify({ text, voice_id: voiceId })
  });
  return response.json();
}

// Check generation status
async function getGeneration(id: string) {
  const response = await fetch(`${BASE_URL}/generations/${id}`, { headers });
  return response.json();
}

// Example usage
async function main() {
  const voices = await listVoices();
  console.log(`Found ${voices.length} voices`);

  const generation = await generateSpeech(
    "Hello, world! This is a test.",
    voices[0].id
  );
  console.log(`Generation started: ${generation.id}`);

  // Poll for completion
  let status;
  do {
    await new Promise(r => setTimeout(r, 2000));
    status = await getGeneration(generation.id);
  } while (status.status === "processing");

  if (status.status === "completed") {
    console.log(`Audio URL: ${status.audio_url}`);
  }
}

main();

Rate Limits

API requests are rate limited based on your subscription tier.

TierRequests / minMonthly Credits
Free10,000
Pro60100,000
Business150500,000

Rate Limit Headers

All responses include rate limit information:

X-RateLimit-LimitMaximum requests per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetSeconds until the rate limit resets

Rate limit exceeded

If you exceed the rate limit, you'll receive a 429 response with a Retry-After header indicating when you can retry.

Error Codes

The API uses standard HTTP status codes and returns detailed error information.

CodeError
400bad_request
401unauthorized
401invalid_api_key
401revoked_api_key
402usage_limit_exceeded
403voice_access_denied
404voice_not_found
404generation_not_found
429rate_limit_exceeded
500internal_error

Error Response Format

json
{
  "error": "voice_not_found",
  "message": "Voice with ID '550e8400-e29b-41d4-a716-446655440000' not found."
}

Need Help?