TikTok non-Spark ad captions: no links, @ or hashtags, lint first
TikTok's auction page says non-Spark captions allow no links, @ symbols, or hashtags; Spark Ads take 4 caption lines. Lint the text in Python before upload.

Before you paste ad text into a non-Spark TikTok ad, strip the links, the @ symbols, and the hashtags. TikTok's auction in-feed page says non-Spark captions are white text and support no clickable links, symbols such as @, or hashtags; Spark Ads instead extract the caption from the organic video, to a maximum of 4 lines (read 2026-10-07). A ten-line Python lint catches both rules.
This is about the ad's caption field in TikTok's tools, not about text burned into the video. Sume does not push ads to TikTok in the docs I read.
The two caption rules
From the auction page, which also lists .mp4, .mov, .mpeg, .3gp, up to 10 minutes, a 500 MB cap, and a 516 kbps floor for non-Spark ads.
| Ad type | Caption source | Rule |
|---|---|---|
| Spark Ads | extracted from the organic video caption | maximum 4 lines |
| Non-Spark | typed with the ad | white text; no clickable links, @ symbols, or hashtags |
A caption linter
The checker flags a URL, an @, a hashtag, or more than four lines. It flags only; it does not rewrite your copy. Note that # can legitimately appear in text like "#1 pick", which the page's hashtag rule would probably still catch, so the lint errs on the strict side.
import re
def lint_caption(text, spark=False):
problems = []
if spark:
if len(text.splitlines()) > 4:
problems.append("more than 4 lines")
return problems
if re.search(r"https?://|www\.", text):
problems.append("link")
if "@" in text:
problems.append("@ symbol")
if "#" in text:
problems.append("hashtag")
return problems
for t in ("Spring sale ends Friday", "Shop at www.example.com #sale"):
print(repr(t), lint_caption(t) or "ok")Where Sume text fits
If the words must be in the picture, video captions burns them into pixels: style values include slam, punch, and tiktok-green, a job is $0.20 for videos of 60 seconds or less, and cues let you author overlay text with no speech recognition. Burned-in text is part of the video file, so the caption field's link and hashtag rules, as written on the page, do not describe it. The page does not say anything else about it either.
Keep the legal or disclosure line out of a hashtag or a tiny overlay; that is outside this post's sources.
What this lint does not cover
The page says nothing here about length in characters, emoji, or line breaks for non-Spark text, so the lint stays silent on them. A separate post in this catalog covers character budgets from another TikTok page; check that one if you need numbers.
Run the lint on every string in the batch, not only the headline. A link buried in the third variant of a ten-ad set is exactly the thing that stalls a whole upload, and a loop over a list costs nothing.
Sources
Related posts
More in Media tools
- White backgrounds hide TikTok's ad UI: dim the clip, check for free
TikTok's reservation page warns that white or transparent backgrounds can hide the nickname and captions. Dim with video-filter ops, check first, then re-probe.
- 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.
- TikTok reservation ads must include audio: probe, then add a bed
TikTok's reservation spec says every video creative must include audio. Probe has_audio with video-inspect, then give a silent clip a voice or music spine.
- TopView says 15 seconds, reservation says 9-15: trim both for $0.04
TikTok's TopView page recommends 15 seconds and the reservation page 9-15. Cut a 9-second and a 15-second version from one master with two video-trim jobs.
Written by Sume