video-filter unsupported_filter_op_field: crop and dim keys allowed
A crop op takes four fractions and dim takes one amount; any extra key returns unsupported_filter_op_field. The exact key lists and where the extra work goes.

Sume video filter validates each entry in ops[] against a closed key list. A dim op may carry only op and amount. A crop op may carry only op, x, y, width and height. Add a sixth key to a crop, or a second to a dim, and the request fails with unsupported_filter_op_field. A different op name, such as scale or blur, fails with the sibling code unsupported_filter_op.
Keys that look reasonable and are refused
Most of these come from habits learned on other APIs. Each one is a plain refusal, not a silent ignore, so nothing renders with a half-applied program.
{"op":"crop","aspect":"9:16"}has nox,y,widthorheight, andaspectis not a key. Compute the width fraction yourself.{"op":"crop","width":607,"height":1080,...}uses pixels. The crop fields are fractions of the source frame:xandyin [0, 1],widthandheightin [0.05, 1].{"op":"crop","gravity":"center"}has no gravity. Centre it withx = (1 - width) / 2.{"op":"dim","amount":0.45,"fade":true}carries a second key. Dim darkens the whole clip evenly.{"op":"scale","width":1080}is the wrong op name. Resizing goes infiltergraph, wherescaleis allowlisted.
Where the extra work goes
Ops are for the two operations that are easy to get wrong in raw ffmpeg: a range-aware luma multiply for dim, and a crop expressed as fractions so you never need to know the pixel size. The compiler rounds crop sides and offsets down to even values for yuv420p. Everything else is a filtergraph, which Sume applies after ops[].
| You want | Put it in | Limit |
|---|---|---|
| Darken the clip | ops[] dim, amount in (0, 1] | 8 ops in total |
| Cut a rectangle | ops[] crop, four fractions | sides at least 0.05 |
| Resize to 1080x1920 | filtergraph scale=1080:1920 | 2048 characters, 32 filters |
| Blur, flip, fade, tone | filtergraph | allowlisted names only |
| Burn words onto the picture | video captions, not this route | drawtext is not allowed |
A body that passes
Crop the middle of a 16:9 frame to a vertical strip, then scale. The ops run first and the graph second, so the scale sees the cropped frame.
{
"video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
"ops": [
{ "op": "crop", "x": 0.3418, "y": 0, "width": 0.3164, "height": 1 }
],
"filtergraph": "scale=1080:1920"
}Catch it before it costs anything
Send the same body to POST /v1/video-filter/check. It runs the schema, op whitelist and graph allowlist and returns fix_program_and_recheck as next_action when something is off. The source must still be a media.sume.com clip from your workspace, because the check also does the host preflight.
Sources
Related posts
More in Media tools
- video-frames returned a null url: the job succeeded, one frame failed
If one instant fails to extract, video-frames sets that frame's url to null and the job still completes. How to detect it and retry only that time.
- video-inspect frames: at[] and fps together is a 400, pick one
video-inspect and video-frames take a list of times or a sample rate, never both. The codes, the 24-still cap, the fps 2 ceiling, and the empty object.
- Inspect a 3-minute Short with a transcript: set duration_seconds 180
video-inspect reserves one minute of speech-to-text unless you send duration_seconds (max 600). Why a 180 hint matters, the $0.01 per minute rate, and the 400s.
- Source too long? The 1800 s and 300 s caps for each Sume media tool
Trim, detach and inspect take sources up to 1800 s; filter, frames and compose stop at 300 s. The error each returns and the order to cut a long file.
Written by Sume