API Reference
Base URL: https://api.leanvox.com
Authentication
All API requests require an API key passed via the Authorization header.
Authorization: Bearer lv_live_YOUR_API_KEYGenerate API keys from the dashboard. Keys use the lv_live_ prefix and are hashed server-side — save them when created.
Register
POST
/v1/auth/register{ "email": "you@example.com", "password": "your-password" }Login
POST
/v1/auth/login{ "email": "you@example.com", "password": "your-password" } Returns: { "token": "jwt...", "user": { "id", "email" } }
Generate Speech
POST
/v1/tts/generate{
"text": "Hello world!",
"model": "standard", // "standard" or "pro"
"voice": "af_heart", // voice ID
"language": "en", // ISO 639-1 code
"format": "mp3", // optional: "mp3" (default) or "wav"
"speed": 1.0, // optional: 0.5 - 2.0
"exaggeration": 0.5 // optional (pro only): 0.0 - 1.0
}Response
{
"audio_url": "https://cdn.leanvox.com/audio/abc123.mp3",
"model": "standard",
"voice": "af_heart",
"characters": 12,
"cost_cents": 0.06
}Models
| Model | Engine | Price | Features |
|---|---|---|---|
| standard | Kokoro 82M | $0.005/1K | Fast, 54+ voices, 10 languages |
| pro | Chatterbox 350M | $0.01/1K | Voice cloning, emotion tags, 23 languages |
Dialogue (Pro only)
Generate multi-speaker dialogue in a single request. Pro model only.
POST
/v1/tts/dialogue{
"model": "pro",
"lines": [
{ "text": "Hi there!", "voice": "emma", "language": "en" },
{ "text": "Hello! [laugh]", "voice": "james", "language": "en", "exaggeration": 0.7 }
],
"gap_ms": 500 // silence between lines (default 500)
}Voices
List Voices
GET
/v1/voices?model=standardClone Voice (Pro)
POST
/v1/voices/clone{
"name": "My Voice",
"audio_base64": "<base64-encoded WAV>",
"description": "optional description"
} Upload a 5-30 second WAV clip. Returns a voice_id for use with the Pro model.
Delete Voice
DELETE
/v1/voices/{voice_id}Async Jobs
For long texts, use async generation. You get a job ID immediately and poll for completion.
Create Async Job
POST
/v1/tts/generate/asyncSame body as /v1/tts/generate. Optional "webhook_url" for completion callback.
Check Job Status
GET
/v1/tts/jobs/{job_id}{
"id": "uuid",
"status": "pending" | "processing" | "completed" | "failed",
"audio_url": "...", // when completed
"error": "...", // when failed
"created_at": "..."
}Account
Get Balance
GET
/v1/account/balance{ "balance_cents": 450, "total_spent_cents": 50 }Usage History
GET
/v1/account/usage?days=30&model=standard&limit=100Buy Credits
POST
/v1/account/credits{ "amount_cents": 2000 } Returns a Stripe checkout URL. Tiers: $5 (0%), $20 (+10%), $50 (+15%), $100 (+20% bonus).
Errors
All errors follow a consistent format:
{ "error": { "code": "error_code", "message": "Human-readable message" } }| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Bad parameters |
| 401 | invalid_api_key | Missing or invalid key |
| 402 | insufficient_balance | Not enough credits |
| 404 | not_found | Resource not found |
| 429 | rate_limit_exceeded | 10/min (free) or 60/min (paid) |
| 500 | server_error | Internal error |