TikTok reservation ads need 2,500 kbps: compute it from the probe

TikTok's auction page asks for 516 kbps, its reservation and TopView pages for 2,500 kbps. Compute the average from video-inspect size and duration first.

5 min readSume
All posts

A file that clears TikTok's auction floor can still miss the reservation floor. The auction in-feed page lists a minimum bitrate of 516 kbps; the reservation in-feed and TopView pages list 2,500 kbps (read 2026-10-07). Sume's video-inspect probe returns size_bytes and duration_seconds, so you can compute the whole-file average in one line before you upload.

One caveat first: that average includes the audio track, and the vendor pages do not say whether their floor is measured on video alone or on the whole file. Treat your number as a screen, not a verdict.

The three floors side by side

Read from the auction page, the reservation page, and the TopView page.

TikTok video bitrate floors and limits by placement (read 2026-10-07)
PlacementMinimum bitrateDurationMax file size
Auction in-feed (non-Spark)516 kbpsup to 10 minutes500 MB
Reservation in-feed2,500 kbps5-60 s500 MB
TopView2,500 kbps5-60 s500 MB

Compute the average from a probe

POST /v1/video-inspect with frames: false returns only the probe, with no stills. The probe schema in the OpenAPI file includes duration_seconds, size_bytes, fps, width, height, and has_audio. Bitrate is not a probe field, so derive it: bytes times 8, divided by seconds, divided by 1,000. I use 1 kbps = 1,000 bits per second; the vendor pages do not define it.

The example below uses a made-up 4.5 MB, 15-second render. It averages 2,400 kbps: fine for auction, short of the reservation floor.

def avg_kbps(probe):
    return probe["size_bytes"] * 8 / probe["duration_seconds"] / 1000


probe = {"size_bytes": 4_500_000, "duration_seconds": 15.0}
kbps = avg_kbps(probe)
print(round(kbps), "kbps")
for name, floor in (("auction", 516), ("reservation", 2500)):
    print(name, "ok" if kbps >= floor else "below floor")

What you can and cannot change in Sume

Be honest about the lever. Timeline 1.0 compiles ffmpeg on the server and rejects codec, crf, and similar keys, so there is no bitrate control. What you can set is output.width, output.height (even integers, 256-2160), and output.fps. More pixels or more motion tend to raise the average, but nothing in the docs guarantees a number, so measure every render.

Probing costs little: the OpenAPI description says the probe and stills are unbilled, and transcription is the only billed part. If the average comes back low, re-render with a larger frame or busier footage and probe again.

A short routine

Run this before any reservation upload.

  • Render the master with POST /v1/timeline-1.0/render and poll the job per Jobs and results.
  • Probe the output with frames: false.
  • Compute the average; compare to 516 or 2,500 depending on the placement.
  • Check duration_seconds against the placement window (5-60 s for reservation and TopView).
  • Check size_bytes against 500 MB, a decimal assumption on my part.

When the number comes back low

A low average is common on calm footage: a static talking head compresses far better than a fast montage, so the same 15 seconds can pass for one creative and fail for another. Do not conclude that the file is bad; conclude that the placement and the footage disagree.

Your options, in order of cost: pick a placement with the lower floor (auction non-Spark at 516 kbps), re-cut with more motion in the shots, or re-render at a larger frame and measure again. Each probe is a single call, so the loop is cheap; each Timeline render is $0.10 per output minute.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume