How to extract frames from a video with the Sume API
POST /v1/video-frames returns stills at the times you name from one Sume-hosted clip, as durable images at source size. The call is unbilled.

To extract frames from a video with Sume, send one Sume-hosted clip and either a list of timestamps (at[]) or a sampling rate (fps) to POST /v1/video-frames. Sume returns durable media.sume.com image artifacts, at the source frame size unless you set max_edge, leaves the source untouched, and does not bill the call.
The facts below are from the Video frames docs, read on 2026-09-25.
How do I extract frames from a clip?
Send video_url and exactly one of at[] or fps. The URL must be your workspace's media.sume.com artifact or asset. There is no open-internet fetch, and off-host URLs are rejected at admit, so import first with POST /v1/media-imports.
Idempotency-Key is required on MCP writes. Send it on REST too, 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: video-frames-001" \
-d '{
"video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
"at": [0, 2.5]
}'Why does the submit always return 202?
Extraction always runs asynchronously. The submit is always 202, so do not send mode: "sync" expecting a 200. The response carries request_id, which is the video_frames_id and also the job id. Poll GET /v1/video-frames/:id, or GET /v1/jobs/:id/status. There is no /v1/models/sume/…/runs alias for this tool.
On the hosted MCP server the flow is video_frames_create, then jobs_wait, then video_frames_get. Writes need idempotency_key, and mcp:write under OAuth; see Connect Claude Code, Cursor, or Codex to Sume.
What does the result contain?
When resource_status is ready, frames[{t,url,width,height}] holds durable artf_ images, and source_duration_seconds is the duration the worker probed.
- If one instant fails to extract, its
urlcomes backnull. That does not fail the job. warnings[]may includelow_confidence_long_videowhen the source is longer than 90 s. That does not fail the job either.
What are the limits?
Video frames is unbilled, in the same class as a screenshot hop: no seat, no reservation.
| Field or cap | Rule |
|---|---|
at[] | Explicit seconds: 1–24 values, each ≥ 0, and each must satisfy 0 <= t < duration. |
fps | 0 < fps ≤ 2, expanded to mid-bin samples (0.5/fps, 1.5/fps, …) and capped at 24 frames. |
format | jpeg (default) or png for lossless inspection. |
max_edge | Optional long-edge clamp, 16–2160. Omit it to keep the source size. |
| Source length | ≤ 300 s. |
| Frames per call | 24. |
Why was my frames request refused?
400(schema): bothat[]andfps, neither, more than 24atvalues,fps > 2, or avideo_urlnot onmedia.sume.com.frame_time_out_of_range: anatvalue outside[0, duration), found by the worker after the probe. The error names the probed duration.duration_out_of_range: the source is longer than 300 s.invalid_source_url: the stored job has no usablevideo_url.ffmpeg_fields_rejected: the request sentvf,filter,filter_complex,select,ffmpeg,cmd,codec,crf, orpreset. The server compiles the extract.
Should I use video frames or video inspect?
Use video frames for exact stills at times you choose, at source size. Use video inspect for whole-clip evidence: a probe, eight mid-bin stills, and an optional transcript (Video inspect API). Inspect stills default to max_edge 768; video frames omits that clamp.
Video frames does not make a new MP4. Range cuts are video trim, covered in Trim, filter, or detach audio.
Sources
Related posts
Written by Sume