TikTok catalog feed: image hosts TikTok lists, and where Sume URLs fit
TikTok's catalog page names supported and unsupported image hosts and asks for 720x1280 video. How to prepare a video_link clip with Sume trim.

TikTok's catalog page does not name media.sume.com as a supported image host, so do not assume a Sume URL will be accepted in an image_link column. The page requires image links to end in JPG or PNG, lists hosts it supports (Imgur, Imgshare.io, Photobucket, Imageshack) and hosts it does not (Google Drive, Flickr, Pinterest, 500px, Imgbb, Smugmug, Dropbox) (read 2026-10-03). The safe path is to test one product row with a Sume-hosted URL in a small upload and read TikTok's feed diagnostics before you build a full catalog on it.
The video column is easier to prepare. Here is what TikTok asks for in each field, and which parts Sume can produce.
What the catalog page specifies
The primary image_link should be at least 500 x 500 for square (1:1) carousel ads. additional_image_link accepts up to 10 image URLs in the same JPG or PNG formats, separated by commas inside double quotes. For video_link, TikTok recommends vertical 9:16, at least 720 x 1280 resolution, a bitrate of at least 516 kbps, and sound with captions included. Custom labels, custom_label_0 through custom_label_4, are limited to 100 characters (read 2026-10-03). The page gives no title or description limits.
| Field | TikTok's requirement | Who produces it |
|---|---|---|
| image_link | At least 500 x 500 for square carousel; URL ends in JPG or PNG | Your image pipeline |
| additional_image_link | Up to 10 URLs, JPG or PNG, comma-separated in quotes | Your image pipeline |
| video_link | Vertical 9:16, at least 720 x 1280, at least 516 kbps, with sound and captions | Video trim and captions |
| custom_label_0 to 4 | At most 100 characters each | Your feed builder |
| Hosting | Imgur, Imgshare.io, Photobucket, Imageshack supported; Dropbox and Google Drive not | Test before you scale |
Image rows: size, count and format
Most catalog failures are boring: an image link that does not end in .jpg or .png, a URL behind a login, or a picture smaller than 500 x 500. Before you upload a feed, run a short script over every image_link and additional_image_link value that checks the extension, fetches the first bytes and reads the width and height. Count the entries in additional_image_link too, because TikTok allows up to 10 and the commas inside the quoted string are easy to break when a URL itself contains one.
Sume's image routes return Sume-hosted artifacts and accept the formats listed on the image docs, but this post does not claim a particular size for a catalog square. If you generate a product still, ask for a square result, read its size, and confirm it is at least 500 x 500 before it goes in the feed. A white-background packshot and a lifestyle angle are separate rows in additional_image_link, not one image.
Prepare the video_link clip
Video trim can cut a product clip to a short range and set the output size, with edges from 256 to 2160, so 720 x 1280 is in range. The captions TikTok asks for are separate: video captions burns them onto a public HTTPS clip. Sume's docs do not offer a bitrate field, so the 516 kbps figure is something you measure, not request; read the probe from video inspect and compare.
The loop below creates one 720 x 1280 clip per source URL, with a stable idempotency key per product so a retry does not create a second charge for the same row. Replace the URLs with clips on media.sume.com.
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)
clips = {"sku-1001": "https://media.sume.com/artifacts/artf_demo/a.mp4",
"sku-1002": "https://media.sume.com/artifacts/artf_demo/b.mp4"}
for sku, url in clips.items():
status, res = run("/v1/video-trim", {
"video_url": url, "start": 0, "duration": 12,
"output": {"width": 720, "height": 1280, "fps": 30}}, f"catalog-video-{sku}")
print(sku, status, res and res["video_url"])
Test the hosting question yourself
Whether a particular host works is TikTok's call. Make a two-row feed, one row with a Sume media URL and one with a host from TikTok's supported list, upload it, and look at the status TikTok gives each product. The Sume media inputs page describes how Sume-hosted media is addressed; it says nothing about TikTok's catalog, so a pass here is something you observe, not something either vendor promises.
If a Sume URL is refused, keep the clip in Sume for editing and download the final file to a host TikTok accepts. Record which host passed, the date, and the product row, so the next person on the feed does not repeat the test.
Sources
Related posts
More in Integrations
- Vimeo embed captions on by default: texttrack and cc parameters
Add texttrack=en to a Vimeo embed URL to open with captions on. What cc does, when texttrack is ignored, and when a burned-in caption is the safer fix.
- VS Code --add-mcp for a remote server: add Sume with mcp.json
VS Code documents code --add-mcp only with a local command. For a remote server like Sume, put a type http entry in mcp.json and sign in with OAuth.
- VS Code Agent Host skips .vscode/mcp.json inputs: place Sume's entry
VS Code's Agent Host forwards your MCP config but drops entries that need input variables. Where to put Sume's entry and how to pass an API key without them.
- VS Code sandboxEnabled for MCP: does it cover a hosted Sume entry?
VS Code's MCP sandbox covers local stdio servers on macOS and Linux. A hosted Sume HTTP entry is outside it; scopes and spend limits are the gates.
Written by Sume