VisionStory Python SDK
Official Python SDK for the VisionStory API — generate AI talking-avatar videos from text or audio.
- Zero dependencies — Python standard library only, Python 3.10+.
- Blocking semantics built in —
generate_video()submits the job and polls until the video is ready: one call in, a finished video out. - Agent-friendly — auth via environment variable, actionable error messages, idempotent retries.
Installation
pip install visionstory
Quick start
Create an API key at visionstory.ai/openapi and export it:
export VISIONSTORY_API_KEY="sk-vs-xxxxxxxxxxxxxxxxxxx"
Text in, talking-avatar video out — five lines:
from pathlib import Path
from visionstory import VisionStoryClient, build_video_payload
client = VisionStoryClient.from_env() # reads VISIONSTORY_API_KEY
video = client.generate_video(build_video_payload(avatar_id="4321918387609092991", text="Hello World, this is my first test video.", voice_id="Alice"))
client.download(video["video_url"], Path("result.mp4"))
generate_video() blocks until the task reaches a terminal state (default timeout 600s, polling every 5s) and returns the finished video object, including video_url. Completed videos are retained for 7 days — download the file if you need permanent storage.
Before building a production integration, discover current IDs instead of hardcoding them:
client.list_models() # GET /api/v1/models
client.list_avatars() # GET /api/v1/avatars
client.list_voices() # GET /api/v1/voices
To use your own audio instead of text, pass audio_url= or audio_file= (a local file, base64-encoded automatically) to build_video_payload() in place of text= — exactly one source is allowed.
Non-blocking mode
Prefer to manage polling yourself? Submit and poll separately:
created = client.generate_video(payload, wait=False) # returns {"video_id": ...} immediately
video = client.wait_for_video(created["video_id"]) # or client.get_video(video_id) manually
Idempotent retries (client_request_id)
Video creation charges credits, so retrying a request that may have already succeeded is risky. Add a client_request_id (an idempotency key of your choice) to make resubmission safe — within 24 hours, the same key returns the original task instead of creating and charging a new one:
payload = build_video_payload(avatar_id="4321918387609092991", text="Hello!", voice_id="Alice")
payload["client_request_id"] = "order-42-intro-video" # ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$
video = client.generate_video(payload) # safe to retry on network errors
If the first submission is still in flight, a retry gets HTTP 409 with a hint to retry shortly.
Error handling
All API failures raise VisionStoryAPIError. The message embeds the API's error body, which carries an error.hint field — a one-sentence, actionable next step (e.g. out of credits → top up at the pricing page). Print it as-is or feed it to your agent:
from visionstory import VisionStoryAPIError
try:
video = client.generate_video(payload)
except VisionStoryAPIError as e:
print(e) # e.g. POST /api/v1/video failed with HTTP 403: {"error": {"code": ..., "message": ..., "hint": "..."}}
Failed generations are refunded automatically; generate_video() raises with that context instead of returning a failed task.
Configuration
| Environment variable | Purpose | Default |
|---|---|---|
VISIONSTORY_API_KEY |
API key (required for from_env()) |
— |
VISIONSTORY_API_BASE |
API base URL override | https://openapi.visionstory.ai |
You can also construct the client explicitly: VisionStoryClient(api_key, base_url=..., request_timeout=...).
More resources
- API documentation — full reference, guides, and error codes.
- Quick start guide
- For agents — MCP server, Agent Skill package, and llms.txt.
Development
This SDK is not generated from the OpenAPI spec. The API surface is intentionally small (~21 operations), and the repository already maintains a mature zero-dependency client layer (src/open_api/client/core.py) with blocking-poll semantics shared by the MCP server and the Agent Skill package. v0.1 packages that client directly; visionstory/_core.py is a script-generated copy kept in lockstep by scripts/check_sdk_sync.py (CI-gated — run with --fix to re-sync). Generator pipelines (Fern / OpenAPI Generator) will be re-evaluated once the endpoint surface grows enough to justify them.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file visionstory-0.0.1.tar.gz.
File metadata
- Download URL: visionstory-0.0.1.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
504663c44def7557bf02bfe6f1f50005fe4974ff175fe264c76670510ca0a9e6
|
|
| MD5 |
bf71a6eab4ea1fab9585b4fbda26efe6
|
|
| BLAKE2b-256 |
ac01bd50bd39f98b2c90b4d9c66d8ab1bc979ab97a0135989da36e708b89f460
|
File details
Details for the file visionstory-0.0.1-py3-none-any.whl.
File metadata
- Download URL: visionstory-0.0.1-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02de535f4fb66d54e9a48204e490841183372b1715d493274ec08035661a5635
|
|
| MD5 |
3e6436545d7af0fd23d88bdab4821983
|
|
| BLAKE2b-256 |
6c81f7361c177125e1b0b0472dd3f5524a3bcdde032bac8109ec813e0499ad5b
|