π¦ TikTok Shop Data Scraper: SKUs, Stock & Pricing
Pricing
from $5.99 / 1,000 results
π¦ TikTok Shop Data Scraper: SKUs, Stock & Pricing
ποΈ TikTok Shop Data Scraper extracts product & seller details from TikTok Shop fastβprices, listings, ratings, categories & more. π Perfect for market research, competitor tracking & lead generation. π Save time, scale insights.
Pricing
from $5.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
2 days ago
Last modified
Categories
Share
TikTok Shop Scraper β Extract Products, SKUs, Stock & Pricing
This TikTok Shop scraper collects product listings by keyword, category link, seller-store link, or direct product URL, and returns a full per-SKU variant breakdown β size, color and width, each with its own real price, stock level and GTIN β alongside ratings, reviews, seller info, sold counts and top affiliate creators. Every response is structured JSON, ready to pass directly to an LLM, load into a spreadsheet, or feed a pricing/inventory pipeline. Start with a keyword or a link, and get catalog-grade product data back in minutes.
π§ What is TikTok Shop Data Scraper: SKUs, Stock & Pricing?
TikTok Shop Data Scraper: SKUs, Stock & Pricing queries the public TikTok Shop storefront β by search keyword, category page, seller store, or a specific product page β and returns one JSON record per product, each carrying a full skus variant table instead of a single blended price and stock number. That per-SKU table (size/color/width, per-variant price, real stock, GTIN) is the field competing product scrapers typically collapse into one row; here it's a first-class part of every record. No TikTok account or login is required β the Actor reads the same public pages a shopper's browser would load.
- π Search the TikTok Shop catalog by one or more keywords
- ποΈ Browse a category by pasting its
/c/link - πͺ Pull a seller's entire store catalog from its
/store/link - π Target individual products directly via their
/pdp/link - π§© Get every SKU's size/color/width, price and real stock in its own table, plus GTIN
- π΅ Filter by
minPrice/maxPriceandinStockOnlybefore you ever pay for a detail fetch
π What data can you get with TikTok Shop Data Scraper: SKUs, Stock & Pricing?
The Actor returns four result types per run β product core data, per-SKU variant records, aggregated affiliate-creator stats, and (optionally) reviews.
| Result Type | Extracted Fields | Primary Use Case |
|---|---|---|
| Product core data | product_id, title, url, price, price_formatted, currency, original_price, discount, rating, review_count, seller_id, seller_name, image_url, sold_count, is_sold_out, in_stock, stock_quantity, sku_count, source | Catalog research, price and stock monitoring |
SKU / variant records (skus[]) | sku_id, sku_name, properties (e.g. Size/Color/Width), price, price_formatted, currency, original_price, discount, in_stock, stock_quantity, gtin_code, gtin_type | Per-variant inventory feeds, repricing tools |
Top affiliate creators (top_creators[]) | nickname, video_count, total_plays, total_likes, is_affiliate, plus creator_count / has_creator_data / total_creator_videos on the product | Affiliate and influencer sourcing |
Reviews (reviews[], optional) | review_id, rating, text, reviewer_name, review_time, is_verified_purchase, sku_specification, country, images, plus reviews_fetched / reviews_accessible | Reputation and buyer-sentiment monitoring |
π§© Full per-SKU variant table with real stock and GTIN
Most product data on a TikTok Shop listing card is a single blended price and a single stock flag. This Actor instead fetches each product's detail page and parses product_model.skus in full, joining each SKU against its own entry in promotion_model.promotion_product_price.skus_price for a genuinely per-variant price. Stock is computed per SKU from sku_quantity.available_quantity (falling back to sku_stock_status only when quantity isn't present) β never a hardcoded guess, and left null rather than faked when TikTok's own payload carries no stock signal at all. A typical SKU record:
{"sku_id": "1729496285843854726","sku_name": "IG9606_6.5_M","properties": { "Size": "6.5", "Color": "Black", "Width": "M" },"price": 64.99,"price_formatted": "64.99","currency": "USD","original_price": 229.99,"discount": "72%","in_stock": true,"stock_quantity": 374,"gtin_code": "195749608799","gtin_type": 3}
π₯ Top affiliate creators per product
Each product's related-video feed is aggregated into the five creators with the most videos on that product (ties broken by total likes): nickname, video_count, total_plays, total_likes, and is_affiliate β set when TikTok's own UI labels the video as commission-earning. This is a best-effort, secondary fetch; a product can legitimately have zero creators (has_creator_data: false) if no affiliate videos are attached to it.
π€ Why not build this yourself?
TikTok Shop's Partner/Open API is seller-gated β it requires a Partner Center account, a registered app and OAuth scopes, and it only reads shops you own or are authorized on. It is a seller-integration tool, not a public marketplace-wide product-search API, as documented on TikTok Shop's own partner developer portal (checked 2026-08-04).
Building this yourself means reverse-engineering and maintaining three moving targets: the __MODERN_ROUTER_DATA__ payload embedded in every PDP page, the brandy_desktop listing endpoint used for search/store/category discovery, and the pdp_desktop page_data/review endpoints β none of which are documented, versioned, or guaranteed stable. On top of that, TikTok Shop only serves real product data to US exit IPs, so a workable scraper also needs a proxy strategy: try direct, escalate to a datacenter proxy, and fall back to a sticky residential session when both are blocked β plus retry and soft-fail detection to tell an anti-bot interstitial apart from a real 200 response. This Actor implements that ladder, the parsing, and the per-SKU price/stock joins already, so you query it and get structured JSON back instead of maintaining a scraper against an undocumented internal API.
π What is the difference between a TikTok Shop product scraper and a TikTok Shop SKU scraper?
A product scraper returns one row per listing with a single price and a single stock flag β fine for a title/price/rating catalog, but useless for deciding whether the specific size or color a buyer wants is actually in stock. A SKU (or variant) scraper goes one level deeper and returns one record per sellable variant β each with its own price, its own stock quantity, and its own GTIN β because on TikTok Shop, price and stock are set per SKU, not per product; a product can be "in stock" overall while the exact size a shopper needs is sold out.
This distinction matters for sourcing and arbitrage in particular: a blended "in stock" flag can hide the fact that only the least-popular variant remains. TikTok Shop Data Scraper: SKUs, Stock & Pricing returns both in the same run β the product-level summary (price, in_stock, stock_quantity, sku_count) and the full variant breakdown in skus[] β so you never have to choose between catalog-level and variant-level data.
π§ How to scrape TikTok Shop with TikTok Shop Data Scraper: SKUs, Stock & Pricing?
- Open TikTok Shop Data Scraper: SKUs, Stock & Pricing on its Apify Store listing and click Try for free (or Start) β no separate signup, just an Apify account.
- Enter one or more
searchKeywords(e.g."shoes") and/or paste TikTok Shopurlsβ product, category, or seller-store links are all auto-detected. - Set the query controls you need:
maxProductsper source,minPrice/maxPrice,inStockOnly,includeReviews+maxReviews, andsortBySoldCount. - Click Start and watch the run log β each product is pushed to the dataset the instant it's collected.
- Open the Output/Storage tab, switch between the Products, SKUs & Stock, Top Creators and Reviews views, and export as JSON, CSV, or XLSX.
Example request body:
{"searchKeywords": ["shoes"],"maxProducts": 30,"minPrice": 20,"maxPrice": 80,"inStockOnly": true,"includeReviews": true}
Running multiple keywords, categories and stores in one job
searchKeywords and urls are both arrays β mix keywords, category links, and seller-store links in a single run, and each source is discovered independently before its products are fetched. maxProducts applies per source (per keyword, per category, per store), not to the run as a whole. Concurrency across all of these product-detail fetches is governed by maxConcurrency (1β20, default 20), a documented, configurable input β not a fixed internal value.
β¬οΈ Input
All fields are optional, but you need at least one searchKeywords entry or one urls entry β a run with neither logs a warning and exits with nothing scraped.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
searchKeywords | No | array | Keywords to search TikTok Shop for. Each keyword runs its own search. | ["shoes", "phone case"] |
urls | No | array | TikTok Shop URLs β product (/pdp/), category (/c/), or seller/store (/store/); type is auto-detected. | ["https://shop.tiktok.com/us/pdp/123"] |
maxProducts | No | integer | Max products to fetch per keyword / category / seller. Min 10, max 100000, default 10. | 50 |
includeReviews | No | boolean | Fetch product reviews too. Not every product exposes accessible reviews. Default false. | true |
maxReviews | No | integer | Max reviews to fetch per product. Min 1, max 100, default 10. | 20 |
sortBySoldCount | No | string | none / highest_first / lowest_first. Only controls an extra sorted-order snapshot saved to the key-value store at the end of the run β the live dataset push order is unaffected. Default none. | "highest_first" |
minPrice | No | integer | Only collect products priced at or above this amount, applied at discovery time. No minimum. | 20 |
maxPrice | No | integer | Only collect products priced at or below this amount, applied at discovery time. No minimum. | 80 |
inStockOnly | No | boolean | Keep only products with confirmed real stock; unknown stock status is excluded too. Default false. | true |
maxRetries | No | integer | Max retry attempts per request before giving up. Min 1, max 10, default 5. | 5 |
requestDelay | No | integer | Delay between requests, in milliseconds. Lower = faster, may trigger rate limits. Min 0, max 2000, default 0. | 250 |
maxConcurrency | No | integer | Max concurrent requests. Min 1, max 20, default 20. | 10 |
timeout | No | integer | Per-request timeout, in seconds. Min 10, max 300, default 60. | 60 |
proxyConfiguration | No | object | Proxy settings. Default {"useApifyProxy": false} β direct connection, auto-escalating to Datacenter then Residential (US). | {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]} |
Example JSON input
{"searchKeywords": ["shoes"],"urls": [],"maxProducts": 30,"includeReviews": true,"maxReviews": 10,"sortBySoldCount": "highest_first","minPrice": 20,"maxPrice": 80,"inStockOnly": true,"maxRetries": 5,"requestDelay": 0,"maxConcurrency": 20,"timeout": 60,"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
Common pitfall: maxProducts has a minimum of 10 β you cannot ask for fewer than 10 products per source, even for a single test keyword. And urls entries must match https://shop.tiktok.com/...; a bare seller handle or a shortened link that doesn't resolve to a /pdp/, /c/, or /store/ path is skipped with a warning rather than guessed at.
β¬οΈ Output
Each product is one typed, normalized JSON record with a consistent schema across runs β pushed to the Apify dataset live, as soon as it's collected. Export the dataset as JSON, CSV, XLSX, or via the API at any time; the Console also exposes four ready-made views built from the same fields: π Products, π§© SKUs & Stock, π₯ Top Creators, and π Reviews.
Scraped results
[{"product_id": "1729496283565954438","title": "Women's High-Top Sneakers - Retro Basketball Shoes","url": "https://shop.tiktok.com/us/pdp/1729496283565954438","price": 64.99,"price_formatted": "64.99","currency": "USD","original_price": 229.99,"discount": "72%","rating": 4.7,"review_count": 207,"seller_id": "8652615273335460303","seller_name": "Juyu Footwear","image_url": "https://p16-oec-va.ibyteimg.com/example~tplv-obj.webp","sold_count": 2743,"is_sold_out": false,"in_stock": true,"stock_quantity": 374,"sku_count": 3,"skus": [{"sku_id": "1729496285843854726","sku_name": "IG9606_6.5_M","properties": { "Size": "6.5", "Color": "Black", "Width": "M" },"price": 64.99,"price_formatted": "64.99","currency": "USD","original_price": 229.99,"discount": "72%","in_stock": true,"stock_quantity": 374,"gtin_code": "195749608799","gtin_type": 3},{"sku_id": "1729496285843854727","sku_name": "IG9606_7_M","properties": { "Size": "7", "Color": "Black", "Width": "M" },"price": 64.99,"price_formatted": "64.99","currency": "USD","in_stock": false,"stock_quantity": 0,"gtin_code": "195749608806","gtin_type": 3}],"creator_count": 16,"has_creator_data": true,"total_creator_videos": 20,"top_creators": [{ "nickname": "Vincent", "video_count": 2, "total_plays": 336691, "total_likes": 1275, "is_affiliate": true }],"reviews_fetched": 3,"reviews_accessible": true,"reviews": [{"review_id": "7291234567890123456","rating": 5,"text": "True to size, arrived fast.","reviewer_name": "A**a S**t","review_time": 1780350129,"is_verified_purchase": true,"sku_specification": "Black, EU41","country": "US","images": ["https://p16-oec-va.ibyteimg.com/review-example.webp"]}],"scraped_at": "2026-08-02T16:44:25.875921","source": "product_page"},{"product_id": "1730112298765430912","title": "Anti-Slip Kitchen Mat Set (2-Piece)","url": "https://shop.tiktok.com/us/pdp/1730112298765430912","price": 19.99,"price_formatted": "19.99","currency": "USD","rating": 4.3,"review_count": 58,"seller_id": "7345981022334455667","seller_name": "HomeCozy Living","image_url": "https://p16-oec-va.ibyteimg.com/mat-example.webp","sold_count": 412,"is_sold_out": false,"in_stock": true,"stock_quantity": 89,"sku_count": 1,"skus": [{"sku_id": "1730112299001122334","sku_name": "GRAY_STD","properties": { "Color": "Gray" },"price": 19.99,"price_formatted": "19.99","currency": "USD","in_stock": true,"stock_quantity": 89,"gtin_code": null,"gtin_type": null}],"creator_count": 0,"has_creator_data": false,"total_creator_videos": 0,"reviews_fetched": 0,"reviews_accessible": false,"scraped_at": "2026-08-02T16:45:03.221410","source": "product_page"},{"product_id": "1728890011223344556","title": "Wireless Earbuds with Charging Case","url": "https://shop.tiktok.com/us/pdp/1728890011223344556","price": 34.5,"price_formatted": "34.50","currency": "USD","rating": 4.5,"review_count": 1204,"seller_id": "9012233445566778899","seller_name": "AudioNext","image_url": "https://p16-oec-va.ibyteimg.com/earbuds-example.webp","sold_count": 8760,"is_sold_out": null,"in_stock": null,"stock_quantity": null,"sku_count": 0,"creator_count": 0,"has_creator_data": false,"total_creator_videos": 0,"reviews_fetched": 0,"reviews_accessible": false,"scraped_at": "2026-08-02T16:45:41.897233","source": "listing_card"}]
Two behaviors worth knowing before you build on this:
original_price/discountare only present on a record when the product is actually discounted β they're omitted, not set tonull, on a non-discounted product.sourcetells you which fetch produced the row."product_page"means a full detail fetch succeeded, soskus,top_creatorsandreviews(when requested) are as complete as TikTok's own page allows."listing_card"means the detail page was temporarily blocked and the Actor degraded to the real title/price/rating/seller data already captured during discovery instead of dropping the row β but a listing card never carries per-SKU data, sosku_countis0andskus/top_creators/reviewsare absent, withis_sold_out/in_stock/stock_quantityleftnullrather than guessed.
πΌ How can I use the data extracted with TikTok Shop Data Scraper: SKUs, Stock & Pricing?
- π Dropshipping and sourcing teams: check
skus[].in_stockandskus[].stock_quantityfor the exact variant you plan to list before importing it, instead of trusting one blended stock flag. - π€ AI engineers and LLM developers: an agent issues a keyword or URL query, receives structured JSON with
price,skus, andtop_creators, and passes it straight to the model as grounded context β no HTML parsing in the agent loop. - π Market researchers: compare
price,discountandsold_countacross sellers for the same keyword to track category-level pricing and best-seller shifts over time. - π§βπΌ Brand and product teams: use
top_creatorsto find affiliate creators already driving sales on comparable products, and diffskus[].price/skus[].stock_quantityagainst your own catalog for competitive gaps.
π How do you monitor SKU-level stock and pricing over time?
Monitoring here means running the same searchKeywords / urls set on a schedule and diffing the result against the previous run, rather than relying on a single snapshot. Each run's product_id and each SKU's sku_id are stable keys, so a new run's record can be matched directly against the last one you saved.
The fields worth diffing are price and stock_quantity at the product level, and skus[].price / skus[].stock_quantity / skus[].in_stock at the variant level β a variant going from in_stock: true to false, or its stock_quantity dropping toward zero, is the signal a repricing or restocking workflow actually needs, and it's invisible if you only look at the product-level summary. sold_count deltas between runs are a proxy for velocity if you're tracking which SKUs are moving.
A practical loop: run the Actor on a fixed keyword/URL set on an Apify schedule, store each run's dataset (or export it to your own database), and compare the latest run's skus[] against the prior run's by sku_id β alerting when a tracked SKU's in_stock flips or its price moves outside a threshold you set. The Actor itself doesn't diff runs for you; that comparison step happens outside it, in your own pipeline or spreadsheet.
π Integrate TikTok Shop Data Scraper: SKUs, Stock & Pricing and automate your workflow
TikTok Shop Data Scraper: SKUs, Stock & Pricing works with any language or tool that can send an HTTP request to the Apify API.
REST API with Python
import requestsTOKEN = "YOUR_APIFY_TOKEN"ACTOR = "your-username~tiktok-shop-data-scraper-skus-stock-and-pricing"url = f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items"resp = requests.post(url,headers={"Authorization": f"Bearer {TOKEN}"},json={"searchKeywords": ["shoes"], "maxProducts": 30, "inStockOnly": True},)products = resp.json()for p in products[:5]:print(p["title"], p["price"], p["sku_count"], p["in_stock"])
Scheduled monitoring and delivery
The Actor has no built-in scheduler of its own, but any saved input can be attached to an Apify schedule to run automatically (hourly, daily, or on a custom cron expression), and an Apify webhook can fire on each run's completion to push results into your own endpoint instead of polling the dataset.
βοΈ Is it legal to scrape TikTok Shop product data?
Yes β scraping publicly accessible web pages is generally lawful, and this Actor only collects what any visitor to shop.tiktok.com can already see: product listings, prices, stock, seller names, and public reviews. US courts have found that scraping publicly available data is not, by itself, unauthorized access under the CFAA (hiQ Labs, Inc. v. LinkedIn Corp., 938 F.3d 985, 9th Cir. 2019).
The data this Actor returns is fundamentally business/product data β prices, stock, SKUs, seller catalogs β so the applicable framework is TikTok's Terms of Service and database/content-rights considerations, not GDPR/CCPA, which govern personal data about identifiable individuals. The optional reviews[] field does carry a reviewer_name, but TikTok Shop itself already partially masks these on the public page (e.g. "A**a S**t"); treat them as incidental, not the purpose of a run, and avoid retaining them longer than your use case needs. Scraping for one-off monitoring or research carries a different risk profile than scraping at scale to train a model or resell the data outright. Consult your legal team for commercial use cases involving bulk data storage.
β Frequently asked questions
Does the scraper support TikTok Shop regions outside the US?
No. Every endpoint the Actor calls is pinned to the US storefront (/us/pdp/..., /us/store/...), the proxy configuration requests a US exit IP, and the startup check specifically warns if TikTok redirects with region_not_match. There is no region or locale parameter in the input schema β this Actor is US-storefront only.
What does sortBySoldCount actually change in the output?
It does not reorder or delay what's pushed to the dataset β products are always pushed live, in the order each product's fetch finishes, regardless of this setting. When set to highest_first or lowest_first, the run additionally saves a sorted list of product_ids (under the key sorted_by_sold_count) to the run's key-value store once all products are collected.
How does the scraper handle TikTok Shop's anti-bot measures?
With a proxy escalation ladder: it tries a direct connection first, escalates to a Datacenter (US) proxy if that's blocked, and falls back to a sticky Residential (US) proxy β retrying on a fresh session and climbing the ladder again β if the datacenter tier is also blocked or returns a degraded page. Once it reaches the residential tier it stays there for the rest of the run. Each request also retries up to maxRetries times (1β10, default 5) on a 403/429/5xx or a detected soft-fail (a 200 response missing the expected page data).
Does the scraper extract the full per-SKU variant table?
Yes β every full detail fetch parses product_model.skus into the skus[] array, with each entry's own price, stock_quantity, in_stock, and gtin_code/gtin_type. It's only available when the detail page fetch succeeds (source: "product_page"); if a product had to fall back to its listing-card data (source: "listing_card"), sku_count is 0 and skus is absent, because a listing card never carries per-SKU data.
How many products does the scraper return per keyword or URL?
maxProducts sets the ceiling β minimum 10, maximum 100000, default 10 β applied per keyword, per category link, and per seller-store link. The actual count can come in lower than requested if that search/store/category genuinely has fewer products, or if minPrice/maxPrice/inStockOnly filter some of them out after discovery.
Does includeReviews fetch reviews for every product?
It tries to, but not every product exposes an accessible review feed on TikTok Shop's public side β the Actor reports which is which via reviews_accessible on each record, and caps how many it fetches per product with maxReviews (1β100, default 10).
How do I monitor stock and price changes over time?
Run the same keyword/URL set on a recurring Apify schedule, and diff each run's price / stock_quantity / skus[].in_stock against the values you stored from the previous run, alerting on the deltas that matter to you β a variant going out of stock, or a price move past a threshold.
Does this scraper work with Claude, ChatGPT, and AI agent frameworks?
It's callable as a plain HTTP endpoint (via the Apify API or the apify-client SDK) from any agent framework β an agent can call it with a keyword or URL, get back structured JSON, and ground its answer in the current product/price/stock data rather than stale training data.
Do I need to provide my own proxies or a TikTok account?
No. No TikTok account or login is used anywhere in the scrape path β it reads the same public pages a browser would. Proxying is handled automatically via the direct β Datacenter β Residential escalation ladder described above; you only need to supply your Apify account/token to run the Actor, and can optionally force it to start on Residential via proxyConfiguration for maximum reliability from the first request.
π¬ Your feedback
Found a bug, or need a field this Actor doesn't return yet? Open an issue on the Actor's Issues tab in Apify Console β reports are read and factored into future updates.