Check an image URL before you pay for image-to-video: Python preflight
A bad first-frame URL fails the job with an input download error. A short Python check of status, content type and size catches most bad URLs first.

The short answer
Before you send a first-frame image to Sume, fetch the URL yourself and check three things: the status is 200, the content type starts with image/, and the size is what you expect. A bad URL surfaces as Could not download an input media URL (image_url). A short Python check catches it before the job is queued.
What the failure looks like
Sume downloads your image_url itself. If the download fails, the job fails with the message Could not download an input media URL (image_url). The usual causes are a private link, a signed URL that expired, a redirect to a login page, or a page that returns HTML with a 200. The model never sees a picture in any of those cases.
The preflight
The function below reads only the headers and a bounded number of bytes, so it is cheap. It returns the problem, or None.
import requests
def check_image(url, max_mb=20):
r = requests.get(url, stream=True, timeout=15, allow_redirects=True)
try:
if r.status_code != 200:
return f"status {r.status_code}"
kind = r.headers.get("content-type", "")
if not kind.startswith("image/"):
return f"content-type {kind or 'missing'}"
size = int(r.headers.get("content-length", 0))
if size > max_mb * 1024 * 1024:
return f"{size} bytes is over {max_mb} MB"
return None
finally:
r.close()
print(check_image("https://example.com/first-frame.png"))Which limits are yours
The 20 MB default in the script is your own guard, not a Sume limit. Set it to what your pipeline needs. The Sume lip-sync routes have their own file rules: the audio must be on the Sume media host and at most 10 MB.
What a check cannot see
A 200 with the right type can still be a bad frame: a thumbnail, a transparent PNG with the subject cut out, or a picture with a watermark. Open the image once. If the picture is a different ratio from the model's, the result is cropped or adapted, so check the model's supported ratios.
Then submit
After the check passes, send the request with an Idempotency-Key. A rerun with the same key and body returns the existing job, and a rerun with the same key and a different body is a conflict, so change the key when you change the image.
Sources
Related posts
More in Developers
- Check each shot against /v1/videos/models before submit: Python
A short Python check tests each shot's duration, resolution and ratio against GET /v1/videos/models fields, so a bad shot fails before it is billed.
- Check an Ideogram 4.5 edit left the rest of the image alone (Python)
Diff the source and the Ideogram 4.5 edit with Pillow, count changed pixels outside your text box, and fail the pass before it enters a chain. Code included.
- Check one video model first: GET /v1/video-router/models/{id}
Before you spend on a clip, read one model's limits with GET /v1/video-router/models/{model_id}. It returns capabilities and price, and 404s on an unknown id.
- Reference video job failed on download: check input URLs first
A Sume reference-to-video job fails when an input URL is not public. Python that HEAD-checks references before POST /v1/videos, and how to read the error.
Written by Sume