Luma Ray3.2 image-to-video ad: first-frame models on Sume at 5 seconds

Luma Ray3.2 is not on Sume. For a still-to-video ad, a 5-second 720p clip is $0.63 on Omni or Wan, $0.70 on Kling 3 and $0.38 on H3 at 768p.

5 min readSume
All posts

Luma Ray3.2 is not a Sume catalog id, so for an image-to-video ad pick a listed model that takes a first frame: a 5-second clip costs $0.38 on minimax-h3 at 768p, $0.63 on gemini-omni-flash-1.1 or wan-3.0 at 720p, and $0.70 on kling-3. Every one of them takes the still through frame_images with frame_type first_frame.

This post makes no claims about Luma's own specs. Sume figures are from the Video Router guide and Video Generation, read 2026-10-05.

Five-second still-to-video prices

Sume bills the provider list price times 1.25 and rounds the job up to the cent, so a one-second figure here is a rate, not a charge.

First-frame models on Sume, 5-second clip (read 2026-10-05)
ModelResolutionRate per second5 s jobLast frame
minimax-h3768p$0.075$0.38Yes
gemini-omni-flash-1.1720p$0.125$0.63Yes
wan-3.0720p$0.125$0.63Yes
kling-3720p$0.14$0.70Yes

Using the first frame

Put the still in frame_images as first_frame and describe only the motion in the prompt, since the picture is already fixed. If you also send input_references, frame_images takes precedence on the models that accept both.

Ratios differ: Omni takes 16:9 and 9:16, Kling adds 1:1, Wan adds 4:3 and 3:4. Crop the still to the target ratio before sending.

  • Product on a clean background: Kling 3 for a silent clip, Omni if you want sound.
  • Longer than 10 s: Wan 3.0.
  • Cheapest still-to-video: H3 at 768p.

Request

Submit the still as a first frame.

import os, time, requests

H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
payload = {
    "model": "wan-3.0",
    "prompt": "Camera pushes in slowly, steam rises from the cup",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9",
    "frame_images": [
        {"type": "image_url", "image_url": {"url": "https://example.com/cup.png"}, "frame_type": "first_frame"}
    ],
}
job = requests.post("https://api.sume.com/v1/videos", headers=H, json=payload).json()
while True:
    time.sleep(30)
    s = requests.get(job["polling_url"], headers=H).json()
    if s["status"] in ("completed", "failed", "cancelled"):
        break
print(s["status"], s.get("unsigned_urls"), s.get("usage"))

Sources

Related posts

More in Comparisons

All Comparisons posts

Written by Sume