Omni reference tokens follow list order: swap list, swap meaning
<IMAGE_REF_0> is the first URL in reference_image_urls, so reordering the list rewires the prompt. A check function and an 8 s body, $1.00 at 720p on Sume.

In a Gemini Omni Flash 1.1 reference request, <IMAGE_REF_0> means the first URL in reference_image_urls and <IMAGE_REF_1> the second, counted from 0 in list order. If you reorder the list but not the prompt, the prompt now describes the wrong picture, and the 8-second clip still costs $1.00 at 720p on Sume.
That is a cheap bug to make and an expensive one to find by eye. This post shows the numbering rule and a check that catches it before you submit (price from the Sume price tool, read 2026-10-09).
The numbering rule
Limits: up to 10 reference images and up to 3 reference videos of at most 3 seconds each. The catalog notes that reference media is sent before the prompt, which is why the numbering follows the list and not the prompt text.
| Token | Refers to | Counted from |
|---|---|---|
<IMAGE_REF_0> | First URL in reference_image_urls | 0 |
<IMAGE_REF_1> | Second URL in reference_image_urls | 0 |
<VIDEO_REF_0> | First URL in reference_video_urls | 0 |
A body where the order matters
Here the product is first and the hand is second. Swap the two URLs and <IMAGE_REF_0> becomes the hand.
{
"model": "gemini-omni-flash-1.1",
"prompt": "<IMAGE_REF_0> sits on a desk while <IMAGE_REF_1> picks it up",
"reference_image_urls": [
"https://example.com/product.png",
"https://example.com/hand.png"
],
"resolution": "720p",
"duration": 8,
"aspect_ratio": "9:16",
"mode": "async"
}A check before you submit
This function fails when a token points past the end of its list. It cannot tell whether the order is right, so keep the list and the prompt in one place in your code.
import re
def check(prompt, images, videos):
for kind, items in (("IMAGE", images), ("VIDEO", videos)):
for n in map(int, re.findall(rf"<{kind}_REF_(\d+)>", prompt)):
if n >= len(items):
raise ValueError(f"<{kind}_REF_{n}> but only {len(items)} {kind.lower()}s")
images = ["https://example.com/product.png", "https://example.com/hand.png"]
check("<IMAGE_REF_0> sits on a desk while <IMAGE_REF_1> picks it up", images, [])What a mix-up costs
A wrong-order take is still a full take. At 720p an 8-second take is $1.00, and ten of them are $10.00. At 1080p, ten are $15.00. Test the order at 360p, where an 8-second take is $0.30.
Write the prompt and the list in one function so the pair cannot drift apart, and add the token check above to your tests.
Limits and gotchas
If the clip shows the right objects doing the wrong thing, look at the list order first.
- Edit requests use
video_url, and it cannot ride withreference_*_urls. Tokens do not apply to an edit. reference_audio_urlsis not supported on Omni.- Omni 1080p for the same 8 seconds costs $1.50; the tokens work the same at every resolution.
Sources
Related posts
More in Developers
- Omni reference videos: read Sume capabilities, not Google's note
Google's Omni page says multi-video reference is unsupported; Sume's docs list up to three reference clips. Read the catalog entry before you send them.
- Omni takes JPEG and PNG: gate each reference image URL in Python
Google lists JPEG and PNG for Gemini Omni image input. Check each reference_image_urls entry with a HEAD request, then submit the clean list through Sume.
- One prompt, two models: asyncio.gather Wan and Seedance for $21.08
Submit one 30 s prompt to wan-3.0 ($3.75) and seedance-2.5 ($17.334) with httpx and asyncio.run. Use one Idempotency-Key per request; a shared key conflicts.
- One webhook route for OpenRouter video and Sume job events
Normalize OpenRouter video.generation.* and Sume job.* webhook bodies to one outcome type, and answer 204 to events you do not know. Runnable Bun/Node code.
Written by Sume