video_inspect: fps 2 and a 24-still cap cover only 12 seconds
At fps 2 video_inspect's 24-still cap covers 12 seconds. Pick fps or explicit at[] times by clip length; a table of coverage from 12 s to 96 s per call.

The highest sample rate, fps 2, covers only 12 seconds before it hits video_inspect's limit of 24 stills per call. Coverage is 24 divided by fps: 48 seconds at fps 0.5, 24 at fps 1. For a long clip, send explicit at[] times, or split the clip's range across calls.
The rules
The frames object takes exactly one of at[] or fps. fps must be above 0 and at most 2, sampling mid-bin, with the 24-still limit. at[] takes 1 to 24 timestamps, each 0 or more, and a time past the end of the clip returns frame_time_out_of_range with the duration. Sending both returns video_inspect_frames_program_conflict, and an object with neither returns video_inspect_frames_program_required. If you send no frames at all, you get 8 mid-bin stills, or 1 per second if the clip is shorter than 8 seconds.
Coverage by sample rate
The numbers below are 24 divided by fps, computed 2026-10-05, and describe the maximum span a single call can cover with an even program.
| fps | Seconds between stills | Span at 24 stills |
|---|---|---|
| 2 | 0.5 | 12 s |
| 1 | 1 | 24 s |
| 0.5 | 2 | 48 s |
| 0.25 | 4 | 96 s |
| 0.1 | 10 | 240 s |
What to do for a long clip
A 5-minute clip at 24 stills is one every 12.5 seconds, which is fps 0.08. That is a skim, not a read. If you need detail, choose where to look: use a transcript to find the moments, then pass those instants as at[], or run several calls with a different fps for each window. A 30-minute file can still be inspected, since the source limit is 1,800 seconds, but 24 stills are 75 seconds apart at an even spread.
Picking fps for a short clip
For a 10-second ad, fps 2 gives about 20 stills, inside the cap, and you see a new frame every half second. For a 30-second ad, fps 0.5 gives 15 stills; fps 1 would ask for 30 and exceed the limit. Work backward from the clip: divide 24 by its length in seconds, and use that as your upper bound on fps. For 20 seconds that is 1.2, so fps 1 fits. For 40 seconds it is 0.6, so fps 0.5 fits.
Round down, since a rate that asks for more than 24 stills will hit the cap. If you are unsure, use at[] and name each instant yourself; it is the one program whose output you can predict exactly.
Size and format
max_edge runs from 64 to 2160 and defaults to 768, with jpeg by default and png available. For on-screen text, raise the edge or ask for the source edge. For a contact sheet that a model will read, 768 is usually enough. Smaller stills are quicker to send to a model, which matters when you pass 24 at once. Keep the program in your request log, so you can say later exactly which seconds were sampled and which were not.
Sources
Related posts
More in Developers
- Video job statuses: pending, cancelled vs Sume's five job states
A /v1/videos job says pending or in_progress; /v1/jobs/{id}/status says queued or processing. Here is the mapping, which one to poll, and the spelling trap.
- Video model fallback chain in Python with one key per model
A Python chain that tries Gemini Omni, Wan 3.0 and Seedance 2 on Sume in order, stops on 401 or 402, and uses a separate idempotency key for each model.
- 'Video Router generate requires a catalog model id': the fix
The model must be an id from the catalog or an Auto alias. Provider names, vendor slugs and marketing names fail. List valid ids from /v1/videos/models first.
- wait_timeout_seconds 30 is not a 30-second video
The 30 in wait_timeout_seconds is how long your HTTP request may block, not how long a clip may run. A 30-second video job still needs a poll or webhook.
Written by Sume