API

API Integration

Add AI voices to your apps, workflows and automations

A simple REST API for personal projects and businesses. Create keys in your account, send text, get studio-quality audio with subtitles and timings back.

Get an API key https://cotsiasane.com/wp-json/ai-tts/v1

Authentication

Send your key in the Authorization header:

Authorization: Bearer tts_live_YOUR_KEY

Or use the X-API-Key header. Keep keys on your server. Business keys can be limited to your server IPs and websites, and every key can have a monthly credit cap.

Credits & limits

1 credit = up to 200 characters. API calls use the same credits as the studio. Requests per minute depend on your plan; going over returns HTTP 429.

Endpoints

POST/speech
Generate speech (simple or video sync). Returns the audio, SRT / VTT and timeline URLs, or a queued job.
GET/generations/{id}
Status and result of a generation (poll queued jobs here).
GET/generations
Your history — page, per_page (max 100).
DELETE/generations/{id}
Delete a generation and its files.
GET/voices?language=en-GB
Voices available for a language / accent (no key needed).
GET/languages
All languages and regional accents (no key needed).
GET/account
Plan, credits left and this key's monthly usage.

Generate speech — POST /speech

curl -X POST https://cotsiasane.com/wp-json/ai-tts/v1/speech \
  -H "Authorization: Bearer tts_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Welcome to our channel! [pause 1s] Let's get started.",
    "voice": "openai:coral",
    "language": "en-GB",
    "tone": "friendly",
    "speed": 1.05,
    "format": "mp3"
  }'

Parameters

textstringThe script. Add [pause 1s] or [pause 500ms] for pauses.
voicestringVoice id from /voices, e.g. openai:coral, google:en-GB-Neural2-A. Defaults to a good voice for the language.
languagestringLocale with accent, e.g. en-US, en-IN, hi-IN, fr-CA. Default en-US.
tonestringneutral, friendly, cheerful, calm, professional, storytelling, serious, excited, whisper
speednumber0.5 – 2.0 (1 = normal)
pitchnumber-10 – +10 semitones (0 = normal)
instructionsstringOptional free-text direction, e.g. "sound like a radio host".
formatstringmp3 | wav
titlestringOptional title shown in your history.
translatebooleanTranslate the text into the language first.
modestring"sync" for video timelines (with segments or srt / vtt).
segmentsarray[{start, end?, text}] — times in seconds or "hh:mm:ss.mmm".
fitbooleanSpeed lines up to fit their slot (default true).
asyncbooleanReturn immediately with status "queued" (long scripts are queued automatically).
webhook_urlstringCalled with the result when the job finishes (signed with your key's webhook secret).

Response

{
  "id": 1842, "status": "done", "voice": "openai:coral", "language": "en-GB",
  "characters": 64, "credits": 1, "duration": 4.21, "render_ms": 1380,
  "audio_url": "https://…/ai-tts/audio/….mp3",
  "srt_url": "https://…/….srt", "vtt_url": "https://…/….vtt", "timeline_url": "https://…/….json",
  "status_url": "https://cotsiasane.com/wp-json/ai-tts/v1/generations/1842"
}

Video sync

Send timed lines (or a whole SRT / VTT file). Each line starts exactly at its time and is sped up to fit its slot when needed. You get one WAV the length of your timeline plus captions and a per-line report.

curl -X POST https://cotsiasane.com/wp-json/ai-tts/v1/speech \
  -H "Authorization: Bearer tts_live_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{
    "mode": "sync",
    "voice": "openai:onyx",
    "fit": true,
    "segments": [
      { "start": "00:00:01.000", "end": "00:00:04.000", "text": "Every great story starts with a voice." },
      { "start": 5.5, "text": "Let's make yours." }
    ]
  }'

# or send a subtitle file as text:  "srt": "1\n00:00:01,000 --> 00:00:04,000\nHello\n"

Webhooks

Pass webhook_url and we POST the finished generation to it. Check the X-TTS-Signature header with your key's webhook secret (shown next to the key in your account).

// Node / Express: verify the webhook signature
const crypto = require('crypto');
app.post('/tts-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = 'sha256=' + crypto.createHmac('sha256', process.env.TTS_WEBHOOK_SECRET)
                               .update(req.body).digest('hex');
  if (sig !== req.get('X-TTS-Signature')) return res.sendStatus(401);
  const { event, generation } = JSON.parse(req.body);
  // event = generation.completed | generation.failed
  res.sendStatus(200);
});

Errors

400Invalid input (empty text, unknown voice, line too long).
401Missing, invalid or revoked key.
402Not enough credits, no plan, or the key's monthly cap is reached.
403Feature not in your plan, or IP / website not allowed for this key.
413Text longer than your plan allows per clip.
429Too many requests per minute.
502 / 503Voice service busy. Nothing is charged — retry shortly.

Bring Your Content to Life.

Create natural, human-like AI voiceovers for videos, courses, podcasts, IVR and more.

Select your currency