Generating Product Feeds for TikTok Catalog
TikTok Shop and TikTok Ads Catalog are two different products with different feed requirements. TikTok Ads Catalog is used for dynamic advertising in Video Shopping Ads and Catalog Ads format, TikTok Shop is a separate commerce platform with stricter region restrictions (available in US, UK, Southeast Asia). This guide covers TikTok Ads Catalog, available in most advertising markets.
Feed Formats
TikTok accepts:
- CSV/TSV — simplest option to start
- XML — more flexible for complex variant structures
- Google Shopping feed — TikTok can import GMC feeds directly, simplifying setup
Required TikTok Catalog Fields
| Field | Requirement |
|---|---|
sku_id |
unique identifier, string up to 50 chars |
title |
up to 255 characters |
price |
number, without currency symbol |
currency |
ISO 4217 (USD, EUR, RUB) |
availability |
in_stock / out_of_stock / preorder |
link |
product page URL, HTTPS |
image_link |
main image URL, min. 500×500 px |
condition |
new / refurbished / used |
Additional Fields for Performance
-
brand— brand. Affects relevance of audience matching -
google_product_category— TikTok uses the same taxonomy as Google -
description— up to 5000 characters; used in automatic ad copy -
sale_price+sale_price_effective_date— displayed as discount in product card -
additional_image_link— up to 10 additional images comma-separated -
video_link— link to mp4 product video (up to 30 sec) — critical for Video Shopping Ads
PHP Generator
class TikTokCatalogFeedGenerator
{
public function generate(string $outputPath): void
{
$headers = [
'sku_id', 'title', 'price', 'currency', 'availability',
'condition', 'link', 'image_link', 'additional_image_link',
'description', 'brand', 'google_product_category',
'sale_price', 'sale_price_effective_date',
'color', 'size', 'age_group', 'gender', 'material',
'video_link',
];
$fp = fopen($outputPath, 'w');
fputcsv($fp, $headers);
Product::with(['images', 'brand', 'variants', 'video'])
->active()
->chunk(500, function ($products) use ($fp, $headers) {
foreach ($products as $product) {
$rows = $product->variants->isNotEmpty()
? $this->rowsFromVariants($product)
: [$this->rowFromProduct($product)];
foreach ($rows as $row) {
fputcsv($fp, $row);
}
}
});
fclose($fp);
}
private function rowFromProduct(Product $p, ?ProductVariant $v = null): array
{
$price = $v?->price ?? $p->price;
$stock = $v?->stock ?? $p->stock;
$skuId = $v ? $p->sku . '_' . $v->sku : $p->sku;
$salePrice = '';
$saleDates = '';
if ($p->sale_price && $p->sale_ends_at?->isFuture()) {
$salePrice = number_format($p->sale_price, 2, '.', '');
$saleDates = $p->sale_starts_at->toIso8601String()
. '/' . $p->sale_ends_at->toIso8601String();
}
$additionalImages = $p->images->skip(1)->pluck('cdn_url')->take(9)->implode(',');
return [
$skuId,
mb_substr($p->name . ($v ? ' ' . $v->option_label : ''), 0, 255),
number_format($price, 2, '.', ''),
'RUB',
$stock > 0 ? 'in_stock' : 'out_of_stock',
'new',
route('products.show', $p->slug) . ($v ? '?v=' . $v->id : ''),
$p->mainImage()?->cdn_url ?? '',
$additionalImages,
mb_substr(strip_tags($p->description), 0, 5000),
$p->brand?->name ?? '',
$p->google_category_id ?? '',
$salePrice,
$saleDates,
$v?->color ?? $p->color ?? '',
$v?->size ?? '',
$p->age_group ?? 'adult',
$p->gender ?? '',
$p->material ?? '',
$p->video?->cdn_url ?? '',
];
}
private function rowsFromVariants(Product $p): array
{
return $p->variants->map(fn($v) => $this->rowFromProduct($p, $v))->toArray();
}
}
Pixel Events for Dynamic Retargeting
TikTok Pixel must pass content_id matching sku_id in catalog:
ttq.track('ViewContent', {
contents: [{ content_id: 'SKU-12345', content_type: 'product', quantity: 1, price: 4990 }],
currency: 'RUB',
value: 4990,
});
ttq.track('AddToCart', {
contents: [{ content_id: 'SKU-12345', content_type: 'product', quantity: 1, price: 4990 }],
currency: 'RUB',
value: 4990,
});
TikTok Catalog Limits
- Maximum 10M products per catalog
- Maximum feed file size — 4 GB (CSV) or 2 GB (XML)
- Images with no background (white background) show better CTR in Shopping Ads
- Feed URL must be accessible without authentication and return feed in less than 30 seconds — for large catalogs, pre-generate file instead of generating on-the-fly
Timeline
Feed generator and catalog setup in TikTok Ads Manager — 2–4 working days. If using Google Shopping feed import — 1 working day.







