TikTokHow-to

Export a TikTok Shop seller's products to CSV with Python

A Python script that exports every product in a TikTok Shop store to CSV with price, sold count and rating: 148 products in 5 calls.

4 min read

Short answer

  • TikTok Shop's official API is built for apps that sellers install on their own shops, not for reading other sellers' catalogs.
  • ToolzerHub's TikTok Shop API pages through a seller's public catalog, 30 products a call: Dr.Melaxin's US store came to 148 products in 5 calls and 9 seconds.
  • Each call costs 2 credits, with 100 free credits a month. In that store the top 5 products held 57.5% of the sold units shown.
On this page

This script exports a TikTok Shop seller's public product catalog to CSV: one row per product with price, sold count, rating and review count. It calls ToolzerHub's TikTok Shop endpoints, which return a catalog 30 products a call. On Dr.Melaxin's US store it saved all 148 products in 5 calls.

What TikTok's API covers

TikTok Shop's official API is built for apps that sellers install on their own shops, so an app reads the shops that authorized it, not other sellers' catalogs. Our TikTok Shop API guide has the detail.

TikTok Shop products with ToolzerHub

We make ToolzerHub. The script calls our TikTok Shop endpoints, part of the TikTok API, which return public store and product data as JSON. Each call costs 2 credits. You need Python 3, requests (pip install requests), an API key from the dashboard and the seller's seller_id. Search for the brand and read it from any of its products:

bash
curl "https://api.toolzerhub.com/v2/tiktok-shop/products/search?keyword=dr%20melaxin&region=US" \
  -H "x-api-key: $TOOLZERHUB_API_KEY"

That returns 20 products, and the first 6 are Dr.Melaxin's, each with "seller_info": { "seller_id": "7495830785034323995", "shop_name": "Dr.Melaxin" }. Check shop_name before you copy a seller_id.

Export the catalog to CSV

Each call returns up to 30 products and a next_search_param; the loop sends it back as search_params until has_more is false. price is the sale_price_decimal TikTok Shop shows, and from_price is True when that price carries a "From" prefix, which products with several variants get.

python
import csv
import os
import sys
import time

import requests

URL = "https://api.toolzerhub.com/v2/tiktok-shop/seller/products"
HEADERS = {"x-api-key": os.environ["TOOLZERHUB_API_KEY"]}
FIELDS = ["product_id", "title", "price", "currency", "from_price", "sold", "rating",
          "reviews", "shop_name"]


def cell(value):
    # Spreadsheets run text that starts with = + - or @ as a formula; an apostrophe keeps it text.
    if isinstance(value, str) and value[:1] in ("=", "+", "-", "@", "\t", "\r"):
        return "'" + value
    return value


def get(params, tries=5):
    # 429 and 503 are retryable; the error body says how long to wait.
    for attempt in range(tries):
        r = requests.get(URL, headers=HEADERS, params=params, timeout=90)
        if r.status_code not in (429, 503) or attempt == tries - 1:
            r.raise_for_status()
            return r.json()["data"]
        wait = r.json().get("error", {}).get("details", {}).get("retryAfter", 5 * (attempt + 1))
        time.sleep(min(wait, 60))


def row(p):
    price = p.get("product_price_info") or {}
    rate = p.get("rate_info") or {}
    return {
        "product_id": p["product_id"],
        "title": p["title"],
        "price": price.get("sale_price_decimal"),
        "currency": price.get("currency_name"),
        "from_price": price.get("price_prefix") == "From",
        "sold": (p.get("sold_info") or {}).get("sold_count"),
        "rating": rate.get("score"),
        "reviews": rate.get("review_count"),
        "shop_name": (p.get("seller_info") or {}).get("shop_name"),
    }


def products(seller_id, region, max_pages):
    cursor = ""
    for _ in range(max_pages):
        data = get({"seller_id": seller_id, "region": region, "search_params": cursor})
        yield from data["products"]
        cursor = data.get("next_search_param")
        if not data.get("has_more") or not cursor:
            break


def main(seller_id, region="US", max_pages=50, out="products.csv"):
    seen = set()
    with open(out, "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.DictWriter(f, fieldnames=FIELDS)
        writer.writeheader()
        for p in products(seller_id, region, int(max_pages)):
            if p["product_id"] not in seen:
                seen.add(p["product_id"])
                writer.writerow({k: cell(v) for k, v in row(p).items()})
    print(f"wrote {len(seen)} products to {out}")


if __name__ == "__main__":
    main(*sys.argv[1:])

region takes US, GB, SG, MY, PH, TH, VN or ID. For one product in depth, pass product_id to /v2/tiktok-shop/product/detail for its variants, shop data and review summary. If you open the CSV in Excel, import product_id as Text: Excel keeps 15 digits of precision and these IDs have 19.

What came out

Run it with the seller ID, region, page cap and file name:

bash
export TOOLZERHUB_API_KEY=your_key
python tiktok_shop_products.py 7495830785034323995 US 50 products.csv

It printed wrote 148 products to products.csv after 8.7 seconds and 5 calls. The five products with the highest sold counts:

product (title shortened) price sold rating reviews
Calcium Multi Balm Eye Care $23.00 1,104,323 4.2 77,824
Peel Shot Glow Rice Duo $39.00 695,329 4.3 41,482
Peel Shot Keratin Care spray $27.90 679,848 4.2 48,846
Gifted Collagen Boost Set $69.00 504,916 4.5 35,717
Calcium Dark Spot Eye Cream $24.00 484,189 4.1 34,765
  • The sold counts add up to 6,037,595. The top 5 products account for 57.5% of that, and the top 10 for 73.3%.
  • Prices run from $17 to $999 (a pack of 72 dark-spot patches), with a median of $36.53. 13 products have "From" prices.
  • 145 products have a rating, with a median of 4.6. The 3 unrated products show rating 0 in the CSV, so drop them before averaging.

What it costs

Each call is 2 credits. This export was 5 calls, 10 credits, plus 2 for the search that found the seller_id. A 1,000-product store takes about 34 calls, 68 credits. You get 100 free credits a month; $19 buys 10,000 credits that never expire, and plans for higher volume cover more stores. Set your key and the first store is a CSV in under a minute.

For TikTok videos and comments instead of products, see the TikTok user videos API and TikTok comments API.

We are not affiliated with TikTok or Dr.Melaxin.

Get this data from your own code

The TikTok API returns it as JSON with one x-api-key header. 100 free credits monthly.