Veo 3.1 Image-to-Video API Guide: Animate Images via GenRelay

Aug 15, 2026·10 min read

You have a product image, a portrait, or a static scene — and you want to turn it into a short video clip. Veo 3.1's image-to-video (i2v) mode takes a still image as the first frame and generates motion from it based on your prompt. The use cases are concrete: animating e-commerce product photos, bringing marketing visuals to life, adding motion to social content, or generating preview clips from static designs.

This guide covers everything specific to the i2v mode: image preparation, the API request, motion prompting, async polling, resolution pricing, and production patterns. For the broader Veo 3.1 tutorial including text-to-video, reference-to-video, and audio, see the Veo 3.1 API tutorial.


What is Veo 3.1 image-to-video and how does it work?

Veo 3.1 image-to-video (i2v) is a generation mode where a provided image becomes the first frame of the output video. The model synthesizes motion from that starting point in the direction your text prompt specifies — camera movement, subject motion, environmental dynamics. The output is a short video clip (1–8 seconds) at your chosen resolution.

This differs from reference-to-video (ref2v), where an image guides visual style without becoming the actual first frame. In i2v, the image IS the opening frame; what you provide is exactly what the video starts with.


How do I authenticate with the GenRelay API?

All GenRelay endpoints use Bearer token authentication. Sign up at genrelay.ai, get your API key from the dashboard, and include it in every request:

Authorization: Bearer grk_live_YOUR_API_KEY

New accounts receive free credits — enough to run several test generations before adding payment.


How do I make an image-to-video request?

Veo 3.1 i2v is asynchronous: the POST returns a job ID immediately; you poll for results using a separate GET request. Here is a complete Python implementation:

import requests
import time

API_KEY = "grk_live_YOUR_KEY_HERE"
BASE = "https://genrelay.ai"

def submit_i2v_job(image_url: str, prompt: str, duration: int = 5,
                   resolution: str = "720p", aspect_ratio: str = "16:9") -> str:
    resp = requests.post(
        f"{BASE}/v1/videos/generations",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        json={
            "model": "veo-3.1",
            "prompt": prompt,
            "image_url": image_url,
            "duration": duration,
            "resolution": resolution,
            "aspect_ratio": aspect_ratio,
        },
    )
    resp.raise_for_status()
    job_id = resp.json()["id"]
    print(f"Job submitted: {job_id}")
    return job_id

def poll_job(job_id: str, interval: int = 8, timeout: int = 360) -> dict:
    deadline = time.time() + timeout
    while time.time() < deadline:
        resp = requests.get(
            f"{BASE}/v1/videos/generations/{job_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
        )
        result = resp.json()
        status = result.get("status")
        print(f"  status: {status}")
        if status == "succeeded":
            return result
        if status == "failed":
            raise RuntimeError(f"Job failed: {result.get('error')}")
        time.sleep(interval)
    raise TimeoutError(f"Job {job_id} timed out after {timeout}s")

# Animate a product image
job_id = submit_i2v_job(
    image_url="https://your-cdn.com/sneaker-front.jpg",
    prompt="The sneaker slowly rotates to reveal the heel, soft studio lighting, white background",
    duration=5,
    resolution="720p",
    aspect_ratio="1:1",
)
result = poll_job(job_id)
video_url = result["output"]["url"]
print("Video:", video_url)
# Cost: 5s × $0.060 = $0.30

The image_url must be publicly accessible. If your images are served behind authentication, pre-sign the URL or proxy through a CDN before passing it to the API. The video URL in the response expires after 24 hours — download and store it immediately.


What image formats and sizes work best?

The source image quality directly affects the output. A blurry or low-resolution input image constrains how well the model can render motion details.

Format: JPEG and PNG are both supported. For images with transparency (product shots on a white-removed background), use PNG.

Resolution: Input at 720p or above. A 1024×1024 image is a solid starting point for most use cases. Very small inputs (under 512px on either dimension) often produce soft or artifact-heavy outputs.

Aspect ratio: Match the input image aspect ratio to the aspect_ratio parameter you request. If you submit a portrait image (2:3) with "aspect_ratio": "16:9", the model will crop or pad — usually not what you want. Supported ratios: 16:9, 9:16, 1:1, 4:3.

Subject clarity: The model performs best on images with a clear subject and uncluttered background. For product animation specifically, clean studio-style images (white or neutral background) produce the most predictable motion.


How do I write effective motion prompts for i2v?

Your text prompt instructs the model on what motion to generate FROM the starting image. The image provides the visual; the prompt specifies movement. Keep prompts motion-focused rather than restating what is already in the image.

Effective i2v prompt patterns:

Goal Prompt example
Product rotation "Slow 360° rotation from front to back, studio lighting, white background"
Camera push-in "Smooth camera push into the center of frame, slight depth-of-field shift"
Environmental dynamics "Wind moves through the hair, slight head tilt, natural daylight, bokeh background"
Ambient motion "Gentle ripples spread outward from the center, warm afternoon light"
Subject reveal "Pull back to reveal the full scene, cinematic, slow motion"

What to avoid: prompts that describe the image itself ("a red sneaker on white background") or that introduce new subjects not in the starting image. The model generates motion from what exists — it does not add new objects.

A useful frame: write the prompt as if you're directing a camera operator and an actor who can already see the image.


How do I handle the async response in production?

Veo 3.1 generation typically takes 30–120 seconds depending on duration and resolution. Do not poll faster than every 5–8 seconds — excessive polling can trigger rate limits.

