Turning product photos into listing videos with an API: a working pipeline
Updated 2026-10-17
Product video is the most predictable use of a video generation API, because you start with an asset you already own: the product photo. The job is not "make a cool clip". It is "turn 2,000 catalogue stills into short, on-brand, honest motion clips without a person babysitting each one". This page walks through a pipeline that does that, with the field choices and the failure points that matter.
Why image-to-video, not text-to-video
A text prompt cannot reproduce your actual product: the label, the stitching, the exact colourway. Text-to-video invents a plausible object. For a store listing that is a liability, because the shopper sees something the warehouse will not ship. So the default mode here is image-to-video: the photo becomes the first frame through start_image_url, and the prompt only describes motion. If you are unsure about the difference, the input modes comparison covers all three.
Reference-to-video (several images guiding one clip) is worth a look when you have multiple angles of the same item, but start with image-to-video because its failure modes are easier to review.
The pipeline in five stages
- Select and prepare images. Use the cleanest packshot per SKU: product centred, even lighting, no watermark, no overlaid text. Crop to the aspect ratio you intend to publish, since the model animates the frame you give it. Host the image at a public https URL, or send a
data:image/...;base64,URI for small files. - Build a motion prompt from a template. Fill a category-level template, for example "slow orbit left around the product, soft studio light, background stays still", rather than writing 2,000 prompts. Categories behave differently: jewellery wants sparkle and a slow turn, apparel wants fabric movement, electronics wants a gentle push-in.
- Submit N variants per SKU on a cheap tier. Two or three prompts per product, short duration, low resolution.
- Review. Automated checks first, then a human on the survivors.
- Promote and publish. Re-render only approved prompts on a higher tier, copy the file to your own storage and attach it to the listing.
The request
curl https://videorouter.sh/api/v1/videos \
-H "Authorization: Bearer llmr_sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"model": "bytedance/seedance-2.0-mini",
"start_image_url": "https://cdn.example.com/sku/48213/packshot.jpg",
"prompt": "slow orbit to the left around the product, soft studio light, background stays perfectly still, product shape and label do not change",
"duration_secs": 4,
"aspect_ratio": "1:1"
}'
The response is a job with status queued; poll GET /videos/{id} until it is completed or failed. Polling is free. Store the job id against the SKU and the prompt template version before you start polling, so any clip and any charge can be traced back. The request anatomy page explains the lifecycle in full.
Field choices that matter for products
| Field | Choice | Reason |
|---|---|---|
duration_secs | Shortest that shows the move | Billed once at creation by requested duration. Durations are snapped to what the model supports, so log the snapped value. |
aspect_ratio | Match the placement (1:1 grid, 9:16 story) | An unsupported combination is ignored, not rejected. Check the real file size with ffprobe. |
model | Cheap tier for drafts, better tier for finals | A tier is just a different model id, so promotion is a config change. |
| prompt: "do not change" | State what must stay fixed | Logos and packaging text are where models drift first. |
Cost control without quoting numbers
Cost scales as SKUs x variants x duration x tier, and the only multiplier you fully control is the tier you use for exploration. Spread across a catalogue, the draft stage is where money disappears, so keep it on the cheapest model that honours your image, and cap concurrency. Live per-model host pricing is below; the gap between the cheapest and priciest host for the same model is often larger than the gap between neighbouring tiers.
| Model | Cheapest host | Priciest host | Cheapest is | Hosts |
|---|---|---|---|---|
| bytedance/seedance-2.5 (720p) | SoCheap-Overseas $0.1419 / second | Fal-US $0.5676 / second | 75% lower | 11 |
| bytedance/seedance-2.0 (720p) | MachGen $0.1275 / second | Fal $0.3034 / second | 58% lower | 8 |
| alibaba/wan-3.0 (480p) | Replicate $0.025 / second | Alibaba $0.05 / second | 50% lower | 11 |
| google/gemini-omni-flash | Google $0.1 / second | Fal $0.13 / second | 23% lower | 4 |
| minimax/h3 (768p) | kie.ai $0.04 / second | WaveSpeedAI-resell $0.1 / second | 60% lower | 13 |
| alibaba/happyhorse-1.1 (720p) | Pika $0.098 / second | Alibaba $0.14 / second | 30% lower | 4 |
| bytedance/seedance-2.0-fast (480p) | Atlas Cloud $0.027 / second | Fal $0.2419 / second | 89% lower | 8 |
| bytedance/seedance-2.0-mini (480p) | Atlas Cloud $0.0112 / second | Fal $0.0721 / second | 84% lower | 7 |
| kling-o3 (720p) | SandBase $0.0588 / second | Tencent TokenHub $0.084 / second | 30% lower | 4 |
| kling-v3 (720p) | SandBase $0.0588 / second | Tencent TokenHub $0.084 / second | 30% lower | 8 |
| google/gemini-omni-1.1-flash (360p) | WaveSpeedAI $0.03 / second | Google $0.1 / second | 70% lower | 3 |
| lightricks/ltx-2.3-pro (2160p) | MachGen $0.1 / second | SandBase $0.32 / second | 69% lower | 2 |
Per second, before VideoRouter's 2.5% platform fee. For tiered models each row compares the resolution tier with the widest host-to-host gap. Built 2026-10-17 from the live catalog.
Two more levers. First, de-duplicate: many SKUs share a packshot with different SKU numbers (sizes, colours), so hash (model, image, prompt, duration) and reuse existing clips. Second, put a monthly spend cap on the key you use for the batch, so a loop bug stops at a known amount instead of at the credit balance. Key policy is covered on the authentication docs.
Review: what to reject
Product video fails in recognisable ways, and most can be caught before a human sees them:
- Shape drift: the product morphs mid-clip. Compare the first and last frame with a perceptual hash against the source image; a large distance flags it.
- Label rewriting: text on packaging turns to nonsense. Run OCR on a mid-clip frame and compare with OCR of the source.
- Wrong dimensions: the requested ratio was ignored. Reject on
ffprobemismatch. - Hands, faces and animals: if the image contains people, the model has more room to invent. Send those to a human first.
Then a person approves in bulk from a contact sheet. Anything claiming a feature the product does not have (a lid that opens, a screen that lights up) must be rejected even if it looks good, because it is a misleading listing.
Pitfalls
- Expired image URLs. Presigned links that expire before the host fetches them are a common cause of failed jobs. Use stable public URLs or data URIs.
- Retrying creation blindly. If the connection drops on create, the job may already exist and be billed. Park the SKU for reconciliation rather than re-submitting; see the async jobs docs.
- Storing the delivery URL. The returned URL is a delivery link. Copy the file to your storage before attaching it to a listing.
- Combining fields. A start image cannot be combined with reference arrays or an editing input in the same request.
- Disclosure. Check your marketplace's rules on AI-generated media before bulk publishing.
A sensible rollout
Run 20 SKUs from three categories end to end, measure the reject rate per category, and tune the templates before scaling. Then expand category by category. The use cases page places this workload next to the others, and the quickstart has the minimal call if you want to try one product today. Create an API key and put a small cap on it first.
Frequently asked questions
Should product videos use text-to-video or image-to-video?
Image-to-video. The photo becomes the first frame through start_image_url, so the product on screen is your product, and the prompt only describes motion.
How do I keep costs under control across a large catalogue?
Draft on a cheap model with short durations, de-duplicate identical image and prompt pairs, promote only approved clips, and set a monthly spend cap on the key. Billing happens once at creation from the requested duration.
What should I check before publishing a generated product clip?
Compare the first and last frame to the source for shape drift, OCR the label text, confirm real output dimensions with ffprobe, and have a person approve anything that shows features the product does not have.
Keep reading
- What Is a Video Generation API? How It Works and What It Costs
- Video Generation API Use Cases and the Workflow Each Needs
- Text-to-Video vs Image-to-Video vs Reference-to-Video (API)
- Build vs Buy Video Generation: Hosted API or Self-Hosting?
VideoRouter puts it next to dozens of other video and image models behind one API key, so you can compare providers, prices and fail over automatically. Compare providers on VideoRouter →