Code Examples
Ready-to-use examples in multiple languages
Examples below use a mix of currently supported providers. Check Provider Capabilities and GET /api/v1/voices before choosing a voice or modifier combination.
Authentication: The public v1 API and hosted MCP HTTP endpoint accept either an API key or an OAuth access token. The npm stdio package still uses AITTSM_API_KEY for authentication and does not perform browser OAuth.
Python
import requests
import time
from urllib.parse import urljoin
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
def generate_speech(text: str, voice_id: str = "polly:en-GB-Generative-Brian") -> str:
"""Generate speech using a public voice_id."""
response = requests.post(
f"{API_BASE}/tts",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"text": text, "voice_id": voice_id}
)
response.raise_for_status()
job_id = response.json()["data"]["job_id"]
# Poll for completion
while True:
status = requests.get(
f"{API_BASE}/tts/{job_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
).json()["data"]
if status["status"] == "completed":
return status["audio_endpoint"]
if status["status"] == "failed":
raise Exception(status.get("error", {}).get("message"))
time.sleep(1)
audio_endpoint = generate_speech("Hello from Joanna!")
# Download the audio file
download_url = urljoin(APP_ORIGIN, audio_endpoint)
audio = requests.get(download_url,
headers={"Authorization": f"Bearer {API_KEY}"},
allow_redirects=True)
audio.raise_for_status()
with open("output.wav", "wb") as f:
f.write(audio.content)
print("Saved to output.wav")import requests
import uuid
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
def generate_safe(text: str, idempotency_key: str = None):
"""Safe retries with idempotency key."""
response = requests.post(
f"{API_BASE}/tts",
headers={
"Authorization": f"Bearer {API_KEY}",
"Idempotency-Key": idempotency_key or str(uuid.uuid4())
},
json={"text": text, "voice_id": "kokoro:en-US-Kokoro-Bella"}
)
return response.json()["data"]Node.js / TypeScript
const API_KEY = "tts_YOUR_KEY";
const APP_ORIGIN = "https://aitts.theproductivepixel.com";
const API_BASE = APP_ORIGIN + "/api/v1";
async function generateSpeech(
text: string,
voice_id = "polly:en-GB-Generative-Brian"
): Promise<string> {
const res = await fetch(API_BASE + "/tts", {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ text, voice_id })
});
const { data: job } = await res.json();
// Poll for completion
while (true) {
const statusRes = await fetch(API_BASE + "/tts/" + job.job_id, {
headers: { "Authorization": `Bearer ${API_KEY}` }
});
const { data: status } = await statusRes.json();
if (status.status === "completed") return status.audio_endpoint;
if (status.status === "failed") throw new Error(status.error?.message);
await new Promise(r => setTimeout(r, 1000));
}
}
const audioEndpoint = await generateSpeech("Hello from TypeScript!");
// Download the audio file
const audioRes = await fetch(new URL(audioEndpoint, APP_ORIGIN), {
headers: { "Authorization": `Bearer ${API_KEY}` },
redirect: "follow",
});
const buffer = Buffer.from(await audioRes.arrayBuffer());
const fs = await import("fs");
fs.writeFileSync("output.wav", buffer);
console.log("Saved to output.wav");cURL
curl -X POST https://aitts.theproductivepixel.com/api/v1/tts \
-H "Authorization: Bearer tts_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Hello world!", "voice_id": "polly:en-GB-Generative-Brian"}'curl https://aitts.theproductivepixel.com/api/v1/tts/JOB_ID \
-H "Authorization: Bearer tts_YOUR_KEY"curl "https://aitts.theproductivepixel.com/api/v1/voices?model_type=premium" \
-H "Authorization: Bearer tts_YOUR_KEY"Output Formats
Customize audio output with output_format, sample_rate_hertz, and output_bitrate_kbps.
import requests
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
response = requests.post(
f"{API_BASE}/tts",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"text": "High quality MP3 audio output.",
"voice_id": "polly:en-GB-Generative-Brian",
"output_format": "mp3",
"sample_rate_hertz": 24000,
"output_bitrate_kbps": 192
}
)import requests
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
response = requests.post(
f"{API_BASE}/tts",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"text": "Compressed OGG Opus audio.",
"voice_id": "kokoro:en-US-Kokoro-Bella",
"output_format": "ogg_opus",
"sample_rate_hertz": 24000,
"output_bitrate_kbps": 64
}
)Note: Default format is wav. Bitrate (output_bitrate_kbps) availability depends on the selected output format, voice, and delivery mode. See Provider Capabilities for support details.
Multi-Speaker Dialogue
Use two voices from the same provider and language that support multi-speaker mode. See Provider Capabilities and GET /api/v1/voices for supported combinations.
import requests
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
response = requests.post(
f"{API_BASE}/tts",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"text": "Instruction: Be cheerful and friendly.\nSpeaker 1: How are you today?\nSpeaker 2: I'm doing great, thanks for asking!",
"speaker_type": "multi",
"voice_id_speaker_1": "google:en-US-Gemini-Kore",
"voice_id_speaker_2": "google:en-US-Gemini-Puck"
}
)Example Voices
Public voice_id format: provider:{language}-{Family}-{Name}
Use GET /api/v1/voices for the full list.
Browse the full voice library for all available options.
Streaming
Two-step flow: create a streaming job, then open the stream URL. Short-form only.
cURL
# Step 1: Create streaming job
RESPONSE=$(curl -s -X POST https://aitts.theproductivepixel.com/api/v1/tts/stream \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Hello from streaming", "voice_id": "google:en-US-Chirp3HD-Charon"}')
echo $RESPONSE
# {"success":true,"data":{"job_id":"...","stream_url":"...","transport_format":"ogg_opus",...}}
# Step 2: Stream the audio
STREAM_URL=$(echo $RESPONSE | jq -r '.data.stream_url')
curl -o audio.ogg "$STREAM_URL"
# The completed file is also available at audio_endpoint afterward# Request a specific format and sample rate
curl -s -X POST https://aitts.theproductivepixel.com/api/v1/tts/stream \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Hello", "voice_id": "polly:en-US-Neural-Danielle", "output_format": "mp3", "sample_rate_hertz": 24000}'
# Polly manages this stream's bitrate, so this request omits output_bitrate_kbpsPython
import requests
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
# Step 1: Create streaming job
resp = requests.post(f"{API_BASE}/tts/stream",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"text": "Hello from streaming", "voice_id": "polly:en-US-Neural-Danielle"})
data = resp.json()["data"]
print(f"Transport: {data['transport_format']}")
# Step 2: Stream the audio
if "stream_url" in data:
audio = requests.get(data["stream_url"])
with open("audio.ogg", "wb") as f:
f.write(audio.content)
else:
# Completed result returned immediately (repeat request)
print(f"Audio ready at: {data['audio_endpoint']}")Node.js / TypeScript
const APP_ORIGIN = "https://aitts.theproductivepixel.com";
const API_BASE = APP_ORIGIN + "/api/v1";
const resp = await fetch(API_BASE + "/tts/stream", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ text: "Hello from streaming", voice_id: "kokoro:en-US-Kokoro-Bella" }),
});
const { data } = await resp.json();
console.log("Transport:", data.transport_format);
if (data.stream_url) {
const audio = await fetch(data.stream_url);
// audio.body is a ReadableStream of chunked audio
} else {
// Completed result returned immediately
console.log("Audio ready at:", data.audio_endpoint);
}Repeated requests for the same text and voice may return the completed result immediately. See Provider Capabilities for which voices support streaming.
Azure requests
Choose the voice ID shown below for text or caller-authored SSML. The selected voice and SSML language are both English.
curl -X POST https://aitts.theproductivepixel.com/api/v1/tts \
-H "Authorization: Bearer tts_YOUR_KEY" -H "Content-Type: application/json" \
-d '{
"text": "Hello from Azure.",
"voice_id": "azure:en-US-Neural-Aria",
"format": "text"
}'curl -X POST https://aitts.theproductivepixel.com/api/v1/tts \
-H "Authorization: Bearer tts_YOUR_KEY" -H "Content-Type: application/json" \
-d '{
"text": "<speak xmlns=\"http://www.w3.org/2001/10/synthesis\" version=\"1.0\" xml:lang=\"en-US\">Hello from Azure.</speak>",
"format": "ssml",
"voice_id": "azure:en-US-Neural-Aria"
}'For longer input, Azure accepts up to 500,000 original UTF-8 bytes. Short and stream requests accept up to 4,000 bytes.
MCP Tool Calls
Send JSON-RPC messages to POST /api/v1/mcp or use the stdio CLI. See MCP docs for connection setup.
Hosted MCP HTTP accepts either an API key or an OAuth access token in the Authorization: Bearer header. The npm stdio package uses AITTSM_API_KEY and does not perform browser OAuth.
{
"jsonrpc": "2.0", "id": 1,
"method": "tools/call",
"params": {
"name": "generate_speech",
"arguments": { "text": "Hello!", "voice_id": "google:en-US-Chirp3HD-Charon" }
}
}{
"jsonrpc": "2.0", "id": 2,
"method": "tools/call",
"params": {
"name": "generate_speech",
"arguments": {
"text": "Stream this audio.",
"voice_id": "google:en-US-Chirp3HD-Charon",
"delivery_mode": "stream",
"idempotency_key": "unique-key-abc"
}
}
}import requests
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
resp = requests.post(f"{API_BASE}/mcp",
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": "generate_speech", "arguments": {
"text": "Hello from Python!",
"voice_id": "google:en-US-Chirp3HD-Charon",
"delivery_mode": "stream"}}})
result = resp.json()["result"]["content"][0]["text"]
print(result) # {"job_id": "...", "stream_url": "...", ...}{
"jsonrpc": "2.0", "id": 3,
"method": "tools/call",
"params": { "name": "search_voices", "arguments": { "language": "en-US" } }
}Storage
curl https://aitts.theproductivepixel.com/api/v1/storage \
-H "Authorization: Bearer tts_YOUR_KEY"curl "https://aitts.theproductivepixel.com/api/v1/storage/items?limit=20" \
-H "Authorization: Bearer tts_YOUR_KEY"curl -X POST https://aitts.theproductivepixel.com/api/v1/storage/bulk-delete \
-H "Authorization: Bearer tts_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"job_ids": ["JOB_1", "JOB_2"]}'Jobs Management
curl "https://aitts.theproductivepixel.com/api/v1/jobs?limit=10" \
-H "Authorization: Bearer tts_YOUR_KEY"curl -X PATCH https://aitts.theproductivepixel.com/api/v1/jobs/JOB_ID \
-H "Authorization: Bearer tts_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"tags": ["final"], "collection_id": "COLLECTION_ID"}'curl https://aitts.theproductivepixel.com/api/v1/jobs/JOB_ID/text \
-H "Authorization: Bearer tts_YOUR_KEY"Pricing Estimate
curl -X POST https://aitts.theproductivepixel.com/api/v1/pricing/estimate \
-H "Authorization: Bearer tts_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Hello world", "voice_id": "google:en-US-Chirp3HD-Charon"}'import requests
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
resp = requests.post(f"{API_BASE}/pricing/estimate",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"text": "Hello world", "voice_id": "polly:en-GB-Generative-Brian"})
est = resp.json()["data"]
print(f"Cost: {est['estimated_cost']} credits ({est['chars_charged']} chars)")Access Codes & QR
curl -X POST https://aitts.theproductivepixel.com/api/v1/shares/SHARE_CODE/access-codes/bulk \
-H "Authorization: Bearer tts_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"count": 5, "label_prefix": "event"}'curl -X POST https://aitts.theproductivepixel.com/api/v1/shares/SHARE_CODE/qr \
-H "Authorization: Bearer tts_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"format": "png"}'
# Response: { "success": true, "data": { "data_uri": "data:image/png;base64,...", "format": "png" } }curl "https://aitts.theproductivepixel.com/api/v1/shares/SHARE_CODE/access-codes/export" \
-H "Authorization: Bearer tts_YOUR_KEY"
# Response: { "success": true, "data": { "access_codes": [...] } }Audio Retrieval
Two endpoints return the same stored audio. /audio issues a 307 redirect to a fresh signed URL (browsers follow it automatically). /audio-url returns that signed URL in a JSON body — use it from agent runtimes and ChatGPT Actions that cannot follow cross-origin redirects.
# 307 redirect to the signed URL; -L follows it
curl -L -o output.wav \
-H "Authorization: Bearer tts_YOUR_KEY" \
"https://aitts.theproductivepixel.com/api/v1/tts/JOB_ID/audio"curl "https://aitts.theproductivepixel.com/api/v1/tts/JOB_ID/audio-url" \
-H "Authorization: Bearer tts_YOUR_KEY"
# { "success": true, "data": { "audio_url": "https://...", "expires_at": "...",
# "expires_in": 3600, "content_type": "audio/wav", "audio_bytes": 12345,
# "audio_endpoint": "/api/v1/tts/JOB_ID/audio" } }import requests
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
job_id = "JOB_ID"
meta = requests.get(f"{API_BASE}/tts/{job_id}/audio-url",
headers={"Authorization": f"Bearer {API_KEY}"}).json()["data"]
# No redirect to follow — read the URL straight from the JSON body
audio = requests.get(meta["audio_url"])
with open("output.wav", "wb") as f:
f.write(audio.content)Bookmarks
curl -X POST https://aitts.theproductivepixel.com/api/v1/bookmarks \
-H "Authorization: Bearer tts_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"code": "SHARE_CODE"}'curl https://aitts.theproductivepixel.com/api/v1/bookmarks \
-H "Authorization: Bearer tts_YOUR_KEY"Voice Capability Discovery
Get full capabilities for a specific voice — streaming support, formats, limits, speed, and prompt.
curl "https://aitts.theproductivepixel.com/api/v1/voices/kokoro%3Aen-US-Kokoro-Bella" \
-H "Authorization: Bearer tts_YOUR_KEY"
# With model selection (ultra voices only)
curl "https://aitts.theproductivepixel.com/api/v1/voices/google%3Aen-US-Gemini-Kore?model=gemini-2.5-flash-tts" \
-H "Authorization: Bearer tts_YOUR_KEY"import requests
from urllib.parse import quote
API_KEY = "tts_YOUR_KEY"
APP_ORIGIN = "https://aitts.theproductivepixel.com"
API_BASE = f"{APP_ORIGIN}/api/v1"
voice_id = "kokoro:en-US-Kokoro-Bella"
resp = requests.get(
f"{API_BASE}/voices/{quote(voice_id, safe='')}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
caps = resp.json()["data"]["capabilities"]
print(f"Streaming: {caps['supports_streaming']}")
print(f"Max async bytes: {caps['max_text_bytes_async']}")Rate Limits
Generation limits apply per account. Additional anti-abuse protections may also apply.
| Pay-as-you-go | 10 requests / 15 min |
| Pro | 100 requests / 15 min |
| Enterprise | 1,000 requests / 15 min |
© 2026 AI TTS Microservice. All rights reserved.