DocsExamples

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

Basic Generation
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")
With Idempotency Key
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

Basic Generation
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

Submit Job
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"}'
Check Status
curl https://aitts.theproductivepixel.com/api/v1/tts/JOB_ID \
  -H "Authorization: Bearer tts_YOUR_KEY"
List Voices
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.

MP3 with custom settings
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
    }
)
OGG Opus (smaller file size)
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.

Two Speakers
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}

polly:en-GB-Generative-Briankokoro:en-US-Kokoro-Bellagoogle:en-US-Chirp3HD-Charongoogle:en-US-Gemini-Kore

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

Streaming — 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
Streaming — Explicit Format
# 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_kbps

Python

Streaming — Python
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

Streaming — Node.js
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.

Default text
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"
}'
Minimal SSML
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.

Shares

Create share — cURL
curl -X POST https://aitts.theproductivepixel.com/api/v1/shares \
  -H "Authorization: Bearer tts_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_ids": ["JOB_ID"], "share_mode": "snapshot", "allow_download": true}'
Create share — Python
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}/shares",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"job_ids": ["JOB_ID"], "share_mode": "snapshot"})
share = resp.json()["data"]
print(f"Share URL: {share['url']}")
List shares — Node.js
const API_KEY = "tts_YOUR_KEY";
const APP_ORIGIN = "https://aitts.theproductivepixel.com";
const API_BASE = APP_ORIGIN + "/api/v1";

const res = await fetch(API_BASE + "/shares", {
  headers: { "Authorization": "Bearer " + API_KEY }
});
const { data } = await res.json();
console.log(`${data.shares.length} shares`);
Revoke share
curl -X DELETE https://aitts.theproductivepixel.com/api/v1/shares/SHARE_CODE \
  -H "Authorization: Bearer tts_YOUR_KEY"

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.

generate_speech (async)
{
  "jsonrpc": "2.0", "id": 1,
  "method": "tools/call",
  "params": {
    "name": "generate_speech",
    "arguments": { "text": "Hello!", "voice_id": "google:en-US-Chirp3HD-Charon" }
  }
}
generate_speech (stream + idempotency)
{
  "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"
    }
  }
}
Stream via Python (MCP HTTP)
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": "...", ...}
search_voices
{
  "jsonrpc": "2.0", "id": 3,
  "method": "tools/call",
  "params": { "name": "search_voices", "arguments": { "language": "en-US" } }
}

Tags & Collections

TTS with tags
curl -X POST https://aitts.theproductivepixel.com/api/v1/tts \
  -H "Authorization: Bearer tts_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Tagged", "voice_id": "kokoro:en-US-Kokoro-Bella", "tags": ["podcast"]}'
Create collection
curl -X POST https://aitts.theproductivepixel.com/api/v1/collections \
  -H "Authorization: Bearer tts_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Project"}'
List tags
curl https://aitts.theproductivepixel.com/api/v1/tags \
  -H "Authorization: Bearer tts_YOUR_KEY"

Storage

Get storage usage
curl https://aitts.theproductivepixel.com/api/v1/storage \
  -H "Authorization: Bearer tts_YOUR_KEY"
List storage items
curl "https://aitts.theproductivepixel.com/api/v1/storage/items?limit=20" \
  -H "Authorization: Bearer tts_YOUR_KEY"
Bulk delete
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

List jobs
curl "https://aitts.theproductivepixel.com/api/v1/jobs?limit=10" \
  -H "Authorization: Bearer tts_YOUR_KEY"
Update metadata (tags + collection)
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"}'
Get job text
curl https://aitts.theproductivepixel.com/api/v1/jobs/JOB_ID/text \
  -H "Authorization: Bearer tts_YOUR_KEY"

Pricing Estimate

Estimate cost
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"}'
Python
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

Create access codes
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"}'
Generate QR code (returns data_uri)
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" } }
Export codes (JSON)
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.

Redirect (browsers) — cURL
# 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"
Fresh signed URL in JSON — cURL
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" } }
Fetch signed URL then download — Python
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

Create bookmark (from share code)
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"}'
List bookmarks
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.

Get voice details (curl)
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"
Get voice details (Python)
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-go10 requests / 15 min
Pro100 requests / 15 min
Enterprise1,000 requests / 15 min
Back to Documentation

© 2026 AI TTS Microservice. All rights reserved.