For production applications where a user is waiting for the result, a clean implementation separates job submission from result delivery:

import requests
import time

def submit_and_wait(image_url: str, prompt: str, **kwargs) -> str:
    job_id = submit_i2v_job(image_url, prompt, **kwargs)
    result = poll_job(job_id)
    return result["output"]["url"]

def submit_batch(items: list[dict]) -> list[str]:
    # Submit all jobs first, then poll concurrently
    job_ids = [
        submit_i2v_job(item["image_url"], item["prompt"], **item.get("opts", {}))
        for item in items
    ]
    results = []
    for job_id in job_ids:
        result = poll_job(job_id)
        results.append(result["output"]["url"])
    return results

# Batch: 3 product images in parallel
products = [
    {"image_url": "https://cdn.example.com/shoe-front.jpg",
     "prompt": "Slow rotation revealing the sole, white background"},
    {"image_url": "https://cdn.example.com/bag-side.jpg",
     "prompt": "Gentle sway showing the strap detail, studio lighting"},
    {"image_url": "https://cdn.example.com/watch-face.jpg",
     "prompt": "Slow zoom into dial detail, reflection on glass"},
]
video_urls = submit_batch(products)

For true parallelism in production, use concurrent.futures.ThreadPoolExecutor to poll jobs concurrently rather than sequentially.


What does Veo 3.1 i2v cost?

Billing is per second of output video at the resolution you specify. Failed jobs are not charged.

Resolution Price per second
720p $0.060
1080p $0.120

Common workload estimates:

Scenario Duration Resolution Cost per clip
Short product loop 4s 720p $0.24
Standard product demo 5s 720p $0.30
High-quality marketing clip 5s 1080p $0.60
Extended scene 8s 720p $0.48
50 product videos/month 5s 720p $15.00
200 product videos/month 5s 720p $60.00

For high-volume pipelines where 720p quality is sufficient (social clips, preview videos), 720p minimizes both cost and generation time. Use 1080p when the output will be displayed at full screen or in a high-quality player where the resolution difference is visible.

For comparison: Gemini Omni Flash charges per generation rather than per second ($0.10 for 720p, $0.15 for 1080p per clip) and is worth evaluating for shorter clips where the per-generation model is more cost-effective.


How do I handle errors specific to i2v?

Error Cause Fix
422 Unprocessable Entity image_url not reachable, invalid format, or aspect ratio mismatch Verify the URL is public, image is JPEG/PNG, and aspect_ratio matches input
400 Bad Request + content policy reason Image content rejected (faces in certain contexts, IP-protected imagery) Check content policy; avoid images with real individuals in fabricated scenarios
401 Unauthorized Missing or invalid Bearer token Confirm Authorization: Bearer grk_live_YOUR_KEY header format
402 Payment Required Credits exhausted Add credits at genrelay.ai/billing
429 Too Many Requests Rate limit exceeded Exponential backoff; minimum 5s between retries
Job status: "failed" Model-side rejection or transient error Retry once; inspect error.message

The most common i2v-specific error is 422 from an inaccessible image_url. Test your image URLs independently (e.g., curl -I <url>) to confirm public accessibility before debugging the API call.


FAQ

Does Veo 3.1 i2v support base64 image input, or only URLs?
As of August 2026, the GenRelay API accepts publicly accessible URLs via image_url. Base64 input is not directly supported — host your image on a CDN or object storage and pass the public URL.

How does i2v differ from reference-to-video (ref2v)?
In i2v, the provided image becomes the literal first frame of the video — the clip starts exactly with that image. In ref2v, the image is a visual style guide — the model generates a new scene that inherits the visual characteristics of the reference without using it as a starting frame. See the Veo 3.1 API tutorial for ref2v parameter details.

What aspect ratios are supported for image-to-video?
Supported aspect_ratio values: 16:9, 9:16, 1:1, 4:3. Match this to your source image's natural aspect ratio for best results.

Can I add audio to an i2v generation?
Yes — add "audio": true to your request payload. Veo 3.1 will synthesize ambient sound or music appropriate to the scene. Check the GenRelay pricing page for the audio-enabled rate, which adds to the base per-second cost.

Is there a minimum or maximum duration for i2v jobs?
Duration range is 1–8 seconds per request. For clips longer than 8 seconds, generate sequential clips and concatenate with ffmpeg: ffmpeg -f concat -safe 0 -i clips.txt -c copy output.mp4.

How long before the output URL expires?
Video URLs expire 24 hours after generation. Download and store the file to your own storage immediately after retrieval.


Common use cases for Veo 3.1 i2v

E-commerce product animation: Turn static product photography into rotating or zooming clips for product pages and ads. Use 1:1 aspect ratio to match common social formats, 720p for web delivery at $0.30/clip.

Marketing and social content: Animate a hero image into a motion banner or social video. Camera push-in or ambient motion prompts work well for scenes that should feel "alive" without introducing new elements.

Avatar and portrait motion: Generate a short motion clip from a portrait photo — subtle head movement, hair dynamics, background bokeh shift. Keep duration short (3–5s) and prompt for minimal motion to avoid artifacts.

Storyboard and prototype video: Convert design mockups or wireframe screenshots into motion previews for stakeholder review. Fast and low-cost at $0.30/clip before committing to full production video.


All Veo 3.1 generation modes — text-to-video, image-to-video, reference-to-video, and audio — are available on GenRelay with a single API key and free credits for new accounts.

Related posts

Join our DiscordVeo 3.1 Image-to-Video API Guide: Animate Images via GenRelay — GenRelay