Video transitions
Frame-to-frame: animate from a start frame, optionally toward an end frame, with optional motion guidance — image-to-video / keyframe morph. Same async contract as video generation: 202 + job id, poll GET /v1/jobs/:id or supply a webhook.
Endpoint
POST https://api.genie.tech/v1/videos/transitions
Authorization: Bearer sk-genie-{your-key}
Content-Type: application/jsonTry it
Submission accepts strict snake_case fields. On a runner that has the diffusion model loaded, the kickoff returns 202 + a polling URL and the eventual GET /v1/jobs/:id resolves to a WebM URL. When the model is not installed on the serving ComfyUI, the failed-poll response now carries code: "comfyui-model-missing" with the requested model and a upstreamError field so SDK clients can branch — instead of an opaque inference-failed with a deeply-escaped JSON wad in message.
Upload a file (encoded inline as a data: URI) or paste an https image URL. Start is required; end is optional — omit it for single-keyframe animate.
SDK + curl
# Submit (start frame -> optional end frame)
curl https://api.genie.tech/v1/videos/transitions \
-H "Authorization: Bearer $GENIE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan-2.1",
"start_image": "https://cdn.example/frame-a.png",
"end_image": "https://cdn.example/frame-b.png",
"prompt": "smooth cinematic morph",
"duration_seconds": 3,
"size": "512x512"
}'
# Poll
curl https://api.genie.tech/v1/jobs/$JOB_ID \
-H "Authorization: Bearer $GENIE_API_KEY"Request body
model—wan-2.1|ltx-video(free tier auto-substitutes toltx-video).start_image— required. Anhttps://URL or adata:image/...URI.end_image— optional second keyframe. Omit for single-keyframe animate; supply for a frame-to-frame transition.prompt— optional motion guidance (≤ 2000 chars). Empty = pure keyframe morph.duration_seconds— 1–15, default 4.size—512x512|720x720|1280x720|1920x1080.seed,negative_prompt— optional.webhook—{ url, secret? }; called when the job finishes.
Validation errors always include informative details (never an opaque {}).
Kickoff response
{
"id": "vidgen-cmoz...",
"object": "video.transition",
"status": "queued",
"poll_url": "/v1/jobs/cmoz...",
"created": 1731020000
}Completed response (poll)
{
"id": "vidgen-cmoz...",
"status": "completed",
"result": {
"url": "https://blob.genie.tech/.../transition.mp4",
"duration_ms": 9800
}
}https:// start_image/end_image pointing at link-local/metadata addresses (e.g. 169.254.169.254) is rejected before any job is enqueued — same defense as webhook.url. data: URIs are inert (never fetched).