Pre-create characters and scenes to cut render latency by ~3x. Assets are stored and reusable across unlimited renders.
Character preprocessing costs 1 credit. Scene creation is free. Rendered video costs 1 credit/second.
Prerequisites
- A Viggle API key (get one here)
- A reference image (PNG or JPG)
- A driving video (MP4)
Workflow
Create a character
Upload a reference image to extract a reusable character embedding. Free — ~5s to process.import requests, time
API_KEY, BASE = "YOUR_API_KEY", "https://apis.viggle.ai"
headers = {"Authorization": f"Bearer {API_KEY}"}
resp = requests.post(f"{BASE}/api/characters/preprocess", headers=headers,
files={"image": open("character.png", "rb")},
data={"name": "My Character"})
character = resp.json()
character_id = character["character_id"]
Poll until ready:while True:
status = requests.get(f"{BASE}/api/characters/{character_id}", headers=headers).json()
if status["status"] == "ready": break
elif status["status"] == "failed": raise Exception(status.get("error_message"))
time.sleep(5)
Create a scene
Upload a driving video to extract motion data. Free — ~20s to process.resp = requests.post(f"{BASE}/api/scenes/preprocess", headers=headers,
files={"video": open("dance.mp4", "rb")},
data={"name": "Dance Sequence"})
scene = resp.json()
scene_id = scene["scene_id"]
Poll until ready:while True:
status = requests.get(f"{BASE}/api/scenes/{scene_id}", headers=headers).json()
if status["status"] == "ready": break
elif status["status"] == "failed": raise Exception(status.get("error_message"))
time.sleep(5)
Render
Combine character + scene to generate video.job = requests.post(f"{BASE}/api/render", headers=headers, data={
"character_id": character_id,
"scene_id": scene_id,
}).json()
print(f"Job: {job['job_id']}")
Poll and download
Poll every 3-5 seconds until complete, then use cdn_url to download the final video.while True:
status = requests.get(f"{BASE}/api/render/{job['job_id']}").json()
if status["status"] == "complete":
cdn_url = status["cdn_url"]
break
elif status["status"] == "failed": raise Exception(status.get("error_message"))
time.sleep(3)
video = requests.get(cdn_url)
open("output.mp4", "wb").write(video.content)
Reusing assets
Render same character with different scenes
job2 = requests.post(f"{BASE}/api/render", headers=headers, data={
"character_id": character_id,
"scene_id": another_scene_id,
}).json()
Render different character with same scene
job3 = requests.post(f"{BASE}/api/render", headers=headers, data={
"character_id": another_character_id,
"scene_id": scene_id,
}).json()
characters = requests.get(f"{BASE}/api/characters", headers=headers).json()
scenes = requests.get(f"{BASE}/api/scenes", headers=headers).json()
What’s next?
On-Demand Rendering
Render without preprocessing — one API call
Import Templates
Use pre-made templates from viggle.ai
Render Options
Background mode, fast mode, and more