Video generation
/v1/videos/generations turns a still image into a short video clip (image-to-video) with
Wan2.2. Because video generation takes minutes, this is an async, two-call API: you
submit a job, then poll it until it’s done.
Video is image-to-video — every request needs a source image (image as base64/data URL,
or image_url). The result is a base64 MP4.
Flow
Submit a job
POST /v1/videos/generations → returns a job id with status queued (HTTP 202). This places
a credit hold but doesn’t charge yet.
from openai import OpenAI
import base64, time, httpx
BASE = "https://api.crustoff.app/v1"
KEY = "sk-crustoff-..."
headers = {"Authorization": f"Bearer {KEY}"}
with open("start.png", "rb") as f:
image_b64 = "data:image/png;base64," + base64.b64encode(f.read()).decode()
job = httpx.post(f"{BASE}/videos/generations", headers=headers, json={
"model": "wan2.2-i2v",
"prompt": "the cat turns its head and blinks, cinematic",
"image": image_b64,
"seconds": 5,
"size": "480x832",
}).json()
job_id = job["id"]Poll until complete
GET /v1/videos/generations/{id} → processing while it runs, then completed with the video.
while True:
res = httpx.get(f"{BASE}/videos/generations/{job_id}", headers=headers).json()
if res["status"] == "completed":
break
if res["status"] == "failed":
raise RuntimeError("generation failed")
time.sleep(5)
with open("out.mp4", "wb") as f:
f.write(base64.b64decode(res["data"][0]["b64_json"]))Submit parameters
| Field | Type | Default | Notes |
|---|---|---|---|
model | string | — | A video model id (e.g. wan2.2-i2v) |
prompt | string | — | Required — describes the motion |
image | string | — | Source frame as base64 / data URL (required unless image_url) |
image_url | string | — | Source frame by URL (alternative to image) |
seconds | int | 5 | Output length, 1–10 (the billed unit) |
size | string | "480x832" | One of 480x832, 832x480, 624x624 |
negative_prompt | string | — | What to avoid |
seed | int | random | Reproducibility |
steps | int | model default | Denoising steps |
Responses
Submit (202):
{ "id": "req_abc123", "object": "video.generation", "status": "queued", "model": "wan2.2-i2v", "seconds": 5 }Poll while running:
{ "id": "req_abc123", "object": "video.generation", "status": "processing", "model": "wan2.2-i2v" }Poll when done:
{
"id": "req_abc123",
"object": "video.generation",
"status": "completed",
"model": "wan2.2-i2v",
"seconds": 5,
"data": [{ "b64_json": "<base64 mp4>", "format": "mp4" }]
}Generation typically takes 1–3 minutes. Poll every few seconds. The finished video is retained for a limited window (~30 minutes) — download it promptly. If a job fails on our side you are not charged; the credit hold is released.
Billing
Video is billed per second of output, charged once the job completes. A 5-second clip on
wan2.2-i2v ($0.030/sec) costs $0.15. See Pricing & billing.