First-frame image for /v1/videos: public HTTPS only, no signed URLs
Image and video inputs to Sume generation must be fetchable public HTTPS URLs. Localhost, private IPs, signed URLs and wrong content types are rejected.

Give Sume a first-frame or reference image as a public HTTPS URL. For the launch media fields, the Media inputs page says input URLs must be fetchable public HTTPS URLs and that the API rejects localhost, private-network, non-HTTPS and signed or private URLs, and mismatched content types, before the job is created. A pre-signed bucket link will not work there. There is no upload step for normal requests.
That rule is written for the launch media fields in Media inputs. For /v1/videos, which takes frame_images and input_references, the Video generation troubleshooting asks that all reference images be available over public HTTPS and in supported formats, so treat the same rule as the safe one.
Preflight, then submit
A HEAD request catches the three mistakes you control: scheme, redirect to a login page, and wrong content type. Use supported_frame_images from GET /v1/videos/models to know whether a model takes first_frame, last_frame, or both.
import os, requests
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
def check(url):
if not url.startswith("https://"):
raise ValueError("not https: " + url)
r = requests.head(url, allow_redirects=True, timeout=10)
if not r.ok or not r.headers.get("content-type", "").startswith("image/"):
raise ValueError("not a fetchable image: %s %s" % (r.status_code, url))
first = "https://example.com/first-frame.png"
check(first)
body = {
"model": "seedance-2",
"prompt": "The character walks into the forest",
"frame_images": [{"type": "image_url", "image_url": {"url": first},
"frame_type": "first_frame"}],
"resolution": "720p",
}
r = requests.post("https://api.sume.com/v1/videos", json=body, headers=H, timeout=30)
print(r.status_code, r.json())Which field does what
| Field | Mode | Entry shape |
|---|---|---|
frame_images | Image to video | frame_type of first_frame or last_frame |
input_references | Reference to video | Style or content guides, not exact frames |
| Both sent | Image to video | frame_images wins |
When the fetch still fails
Errors such as image_not_fetchable or input_media_unreachable mean Sume could not fetch or mirror the media safely. Make sure the URL is public HTTPS, then retry with the same idempotency key, or send the request_id to support.
Making inputs reliable
Host reference images on a stable public address that does not redirect to a login page and does not expire within the job's runtime. Sume fetches and mirrors the media, so a link that works for your browser session but not for an anonymous client will fail at the fetch.
- Serve the right
content-type; a PNG labelled asapplication/octet-streamis a mismatch. - Avoid short-lived presigned URLs, which the API treats as signed or private.
- Store outputs by their media.sume.com URL, not the input URL, once the job completes.
Sources
Related posts
More in Developers
- Free, Pro, Startup, Scale: processing seats, queue slots, full hold
Sume's concurrency by plan, queue capacity max(3, 5 x concurrency), accepted job capacity, and the balance reserved if every slot holds a 10 s clip.
- Typed Sume video client from the OpenAPI JSON, after Sora
Sume publishes OpenAPI 3.0.3 at api.sume.com/reference/json. List the four video operations, then use the SDK's generated calls instead of hand-typing the wire.
- Generate then cut out: an image-model result into RMBG, in Python
Two Sume calls: generate a product shot, then POST its URL to /v1/rmbg-1.0/remove. Runnable Python, the polling loop, and the $0.1225 total per cutout.
- Go: net/http client for a 30-second Wan 3.0 clip, 30 lines
A 30-line Go program using only the standard library: submit wan-3.0 for 30 seconds, poll the job, write clip.mp4. Reserve and per-second rate included.
Written by Sume