Video from Image

Animate an image into a short video (Google Veo, async/delayed)

Async image-to-video generation using Google Veo. Provide a source image (URL or base64) plus an optional motion-guidance prompt; choose model (`veo (Audio)` or `veo fast (Audio)`), resolution (512P / 1080P), duration (4s / 8s), and aspect_ratio (16:9 / 9:16). `media-video-from-image` is **is_delayed:true** — the gateway returns 202 + a gateway job_id immediately. The worker calls the upstream, which queues a task in a dedicated video worker pool, and the gateway worker polls the upstream's `/api/video/status/{job_id}` automatically. Pricing: $1.50/second of generated video (catalog rate). For a 4s video that's $6 per generation.

videogenerationimage-to-videoveoasync

Overview

Features

Source from URL or base64

Pass the image as a URL (use upload-media for local files) or base64-encoded bytes — both go in the `image` field.

Optional motion prompt

An optional `prompt` field steers how the image should animate. If omitted, the upstream applies its default motion model.

Google Veo backend

Two model options: `veo (Audio)` (default, includes audio) and `veo fast (Audio)` (faster).

Async pipeline (delayed service + double polling)

Gateway returns 202 + job.id; worker calls upstream, upstream returns its own job_id, worker polls upstream's /api/video/status/{job_id} until complete. 600s timeout (10 min).

Per-second pricing

$1.50/s — 4s = $6, 8s = $12. usage.units = duration in seconds.

Use Cases

Animated product hero

Take a still product photo and animate it into a looping hero video for landing pages.

Cinemagraph-style content

Add subtle motion to portraits, landscapes, art for social posts.

Concept previs

Animate concept art / mood boards before commissioning real production.

Vertical (TikTok / Reels) content

Use aspect_ratio: 9:16 to generate portrait-format videos from existing portraits.

Input / Output

Input

image (URL or base64) + optional prompt + optional model/resolution/duration/aspect_ratio

JSON body

Output

Initial 202 + gateway job_id; eventual result_data carries the video URL + duration + metadata

JSON (job envelope)Video URL (in result_data)

Specs

Latency
Async — typically 1-5 minutes (longer for 1080P / 8s). Gateway timeout 600s.
Async
true
Rate Limit
60 req/min per API key
Max Input
Source image as URL (any web-accessible image) or base64. Prompt limits per Veo's spec.

Quickstart

Prerequisites

  • -A CN8 Gateway API key with media-video-from-image in allowed_services
  • -A source image — public URL OR base64-encoded bytes (use upload-media for local files)

1. (Optional) Upload your source image

upload-media

If your image is local, use upload-media to get a public_url.

POST
{ "media_type": "image", "filename": "source.png", "content_type": "image/png" }

Response

{
  "status": "success",
  "data": {
    "upload_url": "https://s3.eu-central-1.wasabisys.com/.../source.png?...",
    "public_url": "https://s3.eu-central-1.wasabisys.com/.../source.png?..."
  }
}

PUT your file to upload_url, then use public_url as the `image` field below.

2. Submit a generation job

media-video-from-image

POST image (URL or base64) + optional prompt + optional parameters. The gateway returns 202 + job.id immediately.

POST/v1/proxy/media-video-from-image
{
  "image": "https://s3.eu-central-1.wasabisys.com/.../source.png?...",
  "prompt": "Gentle camera push-in, mist drifting, water reflections shimmering",
  "model": "veo (Audio)",
  "resolution": "1080P",
  "duration": "4s",
  "aspect_ratio": "16:9"
}

Response

{
  "status": "accepted",
  "message": "Job queued for processing",
  "job": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "queued",
    "service": "media-video-from-image",
    "created_at": "2026-04-27T10:30:00Z"
  }
}

Save the gateway job.id and poll GET /v2/jobs/{job_id}. Worker handles upstream + upstream-status polling automatically.

3. Poll for the video

Standard async-job polling.

GET
GET /v2/jobs/{job_id}

Response

{
  "id": "550e8400-...",
  "status": "completed",
  "service_name": "media-video-from-image",
  "created_at": "2026-04-27T10:30:00Z",
  "completed_at": "2026-04-27T10:33:42Z",
  "result_data": {
    "status": "success",
    "video_url": "https://s3.example.com/.../video.mp4",
    "duration_seconds": 4.0,
    "model": "veo (Audio)",
    "resolution": "1080P",
    "aspect_ratio": "16:9"
  },
  "units_consumed": 4.0,
  "token_cost": 6.0
}

