The VisionStory Text-to-Speech API converts text into natural MP3 audio with any public or cloned voice. The request is synchronous: a successful response returns the generated audio bytes directly.
Beta. Any API key backed by an active Pro plan or above can call this endpoint. No separate capability allowlist is required.
Text-to-speech API endpoint
| Method | Path | What it does |
|---|---|---|
POST | /api/v1/tts | Synthesize speech from text; returns MP3 audio |
Generate MP3 speech from text
Send text and a voice_id from GET /api/v1/voices. Add an optional BCP 47 locale, such as en-GB or zh-TW, to steer pronunciation and accent for multilingual voices. Locale handling is best-effort per speech engine; omit it to use the voice's native locale.
curl -s -X POST -H "X-API-Key: $VISIONSTORY_API_KEY" -H "Content-Type: application/json" -d '{"text": "Hello from VisionStory.", "voice_id": "YOUR_VOICE_ID", "locale": "en-GB"}' https://openapi.visionstory.ai/api/v1/tts --output speech.mp3
The 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": "YOUR_VOICE_ID", "locale": "en-GB"},
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"))
Control speech rate
The optional speech_rate accepts slow, normal, or fast. Omit it or send null to use normal speed. The setting works with public and cloned voices, but the actual duration change depends on the voice; read X-Audio-Duration-Sec rather than assuming a fixed duration. Speed changes preserve pitch, and billing is unchanged.
from visionstory import VisionStoryClient
from pathlib import Path
speech = VisionStoryClient.from_env().create_speech(
text="Hello from VisionStory.", voice_id="YOUR_VOICE_ID",
locale="en-GB", speech_rate="slow",
)
Path("speech.mp3").write_bytes(speech["audio"])
visionstory tts --text "Hello from VisionStory." --voice-id YOUR_VOICE_ID --speech-rate slow --output speech.mp3
Local and remote MCP expose the same optional speech_rate on create_speech. REST callers put it alongside text, voice_id, and locale in the JSON body. Existing calls that omit it keep working.
Billing, limits, and storage
- 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. - Concurrency: synchronous generation is capped at a few concurrent requests per key during beta; excess requests are rejected rather than queued.
Related VisionStory API guides
- Voices — pick or clone the
voice_idto speak with. - Audio Transcription and Alignment — align generated speech to exact word timestamps for subtitles.
- API reference — full request schema and error codes.