Skip to main content

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.
  • CLI-compatible — pip install visionstory-cli adds a visionstory command over the same operations.

Installation

pip install visionstory

Interactive SDK sessions check for new releases quietly and show an actionable notice at most once per week. Checks are cached, never install anything, and fail silently offline. For an explicit machine-readable check:

from visionstory import check_for_updates

print(check_for_updates())

Set VISIONSTORY_UPDATE_CHECK=0 to disable passive notices.

Command line

Install visionstory-cli to get a visionstory command that covers the same surface as the SDK — no code required:

pip install visionstory-cli
export VISIONSTORY_API_KEY="sk-vs-xxxxxxxxxxxxxxxxxxx"

# Discover resources
visionstory models
visionstory avatars --is-public
visionstory voices
visionstory credits
visionstory assets

# Talking-avatar video
visionstory create-video --avatar-id 4321918387609092991 --text "Hello from VisionStory." --voice-id Alice --output result.mp4
visionstory status --video-id 7241059991822401536

# Avatars / voices / assets
visionstory create-avatar --image-url https://your.site/face.jpg
visionstory update-avatar-framing --avatar-id <id> --aspect-ratio 9:16 --zoom 1.2 --offset-x 0 --offset-y -0.25
visionstory clone-voice --audio-url https://your.site/sample.mp3
visionstory upload-asset --url https://your.site/clip.mp4

# Text-to-speech, transcription, alignment, and image generation (beta)
visionstory tts --text "Hello" --voice-id Alice --locale en-GB --output speech.mp3
visionstory transcribe --audio-file interview.mp3 --diarize --srt --output interview.srt
visionstory align --audio-url https://your.site/speech.mp3 --text "Hello"
visionstory image-models
visionstory create-image --model-id seedream-5.0-lite --prompt "a corgi surfing at sunset" --resolution 2K

# AI video (Seedance, Wan, Kling) (beta)
visionstory ai-video-models
visionstory ai-video-cost --model-id seedance-2.0 --duration-sec 8 --resolution 1080p
visionstory create-ai-video --model-id seedance-2.0 --prompt "a corgi surfing at sunset" --output ai.mp4

# Delete
visionstory delete-video --video-id 7241059991822401536

Every subcommand prints JSON and maps 1:1 to a client method. create-video / create-ai-video block until the video is ready and, with --output, download it (add --no-wait to return the task immediately). The create-image / create-ai-video commands also accept --json '<body>' to pass a full request body for advanced media references. Run visionstory --help (or visionstory <command> --help) for every command and option. The key is read from VISIONSTORY_API_KEY and never passed on the command line.

Quick start

Create an API key on the VisionStory API keys page 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(limit=20)                  # owned avatars
client.list_avatars(is_public=True, limit=20)  # public avatar library
client.list_voices(locale="en-GB", limit=20)   # GET /api/v1/voices

Avatar responses contain avatars and next_cursor; pass the latter back as cursor=. To change one saved crop on an owned avatar, call client.update_avatar_framing(avatar_id=..., aspect_ratio="9:16", zoom=1.2, offset_x=0, offset_y=-0.25). Public avatars cannot be reframed.

All public channels carry the same generated contract fingerprint. Use it in diagnostics or release checks to confirm the SDK, CLI, and MCP server were built from the same OpenAPI contract:

from visionstory import get_contract_info

print(get_contract_info())
# {'contract_version': '1.0.0', 'contract_hash': 'sha256:...', 'operation_count': 28}

Transcribe audio or align known text with word-level timestamps from a local WAV/MP3 file, public URL, or reusable asset:

transcript = client.transcribe_audio(audio_file=Path("interview.mp3"), diarize=True, srt=True)
alignment = client.align_audio(text="Hello", asset_id="YOUR_AUDIO_ASSET_ID")
speech = client.create_speech(text="Hello", voice_id="YOUR_VOICE_ID", locale="en-GB")

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

Development

This is a zero-dependency client (Python standard library only). The visionstory/_core.py module is generated and kept in sync with the VisionStory API — do not edit it by hand.

Structured media extraction and speech rate

Use understand_media for schema-constrained JSON from images, audio, or video. It takes required prompt, inputs, and schema, waits synchronously for up to 180 seconds, and returns output, usage, and cost_credit.

from visionstory import VisionStoryClient

client = VisionStoryClient.from_env()
result = client.understand_media(
    prompt="Identify the subject",
    inputs=[{"asset_id": "YOUR_ASSET_ID"}],
    schema={"type": "object", "properties": {"subject": {"type": "string"}}, "required": ["subject"]},
)
print(result["output"])

speech = client.create_speech(text="Hello", voice_id="YOUR_VOICE_ID", speech_rate="slow")
# Save speech["audio"] as MP3. Omit speech_rate to keep normal speed.

speech_rate accepts slow, normal, or fast; None leaves the field out. See Media Understanding for input limits, billing, and timeout handling, and Text to Speech for binary responses.

Metadata

Release files for visionstory 0.0.13

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for visionstory 0.0.13
File Size Uploaded Provenance Actions
visionstory-0.0.13.tar.gz 15.3 kB Without provenance Details for visionstory-0.0.13.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for visionstory 0.0.13
File Interpreter ABI Platform Actions
visionstory-0.0.13-py3-none-any.whl Python 3 none any Details for visionstory-0.0.13-py3-none-any.whl

Total release size: 32.7 kB

Release files / visionstory-0.0.13.tar.gz

Download URL visionstory-0.0.13.tar.gz
Size 15.3 kB
Tags Source
SHA-256 checksum
How to use checksums
fd3a1ca6381a843dd96b3297ca07589b21964f312e54a4e2ee3479740e3c7ce9
BLAKE2b-256 checksum
How to use checksums
573783f866ddc61cdb6d511a72d4880906b86b27db0670c0e1f801309299d24d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release files / visionstory-0.0.13-py3-none-any.whl

Download URL visionstory-0.0.13-py3-none-any.whl
Size 17.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ca1aaed1bbb273cd2d375b7b35cf2c6e407af655d7542ada3848226e0e69264c
BLAKE2b-256 checksum
How to use checksums
24d618f86335675f1bd03132d744537317cc58742b0a6fb8fab5246b58365da5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Security for visionstory 0.0.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page