AI narration, one POST away.
A plain REST text-to-speech endpoint — 51 voices, including 13 multilingual OpenAI voices, MP3 out. Pay per character from your plan's credit balance, with no separate API subscription.
Quick start
- Create an account and pick a plan (from $4/month — every plan includes monthly credits).
- Create an API key on your dashboard. It starts with
ksk_live_. - Make a request — POST your text, get an MP3 back.
curl https://vidsly.ai/api/v1/tts \
-H "Authorization: Bearer ksk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Three numbers came out this morning, and every one of them moved the market.",
"voice": "azure-aria",
"speed": "normal"
}' \
--output story.mp3Try it
Hear any voice before you integrate. This uses your account's character allowance — no API key needed here.
Voice sample
76/300"voice": "azure-aria"Request reference
POST/api/v1/tts
Send a JSON body with a Bearer API key. The default response is audio/mpeg, with X-Characters and X-Credits-Charged headers.
| Name | Type | Required | Description |
|---|---|---|---|
| textstring · required | string | Required | Up to 1,000,000 characters per request. Up to ~20,000 returns audio directly; longer texts return 202 + a jobId to poll for the MP3 URL. |
| voicestring · optional | string | Optional | Voice id. Default azure-aria. See Voices or GET /api/v1/voices. |
| speedstring · optional | string | Optional | slow | normal | gentle. Default normal. |
| formatstring · optional | string | Optional | mp3 (binary, default) or json (base64 in audio, plus characters and credits_charged). |
Long texts
Above ~20,000 characters the request returns 202 with a jobId. Poll it until status is completed and read audioUrl.
curl "https://vidsly.ai/api/v1/tts?jobId=JOB_ID" \
-H "Authorization: Bearer ksk_live_YOUR_KEY"Errors
Errors are JSON: { "error": { "code", "message" } }. You are never charged for a failed request.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_requestThe body isn't JSON, or text is missing. | The body isn't JSON, or text is missing. |
| 400 | text_too_longtext is over 1,000,000 characters. | text is over 1,000,000 characters. |
| 400 | invalid_voiceUnknown voice id — GET /api/v1/voices lists them. | Unknown voice id — GET /api/v1/voices lists them. |
| 400 | invalid_speedspeed isn't slow, normal or gentle. | speed isn't slow, normal or gentle. |
| 400 | content_rejectedThe text falls outside the content policy (see Content safety). | The text falls outside the content policy (see Content safety). |
| 401 | unauthorizedMissing or invalid API key. | Missing or invalid API key. |
| 402 | insufficient_creditsNot enough credits in your balance for this request. | Not enough credits in your balance for this request. |
| 402 | key_cap_exceededThe request would pass this key's monthly character cap. | The request would pass this key's monthly character cap. |
| 404 | not_foundUnknown jobId when polling a long job. | Unknown jobId when polling a long job. |
| 429 | rate_limitedToo many requests — wait a minute and retry. | Too many requests — wait a minute and retry. |
| 502 | synthesis_failedSpeech synthesis failed. Retry. | Speech synthesis failed. Retry. |
| 502 | unavailableThe long-text narration service couldn't be reached. Retry. | The long-text narration service couldn't be reached. Retry. |
| 503 | moderation_unavailableContent screening is briefly down, so the request fails closed. Retry. | Content screening is briefly down, so the request fails closed. Retry. |
| 503 | unavailableLong-text narration is briefly unavailable. Retry. | Long-text narration is briefly unavailable. Retry. |
Voices (51)
Pass the id as voice. Tap an id to copy it, or fetch the list from GET /api/v1/voices.
OpenAI Voices (13)
- Alloy · Neutral
- Ash · Confident
- Ballad · Expressive
- Coral · Bright
- Echo · Calm
- Fable · Warm
- Onyx · Deep
- Nova · Energetic
- Sage · Thoughtful
- Shimmer · Light
- Verse · Dynamic
- Marin · Smooth
- Cedar · Resonant
Storytelling Voices (12)
- Aria · English (US)
- Jenny · English (US)
- Michelle · English (US)
- Monica · English (US)
- Sara · English (US)
- Guy · English (US)
- Davis · English (US)
- Tony · English (US)
- Freya · English (AU)
- William · English (AU)
- Neerja · English (IN)
- Emily · English (IE)
Narration Voices (10)
- Calm Guide · English (US)
- Clear Explainer · English (US)
- Sunny Friend · English (US)
- Soft Whisper · English (US)
- Lively · English (US)
- Friendly Host · English (US)
- Steady Narrator · English (US)
- Mellow · English (US)
- Gentle Giant · English (US)
- Seasoned Narrator · English (US)
Language Voices (16)
- Dalia · Spanish (Mexico)
- Jorge · Spanish (Mexico)
- Elena · Spanish (Spain)
- Denise · French
- Henri · French
- Vivienne · French
- Katja · German
- Konrad · German
- Amala · German
- Francisca · Portuguese (Brazil)
- Antonio · Portuguese (Brazil)
- Thalita · Portuguese (Brazil)
- Isabella · Italian
- Giuseppe · Italian
- Sun Hi · Korean
- InJoon · Korean
Storytelling Voices (12)
- Aria · English (US)
- Jenny · English (US)
- Michelle · English (US)
- Monica · English (US)
- Sara · English (US)
- Guy · English (US)
- Davis · English (US)
- Tony · English (US)
- Freya · English (AU)
- William · English (AU)
- Neerja · English (IN)
- Emily · English (IE)
Narration Voices (10)
- Calm Guide · English (US)
- Clear Explainer · English (US)
- Sunny Friend · English (US)
- Soft Whisper · English (US)
- Lively · English (US)
- Friendly Host · English (US)
- Steady Narrator · English (US)
- Mellow · English (US)
- Gentle Giant · English (US)
- Seasoned Narrator · English (US)
Language Voices (16)
- Dalia · Spanish (Mexico)
- Jorge · Spanish (Mexico)
- Elena · Spanish (Spain)
- Denise · French
- Henri · French
- Vivienne · French
- Katja · German
- Konrad · German
- Amala · German
- Francisca · Portuguese (Brazil)
- Antonio · Portuguese (Brazil)
- Thalita · Portuguese (Brazil)
- Isabella · Italian
- Giuseppe · Italian
- Sun Hi · Korean
- InJoon · Korean
Pricing
1 credit per 10 characters (minimum 1 credit per request), from the same credit balance as the rest of Vidsly. Every plan includes monthly credits — from 5,000 on Basic ($4/month) up to 200,000 on Studio — so roughly $0.045–0.08 per 1,000 characters. Unused credits bank for 90 days.
API billing
Credits- Per 1,000 characters
- $0.045–0.08, depending on plan
- Separate API subscription
- None — every plan's credits cover it
- Max characters per request
- 1,000,000 (long jobs return a
jobIdto poll)
Content safety
Every request is screened by an AI moderation layer before synthesis. Text that falls outside our content policy is rejected (HTTP 400 content_rejected, no charge): sexual content, hate speech, threats against real people, instructions for violent wrongdoing, and graphic gore. Reporting on a difficult subject is fine — depicting it explicitly is not, so true crime, war, hard news and politics all pass. If the moderation provider is unreachable the request fails closed with a 503 rather than being synthesised unchecked.
Use the same key from inside Claude
Add the MCP server to Claude Code or Claude Desktop and ask in plain words — the MP3 or a watch link comes back in the chat.
create_audio_story— narrates a script to a voiceover MP3create_talking_storybook— renders a presenter videoget_storybook_status— checks a render and returns the watch linklist_characters— lists the presenter characters
Questions? Contact us — we reply within 24 hours.