TikTok ad safe zone shrinks with caption length: place burned-in text
TikTok says the ad safe zone changes with format and caption length. How to place burned-in captions inside it with Sume's caption anchor_ratio and frames.

Yes, the TikTok ad safe zone moves, and the longer your ad caption is, the smaller it gets. TikTok's Ads Help says each key element, such as text and logos, has to sit inside the safe zone or it may be covered or cropped, and that the zone's size depends on the ad format (vertical, horizontal or square), on the caption length, and on any interactive add-on (read 2026-10-03). It does not publish one fixed pixel box on those pages, so the practical answer is to burn your own text into the part of the frame that stays clear in TikTok's preview, then check a frame before you ship.
Sume gives you the two tools for that: a caption job whose line position you can set per request, and a frame extractor to look at the result. Neither one knows TikTok's UI, so the safe zone itself still comes from TikTok's downloadable safe-zone files and its preview tool.
What TikTok actually says about the safe zone
Three statements matter. First, key elements must be inside the zone or they can be covered or cropped. Second, the zone varies by dimension, caption length and add-on. Third, TikTok recommends checking the preview tool for element placement and points to downloadable safe-zone files that differ by ad format and region (read 2026-10-03).
The caption rule feeds into the first two. On the auction in-feed page, a non-Spark ad caption shows at most four lines and is drawn in white with a uniform font, and the creative best-practices page tells advertisers to keep content visible within the UI safe zone (read 2026-10-03). A four-line caption takes room from the bottom of a vertical frame, so text you burned low in the picture is the first thing to collide with it.
| Factor | What TikTok's page says | What to do on your side |
|---|---|---|
| Format | Safe zone differs for vertical, horizontal and square | Keep a separate placement per aspect ratio |
| Caption length | Longer caption, smaller safe zone | Write the shortest ad caption that works; re-check after edits |
| Interactive add-on | Add-ons also change the zone | Leave the add-on area clear of burned-in text |
| Elements at risk | Text and logos | Burn text in the middle band, not the bottom edge |
| How to verify | Use the preview tool and safe-zone files | Pull a still and compare to the template |
Move burned-in captions with anchor_ratio
Sume's video captions endpoint burns captions onto a public HTTPS clip. Its design.placement.anchor_ratio field is the caption line's centre as a fraction of frame height, so a smaller number lifts the line toward the top and a larger one pushes it down. design is not supported on the punch and tiktok-green styles, so use slam (the Latin default) when you need to move the line.
The docs do not state a default ratio or a recommended range for TikTok, so treat the value in the sample below as a starting guess, not a rule. Pick it by comparing the output against TikTok's template, and burn a different ratio per ad if the on-platform caption lengths differ.
Check one still before you upload
After the caption job finishes, ask video frames for stills at a couple of instants where the caption is on screen. The endpoint returns durable image artifacts at the source size, so you can lay TikTok's safe-zone file over them in any image tool. Frames submit as 202, and each at value must be inside the clip's duration.
This script burns a caption at anchor_ratio 0.42 and pulls two stills. It needs SUME_API_KEY and a clip already on media.sume.com (import it first with POST /v1/media-imports).
import os, time, requests
BASE = "https://api.sume.com"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
def run(path, body, key):
r = requests.post(BASE + path, headers={**H, "Idempotency-Key": key}, json=body)
r.raise_for_status()
job = r.json()["request_id"]
while True:
s = requests.get(f"{BASE}/v1/jobs/{job}/status", headers=H).json()["status"]
if s in ("completed", "failed", "canceled"):
break
time.sleep(3)
return s, (requests.get(f"{BASE}/v1/jobs/{job}/result", headers=H).json() if s == "completed" else None)
clip = "https://media.sume.com/artifacts/artf_demo/ad.mp4"
status, res = run("/v1/video-captions", {
"video_url": clip, "style": "slam",
"design": {"placement": {"anchor_ratio": 0.42}}}, "safe-zone-cap-001")
print(status, res and res.get("video_url"))
if res:
status, frames = run("/v1/video-frames",
{"video_url": res["video_url"], "at": [1.5, 4]}, "safe-zone-frames-001")
print(status, frames)
What Sume cannot do here
Sume does not draw TikTok's caption block, interactive add-ons or the app UI over your clip, so it cannot show you where they will land. A caption job costs $0.20 for videos up to 60 seconds under the current fixed estimate (confirm in GET /v1/catalog), so decide the placement from one test render rather than iterating on the full set.
If your ad later gets a longer caption in Ads Manager, the zone shrinks and a burned-in line that fit yesterday can collide today. Keep the burned-in text short, keep it out of the bottom band, and re-run the still check whenever the caption or add-on changes.
Sources
Related posts
More in Media tools
- TikTok effect music cover 800x800: generate 1024x1024, then resize
TikTok wants an 800x800 music cover with the brand in a 260px centre circle. 800x800 is below Sume's GPT pixel minimum, so render 1024 and resize.
- TikTok branded effect music: 15 to 60 seconds, MP3 or WAV, from a clip
A TikTok branded effect official music track runs 15 seconds to one minute as MP3 or WAV. Pull that range from your own video with Sume audio detach.
- TikTok comment voice note, 60 seconds: avatar script to mp3 for $11.05
TikTok comments take voice notes up to 60 seconds, as reported. Make one from a script: a 60 s avatar job on standard ($11.04) plus an mp3 detach ($0.01).
- Pitch sizzle reel: trim three episodes and join them for $0.19
Cut a 60 second pitch reel from three finished episodes: three video-trim jobs, three audio detaches and one timeline render. Total $0.19, with the request.
Written by Sume