TikTok ad profile photo: 98x98, under 50 KB, logo in the 66px centre

TikTok in-feed ads use a 98x98 square profile photo under 50 KB, with key elements inside a 66px centre. Pull a brand still with Sume video frames and fit it.

5 min readSume
All posts

A TikTok in-feed ad profile photo is a 98 x 98 pixel square, saved as .jpg, .jpeg or .png and smaller than 50 KB, with the key element inside the centre 66 x 66 pixel area (read 2026-10-03). TikTok's TopView page lists the same photo rules and adds that the safe zone is the centre 66 px by 66 px image. The account name beside it is limited to 10 characters for Chinese, Japanese and Korean or 20 characters in other languages.

Sume does not make tiny avatars, but it can hand you the source. Pull a clean frame from your brand video with video frames, then crop and compress it on your side.

The numbers TikTok publishes

The Auction In-Feed page covers non-Spark ads. For Spark Ads, the profile photo and name come from the organic post's account, not from the form, so these limits matter when you run a non-Spark creative or a Spark Ads Push (read 2026-10-03).

Profile photo and name rules, TikTok Ads Help, read 2026-10-03
ItemRuleCheck before upload
Dimension98 x 98 px, square 1:1Image width and height
Formats.jpg, .jpeg, .pngFile extension
File sizeLess than 50 KBByte size of the saved file
Safe zoneKey element in the centre 66 x 66 pxCrop a 66 px box from the centre and look at it
Account name, CJKAt most 10 charactersLength of the name
Account name, otherAt most 20 charactersLength of the name

Get a clean source still from your video

If the logo or mascot appears in your ad, video frames can return a still at a timestamp as a durable image at the source size. Submit it with an Idempotency-Key, poll the job, and download the image. The clip must be hosted on media.sume.com; the media-inputs page explains the import step for other files. A frame is a good source because it has the same colours as the ad, but pick an instant where the logo is sharp and not mid-animation.

The script below pulls one frame, then uses Pillow to crop the centre square, resize to 98 x 98 and save a JPEG, lowering the quality until the file is under 50 KB. It also saves a 66 px centre crop so you can look at it. The frame response shape is not shown on this page, so the script prints it for you to read the image URL; set IMG to that URL.

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)

import io
from PIL import Image
status, res = run("/v1/video-frames", {"video_url": "https://media.sume.com/artifacts/artf_demo/ad.mp4", "at": [2]}, "profile-frame-001")
print(status, res)
IMG = "https://media.sume.com/artifacts/artf_demo/frame.jpg"  # paste the url from the output above
im = Image.open(io.BytesIO(requests.get(IMG).content)).convert("RGB")
s = min(im.size); l, t = (im.width - s) // 2, (im.height - s) // 2
im = im.crop((l, t, l + s, t + s)).resize((98, 98))
im.crop((16, 16, 82, 82)).save("centre-66.png")
for q in range(95, 30, -5):
    buf = io.BytesIO(); im.save(buf, "JPEG", quality=q)
    if buf.tell() < 50_000:
        open("profile.jpg", "wb").write(buf.getvalue()); print("saved", q, buf.tell()); break

Where the photo comes from in each ad type

For a Spark Ads Pull, TikTok uses the profile photo of the account that posted the video, so there is nothing to upload (read 2026-10-03). For a non-Spark ad or a Spark Ads Push, you set the identity yourself, and the 98 x 98 file is yours to prepare. That matters when you run the same clip both ways: the Pull version shows the creator's face, and the non-Spark version shows whatever you upload, so the two ads can look like different advertisers in the feed.

Keep one approved profile file per brand and reuse it across campaigns instead of cutting a new one from each video. A still from the video is a convenient starting point, but once you pick a mark, save it, so the account looks the same from one ad to the next.

Judge the result before you upload

Open centre-66.png and ask whether the brand is still readable. If a wordmark gets cut, use a simpler mark; a 98 pixel square leaves little room for text. A JPEG of that size is usually far below 50 KB, so the size rule is mostly a guard for PNGs with heavy detail. Keep the original frame and the final file together, and re-check against TikTok's page if the numbers change.

This page covers only the ad profile photo. The account name, the caption and the call to action are set in Ads Manager, not in Sume, and Sume's docs describe frame extraction and image generation, not ad profile photos.

Re-check the photo whenever the brand mark changes. A refreshed logo often has finer detail or a new colour, and a file that was under 50 KB last quarter may not be now. Keep the exported 98 x 98 file with the date you read TikTok's page, so you can tell later whether a rejection came from your file or from a change in the spec.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume