Timeline invalid_fps 400: output.fps must be 24, 25, 30 or 60

invalid_fps rejects any output.fps outside 24, 25, 30 and 60. Omit the field to match the source frame rate; details.allowed lists the accepted values.

4 min readSume
All posts

invalid_fps is a 400 from Timeline 1.0 when output.fps is not one of 24, 25, 30 or 60. A value such as 23.976 or 29.97 fails, because the field is an enum of whole numbers. The body points at the field and lists the accepted values, and its next_action is use_supported_fps.

The error body

Sume rewrites the raw schema failure into a stable shape, so you can read it without parsing validator output.

details for invalid_fps (Sume API source and Timeline docs, read 2026-10-05)
FieldValue
messageoutput.fps must be one of: 24, 25, 30, 60.
details.fieldoutput.fps
details.receivedThe value you sent
details.allowed[24, 25, 30, 60]
details.next_actionuse_supported_fps

The better fix is to leave it out

The Timeline docs say that if you omit output.fps, the job renders at the rate of the sources: the longest video sources decide, stills have no rate, and 30 applies only when no source has a rate. Picking a rate that differs from a source makes the job repeat or drop a frame every few frames, which shows as judder, and the job reports output_fps_resamples_sources with the rate the sources wanted. So for fractional-rate footage the cleanest answer is usually no fps at all.

Pick the nearest allowed rate

If you must set one, map the source rate to the closest allowed value, and prefer the one your delivery platform expects. This runs as is:

ALLOWED = (24, 25, 30, 60)

def nearest(src_fps: float) -> int:
    return min(ALLOWED, key=lambda a: abs(a - src_fps))

for f in (23.976, 29.97, 50, 59.94):
    print(f, "->", nearest(f))

Use the free plan call first

POST /v1/timeline-1.0/plan runs the schema checks and the compiler without creating a job or reserving credits, and Idempotency-Key is not required. Send your body there first, and an invalid_fps costs you nothing. The render itself requires an Idempotency-Key.

Common sources of a bad rate

Most invalid_fps errors come from copying a number out of a probe. Phone footage often reports 29.97 or 59.94, screen recordings can report odd variable rates, and a template may hard-code 29.97 from a broadcast habit. None of these is in the enum. Read the rate from your source only to decide, not to pass through, and prefer to omit the field so that the job follows the sources.

If the clip goes to a short-form platform, 30 is a safe and common target, and 24 suits film-like footage. For a mix of sources with different rates, omitting output.fps lets the longest video source decide, which is the documented rule.

Checklist

Before you release a template: drop output.fps unless a platform needs a fixed rate; if it does, store one of 24, 25, 30 or 60; run the plan call in CI; and read the output_fps_resamples_sources note in a test render, to see whether the choice makes the job resample.

Limits

The plan call cannot predict the short-source pad or loop warnings. The full field table is in the Timeline docs; the related post covers a 23.976 fps clip in detail.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume