Voiceover API — Text-to-Speech
The Voiceover API turns text into natural, studio-quality speech over a simple REST API — send text, pick a language and voice, and receive a ready-to-use audio file URL.
Base URL: https://tts-api.sikasio.com
The API is asynchronous: POST /v1/speak returns a job id immediately
(202), and you poll the job until the audio is ready. For short clips,
add ?wait=true to block until it's done and get the finished audio back in a single call.
Quick facts
- Base URL
https://tts-api.sikasio.com- Endpoint
POST /v1/speak- Auth
X-API-Keyheader — keys issued on request (get one)- Input
- Text, up to 5,000 characters · English & Arabic
- Output
- Hosted
WAVorMP3URL + measureddurationSec - Provider
- Sikasio · support@sikasio.com
Authentication
Every /v1 request must include your API key in the X-API-Key header:
X-API-Key: ttk_live_YOUR_KEY
An Authorization: Bearer ttk_live_YOUR_KEY header works as an alternative if that's a
better fit for your HTTP client. Keep the key server-side — never expose it in a browser or mobile app.
Missing or unrecognized keys return 401 with code invalid_key. Keys are
issued on request rather than self-serve signup — see Get a key.
Rate limits
Each API key has its own requests-per-minute limit and a daily cap.
Exceeding either returns 429 rate_limited. Only POST /v1/speak counts toward
these limits; reading jobs, voices, and models does not.
| Endpoint | Counts toward your limit? |
|---|---|
POST /v1/speak | Yes — one unit per created job. |
GET /v1/jobs/:id, /v1/voices, /v1/models | No quota cost (subject to a basic per-IP floor). |
Jobs run with bounded concurrency, so a burst may briefly queue rather than fail. If the queue is
full you get 503 busy with a Retry-After header — retry after a few seconds.
A per-IP ceiling across all routes returns 429 ip_rate_limited.
Quick start
One call — block for the finished audio (?wait=true)
curl -X POST "https://tts-api.sikasio.com/v1/speak?wait=true" \
-H "X-API-Key: ttk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Your brand, brought to life.","language":"en","gender":"female"}'
Response:
{
"id": "c8db555a-…",
"status": "done",
"audio": {
"url": "https://tts-api.sikasio.com/files/c8db555a-….wav",
"durationSec": 4,
"format": "wav"
}
}
For longer text or batch jobs, omit wait to get a job id immediately
(202) and poll it.
Create speech
Synthesizes speech from text. Returns 202 { id, status } immediately (async). Add
?wait=true to block until the audio is ready (up to 120 s) and receive the finished job:
200 when done, 502 if synthesis failed, 202 if it's still running
at the timeout.
Body parameters
| Field | Type | Default | Description |
|---|---|---|---|
text required | string | — | The text to speak. 1–5,000 characters. |
language optional | string | en | Spoken language: en (English) or ar (Arabic). |
gender optional | string | female | Voice gender: male or female. |
voice optional | string | — | A named voice: aria, nova, sami, or omar. Overrides gender. See Voices. |
format optional | string | wav | Audio format: wav (24 kHz PCM) or mp3. |
model optional | string | standard | Quality tier: standard (fast) or premium (highest quality). See Models. |
style optional | string | ad tone | Delivery direction, e.g. "warm, upbeat commercial read" (max 500 chars). Defaults to a friendly advertising style. |
rate optional | number | 1.0 | Speaking rate, 0.25–2.0. Lower is slower. |
Query
| Param | Description |
|---|---|
wait | Set true to block for the result (up to 120 s) and return the settled job instead of 202. |
Example (Arabic, MP3)
curl -X POST "https://tts-api.sikasio.com/v1/speak" \
-H "X-API-Key: ttk_live_YOUR_KEY" -H "Content-Type: application/json" \
-d '{"text":"ابدأ رحلتك اليوم","language":"ar","gender":"male","format":"mp3"}'
→ 202 { "id": "7d09…", "status": "queued" }
Poll a job
Returns the current state of a job. A key can only read jobs it created; unknown or foreign ids
return 404 not_found. Recommended polling: every 1–2 s until status is
done or failed.
| status | meaning |
|---|---|
queued | Accepted, waiting for a worker. |
running | Synthesizing. |
done | Finished — audio is present. |
failed | Could not synthesize — see error. |
Response (done)
{
"id": "7d09…",
"status": "done",
"audio": { "url": "https://…/files/7d09….mp3", "durationSec": 4.7, "format": "mp3" }
}
Voices
Lists the available (language, gender) combinations plus the hand-picked named voices you
can select with the voice parameter.
Language & gender
| language | gender | tone |
|---|---|---|
English (en) | female · male | warm |
Arabic (ar) | female · male | warm |
Named voices
| voice | label | gender | tone |
|---|---|---|---|
aria | Aria | female | conversational |
nova | Nova | female | lively |
sami | Sami | male | friendly |
omar | Omar | male | confident |
Quality tiers
Choose a tier with the model parameter on /v1/speak.
| model | label | notes |
|---|---|---|
standard default | Standard | Fast, natural delivery. |
premium | Premium | Highest quality, more expressive. |
Fetch the audio
On success a job returns audio.url, a public link served from /files/<name>
with an unguessable filename. Download it, or use it directly in a video/render pipeline.
Audio & retention
- WAV
- Linear PCM, mono, 24 kHz, 16-bit — with a click-free fade-in and end padding.
- MP3
- Compressed, smaller download.
durationSec- Measured length in seconds (rounded to 0.1) — useful for timing/sync.
- Caching
Cache-Control: public, max-age=604800, immutable- Retention
- Files are pruned after 7 days. Persist anything you need to keep.
Errors
All errors are JSON with a stable machine-readable code:
{ "error": { "code": "…", "message": "…" } }
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Missing/invalid field (e.g. empty text, bad language, out-of-range rate). |
| 400 | bad_json | Request body is not valid JSON. |
| 401 | invalid_key | Missing or unrecognized API key. |
| 404 | not_found | Job id doesn't exist or isn't yours; unknown endpoint. |
| 413 | too_large | Request body exceeds the size limit. |
| 429 | rate_limited | Per-key rate or daily cap exceeded — retry after the window. |
| 429 | ip_rate_limited | Per-IP request ceiling hit, across all routes — see Retry-After. |
| 502 | failed | Synthesis failed (returned with ?wait=true). |
| 503 | busy | Queue is full — honor Retry-After and retry. |
FAQ
What is the Voiceover API?
The Voiceover API is a developer REST API that turns text into natural, studio-quality speech.
You send text to POST https://tts-api.sikasio.com/v1/speak with an
X-API-Key header and get back a hosted audio file URL (WAV or MP3) plus a measured
durationSec. It's built by Sikasio.
How do I convert text to speech with an API?
POST your text to /v1/speak with your key in the X-API-Key header. Add
?wait=true to block until the audio is ready and get the finished job in one call:
curl -X POST "https://tts-api.sikasio.com/v1/speak?wait=true" \
-H "X-API-Key: ttk_live_YOUR_KEY" -H "Content-Type: application/json" \
-d '{"text":"Your brand, brought to life.","language":"en","gender":"female"}'
Which languages and voices are available?
English (en) and Arabic (ar), each with male and female voices. You can
also pick a named voice with the voice parameter:
| voice | gender | tone |
|---|---|---|
| Aria | female | conversational |
| Nova | female | lively |
| Sami | male | friendly |
| Omar | male | confident |
What audio formats do I get?
| WAV | Linear PCM, mono, 24 kHz, 16-bit (default) |
| MP3 | Compressed, smaller download (format=mp3) |
Every finished job also reports durationSec, the measured length in seconds, for
timing and sync.
How long are audio files kept?
Audio is served from /files/ with immutable caching and is pruned after
7 days. Download anything you need to keep.
How do I get an API key?
Keys are issued on request rather than self-serve signup. Email support@sikasio.com and we'll set you up with a key and the rate limits you need.
Get a key
Keys are issued on request. Tell us your use case and expected volume and we'll provision a key with suitable per-minute and daily limits.
Questions? support@sikasio.com