Billing: 4s × $1.50 = $6.00. result_data shape comes from the upstream — typical fields shown.

Video from Image

POSTasync

Async image-to-video via Google Veo. Returns 202 + gateway job_id. The worker handles upstream POST + status polling. Billed per second of generated video.

/v1/proxy/media-video-from-image

Pricing

Per second of generated video. Async — billing happens once when the gateway job completes.

ServiceUnitPrice
Video from Imagesecond$1.50/second
  • -Examples: 4s 1080P video = $6.00; 8s 1080P video = $12.00.
  • -Pricing is the same for veo (Audio) and veo fast (Audio) — model choice is about latency, not cost.
  • -If the upstream fails (HTTP 4xx/5xx or {status:'error'} envelope), the gateway marks the job FAILED and skips billing (worker.py fix 2026-04-27).

Guides & Tips

Async lifecycle (double polling)

  • -1. POST media-video-from-image → 202 + gateway job.id.
  • -2. Worker calls upstream POST /api/video/from-image → upstream returns its own job_id.
  • -3. Gateway worker polls upstream `/api/video/status/{upstream_job_id}` automatically.
  • -4. When upstream returns success, gateway updates its job and bills (only on success).
  • -5. Optionally publishes a webhook event.
  • -6. Client polls GET /v2/jobs/{gateway_job_id} for the final result.

URL vs base64

  • -URL (preferred): pass a public/presigned URL in the `image` field. Faster; nothing has to be uploaded with the request body.
  • -base64: pass `data:image/png;base64,...` or just the raw base64 string. Useful when you don't have somewhere to host the image first. Larger request bodies; subject to upstream upload size limits.

Veo vs Veo fast

  • -veo (Audio) (default): higher quality, slower. Use for final outputs.
  • -veo fast (Audio): faster generation, slightly lower quality. Use for iteration / drafts.

Aspect ratio choice

  • -`16:9` (default) — landscape. Best for desktop / YouTube / TV. Source image cropped/letterboxed if needed.
  • -`9:16` — portrait. Best for TikTok / Instagram Reels / Shorts.
  • -Pick the aspect_ratio that best matches your source image to minimise cropping.

Writing motion prompts

  • -The optional `prompt` field guides the motion, not the content. Useful patterns:
  • -Camera moves: "slow push-in", "dolly out", "pan left to right", "tilt up"
  • -Subject motion: "subject takes a slow breath", "leaves rustle in the wind", "water ripples"
  • -Atmosphere: "mist drifting in", "snow falling", "fog clearing"
  • -Avoid describing the scene contents — those are already in the image.

FAQ

Q: How long does generation take?

A: Async, typically 1-5 minutes for 4s/1080P. Up to 10 minutes (600s) before the gateway times out.

Q: Can I upload a local image?

A: Use upload-media first to get a public_url, then pass that as `image`. Or base64-encode it and pass directly.

Q: Does the source image need to match the aspect_ratio?

A: Not strictly — the upstream will crop/letterbox to fit. Matching helps avoid unwanted cropping.

Q: Why does duration take a string ('4s') instead of a number?

A: Upstream Pydantic expects exact string values '4s' or '8s'. Passing 4 (int) returns a 400.

Q: Will I be billed if generation fails?

A: No — as of 2026-04-27, the worker detects upstream failures (HTTP 4xx/5xx or {status:'error'} envelope) and skips billing for FAILED jobs.

Related Products

Changelog

1.1 (2026-04-27)

  • -Documented the full async lifecycle (gateway job + worker auto-polling of the upstream's status endpoint).
  • -Confirmed Pydantic VideoFromImageRequest defaults: model='veo (Audio)', resolution='1080P', duration='4s', aspect_ratio='16:9'.
  • -Documented enum values exactly: model is one of 'veo (Audio)' / 'veo fast (Audio)' (with the parenthesised 'Audio' suffix), duration is '4s'/'8s' (string with s suffix).
  • -Documented the 600s gateway timeout.
  • -Added the no-bill-on-failure note (worker.py fix 2026-04-27).
  • -Added URL vs base64 guidance and motion-prompt patterns.

1.0 (2026-01-26)

  • -Initial catalog: media-video-from-image.