Reverse a video by API: FFmpeg reverse is not on Sume's allowlist
FFmpeg's reverse filter buffers a whole clip. Sume's video-filter allowlist has no reverse and no setpts, and the free check shows it. What to do instead.

Sume cannot play a clip backwards. FFmpeg does it with the reverse filter, but reverse is not on the filtergraph allowlist of POST /v1/video-filter, so the free check call returns invalid_filtergraph. Neither video trim nor Timeline 1.0 has a direction or speed field. Reverse the clip with your own FFmpeg, import it, and carry on with trim, filters and Timeline from there.
What does FFmpeg's reverse filter do?
The FFmpeg filters documentation says the filter reverses a video clip, warns that it needs memory to buffer the entire clip, and suggests trimming first. Its example takes the first 5 seconds and reverses them with trim=end=5,reverse.
That memory cost is a good reason a hosted allowlist would think twice about it. The Sume filter list is built from filters that take only inline options, and a clip is bounded at 300 s for this endpoint.
| Filter | What FFmpeg documents | On Sume video-filter |
|---|---|---|
| reverse | Reverses a clip; buffers all of it in memory | Not on the allowlist |
| setpts | Changes frame timestamps (fast or slow motion) | Not on the allowlist |
| trim | Keeps a range of frames | Not on the allowlist; use video trim |
| fps | Frame-rate conversion | On the allowlist |
How do I confirm it without paying?
The check endpoint runs the allowlist and returns diagnostics instead of a 400. Per the Video filter page, invalid_filtergraph covers an unknown filter, and the unknown_filter diagnostic names the token and the allowlist. It does not create a job or reserve credits.
Send "filtergraph": "reverse" as below and read diagnostics and next_action. Expect valid: false and fix_program_and_recheck.
curl -X POST https://api.sume.com/v1/video-filter/check \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
"filtergraph": "reverse"
}'What can I do on Sume instead?
Reorder rather than reverse. Cut the clip into segments with video trim and place the segments in any order in a Timeline 1.0 document: a countdown or a before-and-after reveal usually needs the order flipped, not the frames. A trim is $0.02 per job and a Timeline render is $0.10 per ceil(output minute), per those pages.
For true reverse playback or a speed change, run FFmpeg yourself on a short clip, import the result with POST /v1/media-imports, and use the same hosted calls afterwards. Client-supplied vf, filter, ffmpeg or cmd fields are refused with ffmpeg_fields_rejected on every one of these endpoints.
Why does the allowlist matter?
The server compiles the ffmpeg command from your structured program. A closed list of filters, each with validated options, keeps a hosted job predictable in memory, time and cost. It also removes a whole class of injection problems, which is why raw filter strings and flags are refused.
When a filter you rely on is missing, the check call is the quickest way to find out, since it costs nothing and answers with the exact token that failed. Treat the list on the Video filter page as the source of truth and re-read it when you plan a pipeline, because it is the contract the API enforces.
What does a safe workaround pipeline look like?
Run ffmpeg -i in.mp4 -vf reverse -af areverse out.mp4 on a short clip in your own environment, as the FFmpeg documentation recommends keeping reversed clips short, then import the result and continue on Sume. Keep that step upstream of the hosted calls, so the files you submit are ordinary video that passes the preflight.
Everything after the import is the same as for any clip: inspect it, trim it, filter it, and place it in a Timeline. The pipeline stays reproducible because each hosted step is a structured request with an Idempotency-Key.
Sources
Related posts
More in Developers
- Verify a Sume webhook in Ruby with OpenSSL, no Rack or Rails
A plain Ruby verifier for Sume's sume-v1 HMAC header: OpenSSL::HMAC, a constant-time compare that works on old Rubies, a 300 second window and a self-test.
- Run an OpenRouter video script on Sume: four changes (Python)
Sume's /v1/videos copies OpenRouter's video wire. Port a polling script by changing the base URL and model id, then dropping seed, size and provider options.
- Sume run webhook 3xx redirect: a failed attempt, not a delivery
Sume does not follow redirects on run webhooks, so a trailing-slash 301 fails every attempt. How to find it with a no-follow probe and register the final URL.
- reqwest timeout versus read_timeout for Sume polls and downloads
reqwest has no timeout by default. timeout() is a total deadline including the body; read_timeout() resets per read. Which to use for Sume status polls.
Written by Sume