Text to Speech
Turn text into natural-sounding speech with any public or cloned voice. The endpoint is synchronous — the response body is the MP3 audio.
Beta. This endpoint is in beta and may change. Available to any account with an active paid subscription — no separate allowlisting.
Endpoint
| Method | Path | What it does |
|---|---|---|
POST |
/api/v1/tts |
Synthesize speech from text; returns MP3 audio |
Synthesize speech
Send text and a voice_id (from GET /api/v1/voices — a public or your own cloned voice). The service automatically picks the best synthesis strategy for the voice and the text language. Two optional knobs: locale (BCP 47, e.g. en-GB / zh-TW) steers pronunciation on multilingual voices, and speech_rate (slow / normal / fast) sets the relative pace — the same vocabulary as text_script.speech_rate when generating a talking video.
curl -s -X POST -H "X-API-Key: $VISIONSTORY_API_KEY" -H "Content-Type: application/json" -d '{"text": "Hello from VisionStory.", "voice_id": "Alice"}' https://openapi.visionstory.ai/api/v1/tts --output speech.mp3The response body is the raw MP3 (audio/mpeg, 44.1 kHz). Usage and billing come back in response headers, not the body:
| Header | Meaning |
|---|---|
X-Audio-Duration-Sec |
Length of the generated audio, in seconds |
X-Usage-Characters |
Characters billed |
X-Cost-Credit |
Credits charged for this call |
import requests, os
resp = requests.post(
"https://openapi.visionstory.ai/api/v1/tts",
headers={"X-API-Key": os.environ["VISIONSTORY_API_KEY"]},
json={"text": "Hello from VisionStory.", "voice_id": "Alice"},
timeout=240,
)
resp.raise_for_status()
with open("speech.mp3", "wb") as f:
f.write(resp.content)
print("credits charged:", resp.headers.get("X-Cost-Credit"))Notes
- Synchronous & not stored. The audio is returned inline and is not saved on our side — persist the bytes yourself; a repeat call regenerates and bills again.
- Billing: 2 credits per 1,000 characters (rounded up), charged only on success. There is no free allowance.
- Character limit: long text is supported up to a per-request cap; exceeding it returns
400. - Pace:
speech_rateis applied by the voice engine where it supports pacing natively, otherwise by a ~10% pitch-preserving time-stretch, so every voice honours it — but the exact duration change varies by voice. ReadX-Audio-Duration-Secrather than assuming a fixed ratio; for tight timing, fine-tune playback on your side. - Concurrency: synchronous generation is capped at a few concurrent requests per key during beta; excess requests are rejected rather than queued.
Next steps
- Voices — pick or clone the
voice_idto speak with. - API reference — full request schema and error codes.