Give your code a voice (literally) 🎤
"API so good, your users will think your app learned to speak"
All API requests require authentication using an API key. Include your API key in the
Authorization header as a Bearer token:
Authorization: Bearer YOUR_API_KEY
https://ttsninja.com/api/v1
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Converts text to speech and returns a downloadable audio file URL. Like magic, but with more JSON!
| Parameter | Type | Required | Description |
|---|---|---|---|
text |
string | Required | The text to convert to speech (max 5000 characters) |
voice |
string | Required | Voice ID (e.g., "af_heart", "am_adam"). See Voice Reference below. |
speed |
float | Optional | Speech speed multiplier (0.5 - 2.0, default: 1.0) |
curl -X POST https://ttsninja.com/api/v1/tts/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Hello, world! This is a test.",
"voice": "af_heart",
"speed": 1.0
}'
<?php
$apiKey = 'YOUR_API_KEY';
$url = 'https://ttsninja.com/api/v1/tts/generate';
$data = [
'text' => 'Hello, world! This is a test.',
'voice' => 'af_heart',
'speed' => 1.0
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
if ($result['success']) {
echo 'Audio URL: ' . $result['data']['audio_url'];
} else {
echo 'Error: ' . $result['error'];
}
?>
import requests
api_key = 'YOUR_API_KEY'
url = 'https://ttsninja.com/api/v1/tts/generate'
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
data = {
'text': 'Hello, world! This is a test.',
'voice': 'af_heart',
'speed': 1.0
}
response = requests.post(url, json=data, headers=headers)
result = response.json()
if result['success']:
print(f"Audio URL: {result['data']['audio_url']}")
print(f"Credits remaining: {result['credits_remaining']}")
else:
print(f"Error: {result['error']}")
const apiKey = 'YOUR_API_KEY';
const url = 'https://ttsninja.com/api/v1/tts/generate';
const data = {
text: 'Hello, world! This is a test.',
voice: 'af_heart',
speed: 1.0
};
fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
if (result.success) {
console.log('Audio URL:', result.data.audio_url);
console.log('Credits remaining:', result.credits_remaining);
} else {
console.error('Error:', result.error);
}
});
{
"success": true,
"data": {
"audio_url": "https://ttsninja.com/audio/api_abc123.mp3",
"file_path": "/audio/api_abc123.mp3",
"file_size": 24576,
"characters_count": 28,
"credits_used": 28,
"voice": "af_heart",
"generation_id": 123
},
"credits_remaining": 9972
}
| Status Code | Error | Description |
|---|---|---|
400 |
Bad Request | Invalid parameters (e.g., missing text, text too long) |
401 |
Unauthorized | Invalid or missing API key |
402 |
Payment Required | Insufficient credits |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server error during generation |
Retrieve your account details, credits, and usage statistics. It's like checking your bank account, but way more fun!
curl -X GET https://ttsninja.com/api/v1/account \ -H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"data": {
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"credits": 10000,
"member_since": "2024-01-01 10:00:00"
},
"subscription": {
"plan": "Pro",
"has_api_access": true,
"expires_at": "2024-12-31 23:59:59"
},
"usage": {
"total_api_requests": 150,
"total_characters": 25000,
"total_credits_used": 25000
}
}
}
voice_clone_credits,
not regular TTS credits. Currently only English language is supported.
Get a list of your cloned voices that are ready for use. Only voices with "ready" status are returned.
curl -X GET https://ttsninja.com/api/v1/voices \ -H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"data": {
"voices": [
{
"id": 1,
"name": "My Custom Voice",
"description": "A warm, friendly voice",
"language": "English",
"usage_count": 15,
"created_at": "2024-01-15 14:30:00"
},
{
"id": 2,
"name": "Narrator Voice",
"description": "Deep, professional narrator",
"language": "English",
"usage_count": 42,
"created_at": "2024-01-10 09:15:00"
}
],
"total": 2
}
}
Generate speech using one of your cloned voices. Like magic, but with your own custom voice!
| Parameter | Type | Required | Description |
|---|---|---|---|
text |
string | Required | The text to convert to speech (max 5000 characters) |
voice_id |
integer | Required | Your cloned voice ID from /api/v1/voices |
exaggeration |
float | Optional | Voice exaggeration (0.0 - 1.0, default: 0.5) |
temperature |
float | Optional | Generation temperature (0.0 - 1.0, default: 0.8) |
cfg |
float | Optional | CFG scale (0.0 - 1.0, default: 0.5) |
curl -X POST https://ttsninja.com/api/v1/voice-clone/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Hello! This is my cloned voice speaking.",
"voice_id": 1,
"exaggeration": 0.5,
"temperature": 0.8
}'
<?php
$apiKey = 'YOUR_API_KEY';
$url = 'https://ttsninja.com/api/v1/voice-clone/generate';
$data = [
'text' => 'Hello! This is my cloned voice speaking.',
'voice_id' => 1,
'exaggeration' => 0.5,
'temperature' => 0.8
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
if ($result['success']) {
echo 'Audio URL: ' . $result['data']['audio_url'];
echo 'Credits remaining: ' . $result['credits_remaining'];
} else {
echo 'Error: ' . $result['error'];
}
?>
import requests
api_key = 'YOUR_API_KEY'
url = 'https://ttsninja.com/api/v1/voice-clone/generate'
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
data = {
'text': 'Hello! This is my cloned voice speaking.',
'voice_id': 1,
'exaggeration': 0.5,
'temperature': 0.8
}
response = requests.post(url, json=data, headers=headers)
result = response.json()
if result['success']:
print(f"Audio URL: {result['data']['audio_url']}")
print(f"Voice used: {result['data']['voice_name']}")
print(f"Credits remaining: {result['credits_remaining']}")
else:
print(f"Error: {result['error']}")
const apiKey = 'YOUR_API_KEY';
const url = 'https://ttsninja.com/api/v1/voice-clone/generate';
const data = {
text: 'Hello! This is my cloned voice speaking.',
voice_id: 1,
exaggeration: 0.5,
temperature: 0.8
};
fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
if (result.success) {
console.log('Audio URL:', result.data.audio_url);
console.log('Voice used:', result.data.voice_name);
console.log('Credits remaining:', result.credits_remaining);
} else {
console.error('Error:', result.error);
}
});
{
"success": true,
"data": {
"audio_url": "https://ttsninja.com/storage/voice-clone/generations/api_clone_1_abc123.mp3",
"file_path": "/storage/voice-clone/generations/api_clone_1_abc123.mp3",
"file_size": 45678,
"characters_count": 42,
"credits_used": 42,
"voice_id": 1,
"voice_name": "My Custom Voice"
},
"credits_remaining": 9958
}
| Status Code | Error | Description |
|---|---|---|
400 |
Bad Request | Invalid parameters (e.g., missing text or voice_id) |
401 |
Unauthorized | Invalid or missing API key |
402 |
Payment Required | Insufficient voice clone credits |
403 |
Forbidden | Plan does not include voice clone access |
404 |
Not Found | Voice ID not found or not ready |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server error during generation |
Choose from 54 premium voices across 9 languages. Each voice has been carefully selected for quality and expressiveness.
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
af_heart |
Heart | Female | a |
af_alloy |
Alloy | Female | a |
af_aoede |
Aoede | Female | a |
af_bella |
Bella | Female | a |
af_jessica |
Jessica | Female | a |
af_kore |
Kore | Female | a |
af_nicole |
Nicole | Female | a |
af_nova |
Nova | Female | a |
af_river |
River | Female | a |
af_sarah |
Sarah | Female | a |
af_sky |
Sky | Female | a |
am_adam |
Adam | Male | a |
am_echo |
Echo | Male | a |
am_eric |
Eric | Male | a |
am_fenrir |
Fenrir | Male | a |
am_liam |
Liam | Male | a |
am_michael |
Michael | Male | a |
am_onyx |
Onyx | Male | a |
am_puck |
Puck | Male | a |
am_santa |
Santa | Male | a |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
bf_alice |
Alice | Female | b |
bf_emma |
Emma | Female | b |
bf_isabella |
Isabella | Female | b |
bf_lily |
Lily | Female | b |
bm_daniel |
Daniel | Male | b |
bm_fable |
Fable | Male | b |
bm_george |
George | Male | b |
bm_lewis |
Lewis | Male | b |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
jf_alpha |
Alpha | Female | j |
jf_gongitsune |
Gongitsune | Female | j |
jf_nezumi |
Nezumi | Female | j |
jf_tebukuro |
Tebukuro | Female | j |
jm_kumo |
Kumo | Male | j |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
zf_xiaobei |
Xiaobei | Female | z |
zf_xiaoni |
Xiaoni | Female | z |
zf_xiaoxiao |
Xiaoxiao | Female | z |
zf_xiaoyi |
Xiaoyi | Female | z |
zm_yunjian |
Yunjian | Male | z |
zm_yunxi |
Yunxi | Male | z |
zm_yunxia |
Yunxia | Male | z |
zm_yunyang |
Yunyang | Male | z |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
ef_dora |
Dora | Female | e |
em_alex |
Alex | Male | e |
em_santa |
Santa | Male | e |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
ff_siwis |
Siwis | Female | f |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
hf_alpha |
Alpha | Female | h |
hf_beta |
Beta | Female | h |
hm_omega |
Omega | Male | h |
hm_psi |
Psi | Male | h |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
if_sara |
Sara | Female | i |
im_nicola |
Nicola | Male | i |
| Voice ID | Display Name | Gender | Language Code |
|---|---|---|---|
pf_dora |
Dora | Female | p |
pm_alex |
Alex | Male | p |
pm_santa |
Santa | Male | p |
success field in responses
Need help? We're here for you! (Well, our support team is. The API itself is pretty shy.)