'end_image_url requires image_url': a last frame needs a first frame
A last frame without a first frame is refused on both Sume video routes. Add a first frame, or drop the end frame and describe the ending in the prompt.

"end_image_url requires image_url or first_frame_url." means you sent only a last frame to Video Router. Sume video models treat the end frame as a second anchor, so a start frame must come with it. The OpenRouter-shaped route says the same thing in its own words: "frame_images with a last_frame also requires a first_frame."
Both routes refuse a last-frame-only request
On the Video Router the check looks at the flat fields. On /v1/videos it looks at the frame_images array and raises an unsupported_capability error that names the model. Either way no job is created and nothing is reserved.
This means "end on this exact still" is not a standalone mode. If you only have the ending picture, you have three honest options.
| Route | You send | Result |
|---|---|---|
| POST /v1/video-router/generate | end_image_url only | 400: end_image_url requires image_url or first_frame_url. |
| POST /v1/video-router/generate | last_frame_url only | Same 400, same message |
| POST /v1/videos | frame_images with only last_frame | unsupported_capability: frame_images with a last_frame also requires a first_frame. |
| Either route | first and last frame together | Accepted if the model has end-frame support |
Three ways out
Supply a first frame. If the shot continues a previous clip, the last frame of that clip makes a natural first frame; video_frames can extract it from a stored clip, as the related post on opening episode two shows. If the shot has no predecessor, make or pick a still that represents the opening and send both.
- Add the opening still and keep the end frame, on a model with
end_frame: true. - Drop the end frame and describe the ending in the prompt, accepting less control.
- Generate the opening still first, then run the clip with both anchors.
Check the model supports an end frame at all
Even with a first frame, some models refuse the end frame. The catalog marks grok-imagine-video-1.5 and h3-max-recast as having no end frame, and Grok returns "end_image_url is not supported by model grok-imagine-video-1.5." The snippet reads the flag from the documented models endpoint, using supported_frame_images on each entry.
import os
import requests
hdr = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
r = requests.get("https://api.sume.com/v1/videos/models", headers=hdr, timeout=30)
r.raise_for_status()
for m in r.json()["data"]:
frames = m.get("supported_frame_images") or []
if "last_frame" in frames:
print(m["id"], frames)
When this is the wrong tool
If you need a clip that lands on a precise end picture and cannot invent a start, a two-anchor interpolation is not available as a mode here; treat it as a prompt problem or build the first frame yourself. A still from a stock folder or a brand asset works as well as a generated one, as long as it is a public HTTPS image. Whatever you choose, test the combination on a short, cheap clip before committing to the full length.
Sources
Related posts
More in Developers
- An es-MX voice with an es-ES request: Sume compares primary language
Sume's TTS language check compares regional tags by primary language, so es-MX against es-ES passes. What that means for accent, and what 409 you get otherwise.
- Estimate a Sume video clip in Python: list x 1.25, rounded up
A runnable Python script that prices a clip for Wan 3.0, MiniMax H3, H3 Max and Gemini Omni 1.1 Flash with integer micros, so the cents match the bill.
- Add the EU AI icon to a clip with Timeline compose overlay
The EU publishes an AI icon as PNG and SVG. Sume timeline compose with operation overlay puts a hosted still on a hosted video and returns a new MP4 for $0.02.
- If a lip-sync job fails on Sume, is the reserved money refunded?
Yes. Sume reserves the price at admit, captures on completion and refunds on failure. For a 5-second H3 Max lip-sync at 768p the reservation is $0.50.
Written by Sume