[{"data":1,"prerenderedAt":132},["ShallowReactive",2],{"reference-detail-en-create_speech_api_v1_tts_post":3,"developer-code-tpufuf":130,"developer-code-2ucgch":131},{"tag":4,"sourceTag":5,"tagSlug":6,"method":7,"path":8,"slug":9,"summary":10,"description":11,"operationId":12,"groupOrder":13,"descriptionHtml":14,"parameters":15,"requestBody":23,"responses":55,"security":117,"codeSamples":120},"Text to Speech","Speech","speech","POST","\u002Fapi\u002Fv1\u002Ftts","create-speech","Create Speech","Convert text to speech with VisionStory smart TTS. Pick a voice from GET \u002Fapi\u002Fv1\u002Fvoices (public or\nyour cloned voices). The service automatically selects the best synthesis strategy for the voice\nand the text language. Billing: 2 credits per 1000 characters (rounded up), only charged on success.\n\nSynchronous — the response body is the MP3 audio itself (`audio\u002Fmpeg`). Duration and billing are\nreturned in the `X-Audio-Duration-Sec`, `X-Usage-Characters` and `X-Cost-Credit` headers. The audio\nis not stored on our side, so save the response body; a repeat call regenerates and bills again. Per-key concurrency is limited during beta; requests beyond the limit are rejected, not queued.","create_speech_api_v1_tts_post",70,"\u003Cp>Convert text to speech with VisionStory smart TTS. Pick a voice from GET \u002Fapi\u002Fv1\u002Fvoices (public or your cloned voices). The service automatically selects the best synthesis strategy for the voice and the text language. Billing: 2 credits per 1000 characters (rounded up), only charged on success.\u003C\u002Fp>\u003Cp>Synchronous — the response body is the MP3 audio itself (\u003Ccode>audio\u002Fmpeg\u003C\u002Fcode>). Duration and billing are returned in the \u003Ccode>X-Audio-Duration-Sec\u003C\u002Fcode>, \u003Ccode>X-Usage-Characters\u003C\u002Fcode> and \u003Ccode>X-Cost-Credit\u003C\u002Fcode> headers. The audio is not stored on our side, so save the response body; a repeat call regenerates and bills again. Per-key concurrency is limited during beta; requests beyond the limit are rejected, not queued.\u003C\u002Fp>",[16],{"name":17,"in":18,"required":19,"description":20,"type":21,"example":22},"X-API-Key","header",true,"Your VisionStory API key (`sk-vs-...`), kept server-side. Create or manage keys in [API keys](\u002Fapi-keys) (Pro plan and up).","string","sk-vs-your-api-key",{"required":19,"contentType":24,"schema":25,"example":51},"application\u002Fjson",{"type":26,"description":27,"nullable":28,"properties":29},"CreateSpeechRequest","",false,[30,35,43,47],{"name":31,"required":28,"type":32,"description":33,"nullable":19,"properties":34},"locale","string | null","Optional BCP 47 locale (e.g. `en-GB`, `zh-TW`) steering pronunciation and accent for multilingual voices, applied best-effort per voice engine. Defaults to the voice's native locale.",[],{"name":36,"required":28,"type":32,"description":37,"nullable":19,"enum":38,"properties":42},"speech_rate","Relative speaking pace: `slow` \u002F `normal` \u002F `fast`; defaults to `normal`. Same vocabulary as `text_script.speech_rate` in POST \u002Fapi\u002Fv1\u002Fvideo. Applied by the voice engine where it supports pacing natively, otherwise by a ~10% time-stretch of the audio (pitch preserved); the exact duration change varies by voice, so read `X-Audio-Duration-Sec`.",[39,40,41],"slow","normal","fast",[],{"name":44,"required":19,"type":21,"description":45,"nullable":28,"properties":46},"text","Text to synthesize, up to 3000 characters",[],{"name":48,"required":19,"type":21,"description":49,"nullable":28,"properties":50},"voice_id","Public or cloned voice id, check GET \u002Fapi\u002Fv1\u002Fvoices",[],{"text":52,"voice_id":53,"locale":54,"speech_rate":40},"Welcome to VisionStory.","voice_123456","en-GB",[56,87],{"status":57,"description":58,"contentType":59,"schema":60,"example":63,"headers":64},"200","MP3 audio (44.1kHz). Usage metadata is returned in response headers. The example text is a binary-body placeholder, not playable audio or JSON.","audio\u002Fmpeg",{"type":61,"description":27,"nullable":28,"properties":62},"string · binary",[],"\u003Cbinary MP3 audio bytes; save the response body as speech.mp3>",[65,71,76,82],{"type":66,"description":67,"nullable":28,"example":68,"properties":69,"name":70,"required":28},"number","Actual generated duration in seconds.",1.5,[],"X-Audio-Duration-Sec",{"type":21,"description":72,"nullable":28,"example":73,"properties":74,"name":75,"required":28},"Identifier of the generated audio.","example_audio_id",[],"X-Audio-Id",{"type":77,"description":78,"nullable":28,"example":79,"properties":80,"name":81,"required":28},"integer","Credits charged. This example is illustrative, not a quote.",2,[],"X-Cost-Credit",{"type":77,"description":83,"nullable":28,"example":84,"properties":85,"name":86,"required":28},"Number of characters billed.",22,[],"X-Usage-Characters",{"status":88,"description":89,"contentType":24,"schema":90,"example":113,"headers":116},"default","Error response. All failures share one envelope: an `error` object with a numeric `code`, a human-readable `message`, an optional `details` string, and an optional `hint` giving an actionable next step (useful for AI agents).",{"type":91,"description":27,"nullable":28,"properties":92},"ErrorResponse",[93],{"name":94,"required":19,"type":95,"description":27,"nullable":28,"properties":96},"error","ErrorDetail",[97,101,105,109],{"name":98,"required":19,"type":77,"description":99,"nullable":28,"properties":100},"code","Machine-readable error code. Mirrors the HTTP status for transport-level failures (e.g. 401, 404, 422, 500) and may carry a business-specific code otherwise.",[],{"name":102,"required":28,"type":32,"description":103,"nullable":19,"properties":104},"details","Optional structured detail about the failure, e.g. a JSON string of per-field validation errors on a 422. Absent when there is nothing extra to report.",[],{"name":106,"required":28,"type":32,"description":107,"nullable":19,"properties":108},"hint","Actionable next step for resolving the error, written for both humans and AI agents (e.g. how to fix the request, or where to obtain an API key). May be absent.",[],{"name":110,"required":19,"type":21,"description":111,"nullable":28,"properties":112},"message","Human-readable explanation of what went wrong. Safe to log or surface to end users; not localized.",[],{"error":114},{"code":115,"message":21,"details":21,"hint":21},1,[],[118],{"APIKeyHeader":119},[],[121,124,127],{"lang":122,"source":123},"SDK","from pathlib import Path\nfrom visionstory import VisionStoryClient\n\nclient = VisionStoryClient.from_env()\nspeech = client.create_speech(\n    text=\"Welcome to VisionStory.\",\n    voice_id=\"voice_123456\",\n    locale=\"en-GB\",\n    speech_rate=\"normal\",\n)\nPath(\"speech.mp3\").write_bytes(speech[\"audio\"])\nprint({key: value for key, value in speech.items() if key != \"audio\"})",{"lang":125,"source":126},"REST","from pathlib import Path\nimport os\nimport requests\n\nresponse = requests.post(\n    \"https:\u002F\u002Fopenapi.visionstory.ai\u002Fapi\u002Fv1\u002Ftts\",\n    headers={\"X-API-Key\": os.environ[\"VISIONSTORY_API_KEY\"]},\n    json={\n      \"text\": \"Welcome to VisionStory.\",\n      \"voice_id\": \"voice_123456\",\n      \"locale\": \"en-GB\",\n      \"speech_rate\": \"normal\"\n    },\n)\nresponse.raise_for_status()\nPath(\"response.mp3\").write_bytes(response.content)",{"lang":128,"source":129},"cURL","curl --request POST 'https:\u002F\u002Fopenapi.visionstory.ai\u002Fapi\u002Fv1\u002Ftts' \\\n  --header 'X-API-Key: $VISIONSTORY_API_KEY' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --data '{\n  \"text\": \"Welcome to VisionStory.\",\n  \"voice_id\": \"voice_123456\",\n  \"locale\": \"en-GB\",\n  \"speech_rate\": \"normal\"\n}' \\\n  --output 'response.mp3'","\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#FF7B72\">from\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> pathlib \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> Path\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FF7B72\">from\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> visionstory \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> VisionStoryClient\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E6EDF3\">client \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> VisionStoryClient.from_env()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E6EDF3\">speech \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> client.create_speech(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFA657\">    text\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">\"Welcome to VisionStory.\"\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFA657\">    voice_id\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">\"voice_123456\"\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFA657\">    locale\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">\"en-GB\"\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFA657\">    speech_rate\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">\"normal\"\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E6EDF3\">Path(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">\"speech.mp3\"\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">).write_bytes(speech[\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">\"audio\"\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">({key: value \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">for\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> key, value \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">in\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> speech.items() \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> key \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">!=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> \"audio\"\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">})\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#FF7B72\">HTTP\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">\u002F\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">1.1\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 200\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> OK\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#7EE787\">Content-Type\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> audio\u002Fmpeg\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#7EE787\">X-Audio-Duration-Sec\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 1.5\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#7EE787\">X-Audio-Id\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> example_audio_id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#7EE787\">X-Cost-Credit\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 2\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#7EE787\">X-Usage-Characters\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 22\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E6EDF3\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"color:#7EE787\">binary\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> MP3 audio bytes; save the response body as speech.mp3>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1790231924564]