VocifyVOICE API
Voice API · v1

Natural voices,
one simple key.

Turn text into natural speech from your apps, bots and AI agents. Send text, get back a studio-quality MP3 with matching subtitles. One request, any programming language.

320+natural voices
75+languages
$5 = 2Mtokens
BASE URL
Works with Claude, ChatGPT & Gemini

Let your AI assistant make the voices

Copy the full API guide (with your key) and paste it into any AI chat. It will understand the API and can write the code or call it for you. Agents can also read it directly from the links below.

Paste it into Claude or ChatGPT, then ask for what you need.

Quick start

You can make your first request in under a minute.

1Get your key

Buy tokens ($5 = 2M) or get one from your admin. It starts with sk_.

2Pick a voice

Browse the Voice Library or call GET /api/v1/voices.

3Send text

POST to /api/v1/tts and save the MP3 you get back.

curl -X POST {{BASE}}/api/v1/tts \
  -H "Authorization: Bearer {{KEY}}" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello class, welcome to the lesson.", "voice": "{{V:default}}"}' \
  --output speech.mp3

Authentication

Send your key in the Authorization header as a bearer token. The X-API-Key header works too.

Authorization: Bearer {{KEY}}
Keep your key private. Don't paste it into public code on GitHub or in a website's front end that others can view. If it leaks, contact support to get a new one.

Text to speech

Converts text to speech. Long text is split and voiced in parallel automatically, so even a full chapter comes back quickly.

POST/api/v1/ttsreturns audio/mpeg or JSON
FieldDescription
textrequiredstringThe words to speak. Supports [pause 2s] tags.
voicestringA voice id such as {{V:urdu_female}}. Defaults to {{V:default}}.
speednumber · 0.5–2.0Playback speed multiplier. 1.0 is normal. You can send rate as a percent (-50 to 100) instead.
pitchnumber · -50–50Pitch shift in Hz. Negative is deeper.
volumenumber · -100–100Volume change in percent.
emotionstring"auto" gives every sentence its own feeling from its meaning, or set one emotion such as "happy". See Emotions & styles.
stylestringSpeaking style, e.g. "storytelling", "news", "cinematic".
intensitynumber · 0–2How strong the emotion is. 1 is normal.
format"mp3" | "json"mp3 (default) returns the audio bytes directly. json returns links to the MP3 and SRT files plus timed subtitle cues.

MP3 response headers

X-Audio-DurationLength of the audio in seconds.
X-CharactersTokens used by this request (1 token = 1 character).
X-Tokens-RemainingTokens left on your key, or unlimited.
X-Audio-IdUse it to fetch the subtitles: GET /files/<id>.srt.

JSON response

{
  "id": "q1Xb3mXr0P2kZ8aB",
  "audio_url": "{{BASE}}/files/q1Xb3mXr0P2kZ8aB.mp3",
  "srt_url": "{{BASE}}/files/q1Xb3mXr0P2kZ8aB.srt",
  "duration": 6.74,
  "characters": 68,
  "voice": "{{V:male}}",
  "cues": [[0.05, 1.21, "Hello students."], [2.93, 5.32, "This is a test."]],
  "quota": { "tokens": 1999932, "unlimited": false, "used_today": 68 }
}

Files made with your key are kept in your library for 7 days: list them again with GET /api/v1/library (same Authorization header) and download any audio_url. Delete one with POST /api/v1/library/ID/delete.

Emotions & styles

Add emotion and/or style to any request (text, dialogue or SRT). With "emotion": "auto" each sentence is read with the feeling that fits its words and punctuation, and the mood fades naturally between sentences instead of staying flat.

emotionauto, neutral, happy, sad, angry, excited, fearful, suspenseful, curious, surprised, shocked, confident, empathetic, sarcastic, romantic, hopeful, frustrated, nervous, calm, soothing, mysterious, inspirational
stylenatural, conversational, cinematic, documentary, storytelling, audiobook, podcast, news, motivational, comedic, whispering, shouting, asmr
intensity0 to 2, default 1.
dramatic_pausesDefault true: longer pauses at ... and dashes.
pitch_variationDefault true: small pitch movement between sentences, so long reads don't sound robotic.

Tags inside the text

Put a tag before a sentence to control it. It lasts until the next tag or the end of the paragraph.

  • Emotion: [happy], [sad], [angry], [mysterious]… (any emotion above), [neutral] to reset.
  • Delivery: [whisper], [shout].
  • Sounds: [laugh], [chuckle], [sigh], [gasp], [breath], [cry]. These are short spoken cues ("Haha!", "Hmm…", "Oh!") or pauses, not recorded laughter or crying.
  • Emphasis: wrap a word in **double stars** to stress it.
  • Pause: [pause 2s] or [pause 500ms].
{
  "text": "It was a quiet night... Suddenly, the door creaked open! [gasp] Who is there? [whisper] Don't make a sound.",
  "voice": "{{V:male}}",
  "style": "storytelling",
  "emotion": "auto",
  "intensity": 1.2
}

