Validate a cut list against video-trim's rules before you submit
Video trim has no unbilled check endpoint, so mirror its rules locally: 1800 s source, 0.2 s to 900 s output, one of end or duration, exact with output.

Video filter has a free /check endpoint; video trim does not, so a bad cut list fails after the request is made. Mirror the documented rules in a local function: the source must be 1800 s or shorter, the output between 0.2 s and 900 s, exactly one of end or duration must be sent, and output conforming needs precision: "exact". A cut list with 30 ranges then fails on your machine, not at $0.02 a range.
The rules, as codes
Each rule maps to a stable refusal code in the docs, which makes a local validator easy to test against the real API response.
| Rule | Limit | Code |
|---|---|---|
| Neither end nor duration | one is required | video_trim_range_required |
| Both end and duration | only one allowed | video_trim_range_conflict |
| end <= start, or output > 900 s | 0.2 s to 900 s | video_trim_range_empty |
| output with keyframe | exact only | video_trim_output_requires_exact |
| Source longer than 1800 s | checked by the worker | source_duration_exceeded |
A local check
Note the documented behavior at the end of the clip: an end past the source end clamps and the result carries the warning trim_clamped_to_source, so it is not an error. The sample's third range therefore passes; the second is a 0.1 s sliver that your validator should reject before sending.
def check(start, end, source_s, keyframe=False, output=None):
"""Return the stable video-trim code this request would hit, or None."""
if source_s > 1800:
return "source_duration_exceeded"
if end is None:
return "video_trim_range_required"
if end <= start or end - start > 900:
return "video_trim_range_empty"
if end - start < 0.2:
return "output under 0.2 s (schema)"
if keyframe and output:
return "video_trim_output_requires_exact"
return None # end > source_s only clamps, with trim_clamped_to_source
cuts = [(1.84, 9.1), (9.5, 9.6), (12.0, 1000.0)]
for s, e in cuts:
print((s, e), check(s, e, 42.0))Limits of a local check
- Worker-side codes (
source_not_found,unsupported_media_type,source_duration_exceeded) depend on the real file, so a local function only needs your probe duration. - Treat the validator as a guard rail, not the contract; confirm against the docs when limits change.
- Send an
Idempotency-Keyper trim so a retry does not queue a second billed job.
Sources
Related posts
More in Developers
- VEED Fabric audio must be under 10 MB: stereo wav tops out near 56 s
Sume lists VEED Fabric 1.0 audio as Sume-hosted, under 10 MB, at most 300 seconds. A 44.1 kHz stereo wav hits 10 MB near 56 seconds; a 128 kbps mp3 never does.
- Fabric request: image_url and avatar_handle together are not allowed
Sume's VEED Fabric 1.0 body needs exactly one visual source: image_url or avatar_id / avatar_handle, never two. Valid bodies and audio rules.
- Veo 3.1 preview ends October 22: what to change in each request
Google retires three Veo 3.1 preview ids on October 22, 2026 and names Omni as the replacement. A field-by-field list of what changes, and the Sume id to send.
- Vercel AI SDK chunkMs timeouts and a 55 s Sume jobs_wait
ai@7.0.136 stops chunkMs and firstChunkMs when the model response ends. stepMs still covers the step, so size it for a Sume jobs_wait slice of up to 55 s.
Written by Sume