Arcadium Data Scrapers
Home / Tutorials / TikTok Shop store products and sold count

TikTok Shop scraper: track a store’s products, price, stock and sold count

Sellers and brand analysts watch competing TikTok Shop stores to see which products sell, when prices drop and when stock runs out. TikTok Shop has no export, and the numbers change every day.

arcadium/tiktok-shop-products takes product, store or category URLs (US and UK) and returns one row per product: current and original price, every variant with its stock, TikTok’s sold counter, rating, shipping, promotion labels and the shop’s own stats. No login or cookies.

Cost of this example on the Apify Free plan: 15 × $0.0225 + 5 × $0.0075 = $0.375 ($0.225 on the Apify Gold plan and higher), plus $0.001 per GB of memory when the run starts.

What you need

Step 1: Run it in the Apify Store (no code)

  1. Open arcadium/tiktok-shop-products on the Apify Store and sign in (a free Apify account works).
  2. Paste the store URLs into TikTok Shop URLs or product ids, one per line.
  3. Set Max products per store or category URL, for example 20 (a store page lists its first ~20 products).
  4. Set Description to none if you only need the numbers; it keeps the rows small.
  5. Optional: set a maximum cost per run in the run options as a hard cap.
  6. Click Start. Rows appear in the Output tab; export them as JSON, CSV or Excel.

The same input as JSON (paste it in the JSON tab of the input form):

{
  "startUrls": [
    "https://www.tiktok.com/shop/store/asterwood/7495384600901552906"
  ],
  "maxProductsPerUrl": 20,
  "description": "none"
}

Step 2: Call it over the Apify API

One HTTP call runs the actor and returns its rows. It suits runs up to about five minutes; for longer runs start the run asynchronously and read the dataset when it finishes.

curl -X POST "https://api.apify.com/v2/acts/arcadium~tiktok-shop-products/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":["https://www.tiktok.com/shop/store/asterwood/7495384600901552906"],"maxProductsPerUrl":20,"description":"none"}'

Step 3: Run it from Python

With apify-client 3.x, call() returns a Run object: read the dataset id as run.default_dataset_id (older examples use run["defaultDatasetId"], which no longer works).

# pip install "apify-client>=3"
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/tiktok-shop-products").call(run_input={
    "startUrls": ["https://www.tiktok.com/shop/store/asterwood/7495384600901552906"],
    "maxProductsPerUrl": 20,
    "description": "none",
})
rows = list(client.dataset(run.default_dataset_id).iterate_items())  # apify-client 3.x

products = [r for r in rows if r.get("rowType") == "product"]
for p in sorted(products, key=lambda r: r.get("soldCount") or 0, reverse=True):
    print(p.get("soldCount"), p.get("price"), p.get("originalPrice"), p.get("totalStock"),
          p.get("detailLevel"), ", ".join(p.get("promotions") or []), p.get("title"))
for e in (r for r in rows if r.get("rowType") == "error"):
    print("could not read:", e.get("input"), e.get("code"))

Step 4: Run it from JavaScript

// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/tiktok-shop-products').call({
  "startUrls": [
    "https://www.tiktok.com/shop/store/asterwood/7495384600901552906"
  ],
  "maxProductsPerUrl": 20,
  "description": "none"
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Step 5: Ask an AI assistant (MCP)

Apify’s hosted MCP server turns the actor into one tool. Add it to Claude, Cursor, VS Code or any MCP client:

{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=arcadium/tiktok-shop-products",
      "headers": {
        "Authorization": "Bearer <APIFY_TOKEN>"
      }
    }
  }
}

Then ask, for example:

Use arcadium/tiktok-shop-products to read the products of https://www.tiktok.com/shop/store/asterwood/7495384600901552906. Rank them by soldCount and tell me which ones are discounted, in a flash sale or low on stock.

More clients and the local setup on the MCP page.

Track changes every day

Save the input as a Task in Apify Console and add a daily Schedule. Each run writes a new dataset; join the runs on productId and compare price, totalStock, soldCount and promotions to see price changes, sell-outs and new flash sales. The difference in soldCount between two days is TikTok’s own counter moving, not an exact sales figure.

Single products and categories

Product URLs (https://shop.tiktok.com/us/pdp/...) or bare product ids give one full row each; use region (US or GB) for bare ids. A category URL (https://shop.tiktok.com/us/c/<name>/<id>) gives a changing sample of the category, so repeated runs build a wider picture.

Output fields

Every row has a rowType; filter on it first. Failed inputs come back as free rows with a code and message. The fields this tutorial uses, from the actor’s dataset schema:

FieldWhat it holds
rowTypeKind of row. Filter on this first. 'product': one TikTok Shop product (charged; see detailLevel). 'error': an input could not be read; see code and message (free).
productIdTikTok Shop product id (the long number at the end of the product URL).
detailLevel'full': read from the product page (charged as 'product'). 'card': TikTok did not serve the product page to an anonymous visitor, so the row holds only what the store or category card shows: title, price, originalPrice, discountPercent, soldCount, rating, reviewCount, seller id and name, one image (charged as 'product-card'; the other fields are null or empty).
titleProduct title as the seller wrote it.
priceLowest current variant price (after discounts), in currency.
originalPriceLowest variant price before discounts; null when nothing is discounted.
discountPercentDiscount of the lowest price against originalPrice, in percent; null without a discount.
soldCountItems sold since the product was listed, all markets (TikTok's own counter, excluding returns).
ratingAverage product rating, 1 to 5; null without reviews.
reviewCountNumber of product reviews.
variantsPurchasable variants (SKUs): skuId, options (e.g. {"Size": "1oz"}), price, originalPrice, discountPercent, stock, purchaseLimit, available.
totalStockSum of variant stock as the page states it; null when no variant states stock.
promotionsPromotion labels shown on the page, e.g. "Flash sale", "Free shipping".
sellerThe shop as a business: sellerId, name, url, rating, soldCount, productCount, reviewCount, followers, videoCount, badge (e.g. "OFFICIAL SHOP"), businessName (legal company name, only when it is clearly a company). No owner or creator account.

All fields: TikTok Shop Scraper guide.

Cost per run

Pay per event: you pay for the rows delivered, at the actor’s live Apify price on 2026-11-02. Error, coverage and summary rows are free.

WhatRowsPrice per row (Free plan)Subtotal
Product: 1 store, products read from their own page15$0.0225$0.3375
Product card: products TikTok does not open anonymously (card data)5$0.0075$0.0375

Cost of this example on the Apify Free plan: 15 × $0.0225 + 5 × $0.0075 = $0.375 ($0.225 on the Apify Gold plan and higher), plus $0.001 per GB of memory when the run starts. Higher Apify plans pay less per row. The Store page always has the current price.

Limitations

Links