Poster frame at 2.5 seconds: video-frames returns source-size stills
Sume POST /v1/video-frames extracts up to 24 exact stills at source size. Always async (202); a failed instant gives a null url and the job still succeeds.

To pull a poster frame from a video with Sume, call POST /v1/video-frames with video_url and at: [2.5]. It always returns 202, then you poll and read frames[{t,url,width,height}] as durable images on media.sume.com. Unlike video inspect, frames keep the source size unless you set max_edge.
Request
Send video_url plus exactly one of at[] (1 to 24 timestamps, each 0 or more) or fps (above 0, up to 2, mid-bin samples, limit 24). Optional format is jpeg (default) or png for lossless; max_edge is 16 to 2160. Add an Idempotency-Key so a retry does not queue a second extract.
curl -X POST https://api.sume.com/v1/video-frames \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: poster-001" \
-d '{
"video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
"at": [2.5],
"format": "png"
}'Always async
The submit pins async mode. Do not send mode: "sync"; it will not give you a 200. The resource ID is the job ID, so GET /v1/video-frames/{id} returns the object, with resource_status: ready when frames are available. There is no /v1/models/sume/.../runs alias for this family.
Frames versus inspect
| Question | video-frames | video-inspect |
|---|---|---|
| Default size | Source size | max_edge 768 |
| Source limit | 300 seconds | 1800 seconds |
| Stills per call | 24 | 24 |
| Returns probe and transcript | No | Yes (transcript optional) |
| Default mode | async only (202) | sync, 30 s wait |
Choosing the timestamp
A poster at 2.5 seconds is arbitrary; the point is that you choose the instant. Pull a handful at once, for example at: [0.5, 2.5, 5, 7.5], and keep the best. One job can return up to 24 frames, so four candidates cost the same single job as one. Use png if a downstream step will compress the image again, and jpeg for the final delivery.
If you want a smaller file, set max_edge, which clamps the long edge between 16 and 2160 pixels. If you omit it the frames keep the source size, which is what you want for a restage or a cover image.
Polling loop
After the 202, poll GET /v1/video-frames/{id} until resource_status is ready. Because the job is billed by Modal compute with a hold taken at submit, a frame request on a 300-second source holds the compute ceiling until it finishes, and the charge is never more than the hold. Keep source clips short when you only need a poster; the limit is 300 seconds, and the same job on a 30-second clip finishes sooner.
A cheap pattern is to extract four to eight candidates in one job, show them to a person or a scoring step, and keep one url. The other frames are durable media.sume.com images and can be discarded without cleanup on your side.
Failure handling
If one instant fails to extract, that frame has url: null, and the job does not fail, so check each entry before using it. An at value outside [0, duration) fails the worker with frame_time_out_of_range and tells you the probed duration, and a source over 300 seconds fails with duration_out_of_range. Clips over 90 seconds may carry a low_confidence_long_video warning, which is not a failure. Billing is the same as inspect: Modal container seconds at list times 1.25 plus the platform fee, capped at the hold, with no admission seat used.
Sources
Related posts
More in Media tools
- Is a 4:5 video a YouTube Short? 1080x1350 fits square or vertical
YouTube's Shorts page says square or vertical, up to three minutes. 4:5 is vertical, though not named. A 170-second 1080x1350 Timeline render costs $0.30.
- Keep 0.24 s of breath: shorten pauses instead of deleting them
Pad each kept range by 0.12 s per side and 9 pauses totalling 6.35 s lose 4.19 s, not 6.35 s. The speech keeps a 0.24 s breath at every join.
- Does Kling motion control follow my prompt? Only for appearance
On Sume's Kling 3.0 Motion Control the optional prompt (up to 2,000 characters) steers appearance only; motion and framing follow the driving video.
- Korean captions: slam returns 400, so use korean-ad with language ko
Latin caption styles have no Hangul glyphs, so Korean text on slam, punch or tiktok-green returns 400 caption_hangul_text_latin_style. Use korean-ad.
Written by Sume