The full list is also available as JSON at GET /api/v1/expressions.

Voices

Lists every available voice. The list is kept up to date automatically, so new voices appear on their own. No key needed.

GET/api/v1/voicespublic
QueryDescription
langLanguage code, e.g. ur, en, ar.
localeLocale prefix, e.g. en-GB.
genderFemale or Male.
multilingualtrue for voices that can speak many languages.
qFree-text search over name, language and country.
curl "{{BASE}}/api/v1/voices?lang=ur"

Hear any voice instantly with GET /api/v1/voices/<id>/preview. It returns a short MP3 sample.

Dialogue

Create a conversation with a different voice for every line. Great for language-learning role plays, podcasts and stories.

POST/api/v1/dialogue
linesrequiredarrayA list of {"voice": "...", "text": "..."} objects, in order.
gapnumberSeconds of silence between lines (default 0.35).
speed, pitch, volume, formatSame as text to speech.
import requests

lines = [
    {"voice": "{{V:urdu_male}}", "text": "السلام علیکم! آج ہم کیا پڑھیں گے؟"},
    {"voice": "{{V:urdu_female}}", "text": "آج ہم سائنس کا سبق پڑھیں گے۔"},
]
res = requests.post("{{BASE}}/api/v1/dialogue",
                    headers={"Authorization": "Bearer {{KEY}}"},
                    json={"lines": lines, "gap": 0.4})
open("dialogue.mp3", "wb").write(res.content)

SRT dubbing

Send a subtitle file and get back one audio track where every line starts exactly at its timestamp. Perfect for dubbing videos into another language.

POST/api/v1/srt
srtrequiredstringThe full contents of an .srt file.
voiceThe voice to use for every line.
auto_fitbooleanDefault true. Speeds up any line that would run into the next one.
speed, pitch, volume, formatSame as text to speech.
import requests

srt = open("video.srt", encoding="utf-8").read()
res = requests.post("{{BASE}}/api/v1/srt",
                    headers={"Authorization": "Bearer {{KEY}}"},
                    json={"srt": srt, "voice": "{{V:hindi_female}}", "auto_fit": True})
open("dub.mp3", "wb").write(res.content)

OpenAI compatible

Already using OpenAI's text-to-speech? Point the official SDK at this server and it just works. Use any voice id from this site, or the OpenAI names alloy, echo, fable, onyx, nova, shimmer, ash, coral, sage.

POST/v1/audio/speechinput · voice · speed
from openai import OpenAI

client = OpenAI(api_key="{{KEY}}", base_url="{{BASE}}/v1")

with client.audio.speech.with_streaming_response.create(
    model="tts-1",
    voice="{{V:urdu_female}}",   # or "nova", "alloy", ...
    input="یہ آواز OpenAI SDK سے بنائی گئی ہے۔",
) as response:
    response.stream_to_file("speech.mp3")

Tokens & balance

1 token = 1 character of text you send. Pause tags, extra spaces, markdown symbols and emoji are not counted. $5 buys 2,000,000 tokens, which never expire. Buy or top up here.

GET/api/v1/me
{
  "kind": "key",
  "name": "Ayesha Khan",
  "quota": {
    "tokens": 1996880, "unlimited": false, "used_today": 3120,
    "max_request_chars": 100000, "expires_at": null
  }
}

Every request needs your API key. Your balance drops only when audio is generated successfully.

Pauses & tips

  • Pauses: add [pause] (1 second), [pause 2s] or [pause 500ms] anywhere in your text.
  • Paragraphs: sentence breaks and new lines already add natural pauses.
  • Most natural voices have ids ending in -multi (for example {{V:default}}, {{V:male}}). They can also read many languages in one script.
  • Urdu & Hindi: use {{V:urdu_female}}, {{V:urdu_male}}, {{V:hindi_female}} or {{V:hindi_male}} for the most natural accent.
  • AI-written scripts: markdown (#, **, bullet points) and emoji are cleaned up automatically, and headings get a natural pause.
  • Big jobs: send up to your per-request limit in one go. The server splits it and voices the pieces in parallel.

Errors

Errors come back as JSON with a stable code you can check in your program:

{ "error": { "code": "insufficient_tokens", "message": "Not enough tokens: this needs 5,200 but the key has 1,040 left." } }
StatusCode & meaning
400empty_text, invalid_voice, invalid_param, invalid_srt, invalid_json: check your request body.
401invalid_key or key_required: the key is missing or wrong.
402insufficient_tokens: top up your key on the pricing page.
403key_disabled or key_expired: contact support.
413text_too_long: split the text into smaller requests.
429quota_exceeded: the key's daily limit is used up. Try again tomorrow or ask the admin.
502tts_failed: a temporary hiccup. Retry after a few seconds.

Playground

Try the API right here. This sends a real request with the key you enter.