TikTok Shop Product Scraper | Sold Count, Prices & Trends
Pricing
from $3.50 / 1,000 product (search result)s
TikTok Shop Product Scraper | Sold Count, Prices & Trends
All-in-one TikTok Shop (US) scraper: keyword search with sold count, price, rating and the bound TikTok video; full product pages with SKUs, stock and seller compliance; plus the shops behind the results and every sort/category filter TikTok offers. Sort by best sellers or price. No API key.
Pricing
from $3.50 / 1,000 product (search result)s
Rating
0.0
(0)
Developer
Mr Zack
Maintained by CommunityActor stats
0
Bookmarked
11
Total users
8
Monthly active users
2 days ago
Last modified
Categories
Share
TikTok Shop Scraper AIO | Products, Shops, Sold Count & Prices
Search TikTok Shop US by keyword and get every product as clean JSON — sold count, price, original price, discount %, rating, review count, shop name & seller id, verified-shop badge, brand, free-shipping / limited-time-deal labels, image, and the TikTok video bound to the listing (creator, plays, likes). Add product URLs or IDs to pull full product details: every SKU with live stock, per-SKU price, weight & dimensions, description text, all images, video count, delivery days, deal end time and the seller's registered business name & address.
No browser, no cookies, no proxies to configure. Straight from TikTok Shop's own web endpoints — $5 per 1,000 products, and with filters you only pay for the products that match.
Who uses this
- Affiliates & creators — shortlist products worth promoting:
minVerdict: "shortlist",onlyWithCreatorVideo,minRating. Every row says why inverdictReason(sold, reviews, rating, discount, creator video). Commission rates are not shown on TikTok Shop's public pages, so this Actor does not output them. - Sellers watching competitors — a scheduled watch-list (
productUrls+trackTrends) gives one freechanges-digestrow per run: who sells fastest, price drops/rises, sold-out and removed products, plusstockChangeon every detail row. - Dropshippers & product researchers — filter by demand and margin before paying (
minSoldCount,maxPrice,minSoldPerDay), then validate the niche with the freemarket-summary: price quartiles, units sold, estimated GMV, discount share, top-3 shop share and TikTok's own related searches/categories as next keywords. - Agencies & brands —
includeShopLeaderboardranks the shops that dominate a keyword (sold share, median price, rating,shopVerified);searchPositionis a product's place in TikTok's search order. - Deal hunters —
minDiscountPct,onlyDiscounted, and withtrackTrendsthelowestPriceSeen/isNewLowestPricefields and the digest's price-drop list. - Automations (Sheets, Slack, Make, Zapier) — read the
changes-digestrow'sheadlineandcountsinstead of every product.
Input
| Field | Description |
|---|---|
keywords | Searches, one per line ("air fryer"). |
maxResultsPerKeyword | Products per keyword (30/page, max 600). Default 60. With filters it counts matching products. |
productUrls | shop.tiktok.com/us/pdp/…/<id>, tiktok.com/view/product/<id> or bare 19-digit ids → detail rows. |
enrichDetails | Fetch full details for every (matching) search result (charged per detail). |
includeMarketSummary | Free aggregate row per keyword (default on). |
trackTrends | Compare with your previous run: sold velocity, price moves, rank moves, free changes-digest (default off). |
onlyChanges | With trackTrends: unchanged products are skipped and not charged. |
includeShopLeaderboard · includeShops · includeFilters | Free extra rows (see below). |
sortBy | relevance (default), best_sellers, price_asc, price_desc, newest. |
{ "keywords": ["air fryer", "led strip lights"], "maxResultsPerKeyword": 90,"productUrls": ["https://shop.tiktok.com/us/pdp/9qt-dual-air-fryer/1732304925049327689"] }
Filters — applied before charging
Products that don't match are skipped and never charged. maxResultsPerKeyword counts only matching products: the Actor keeps paging TikTok's results (up to offset 2,000, stopping after 2 pages with no new products) until it has enough. Filters apply to keyword search results; product URLs are always returned. Empty or 0 = off, so inputs written before 0.1.8 run exactly as before.
| Filter | Keeps products… |
|---|---|
minSoldCount / maxSoldCount | whose lifetime sold count is at least / at most this |
minPrice / maxPrice | priced (USD) at least / at most this |
minRating | rated at least this (products without reviews have no rating and are skipped) |
minReviewCount | with at least this many reviews |
minDiscountPct | at least this % below the strike-through price |
freeShippingOnly | with TikTok's "Free shipping" label |
onlyDiscounted | shown with a strike-through price |
onlyWithCreatorVideo | with a TikTok video bound to the listing |
minSoldPerDay | selling at least this many units/day since your last run (needs trackTrends; nothing matches on the first, baseline run) |
minVerdict | with at least this verdict: watch or shortlist |
With filters on, the free market-summary and shop-leaderboard still describe every product scanned (the market), and the summary adds matchedFilters and filters.
{ "keywords": ["air fryer"], "maxResultsPerKeyword": 20, "minSoldCount": 500, "minRating": 4.5, "freeShippingOnly": true, "onlyWithCreatorVideo": true }
Verdict (free, on every product and product-detail row)
verdict | Rule |
|---|---|
shortlist | ≥ 500 sold, ≥ 20 reviews, ≥ 4.0★ and a discount or a creator video — or, with trackTrends, ≥ 50 sold/day observed since the last run (rating ≥ 4.0★ or none yet) |
watch | ≥ 100 sold, or selling since the last run |
skip | everything else, ratings under 3.5★ with 5+ reviews, sold-out or unavailable products |
verdictReason says it in plain words, e.g. "4,350 sold · 779 reviews · 4.7★ · 29% off · creator video" or "1,139 sold · 170 reviews · 4.6★ — no discount or creator video" (real rows from an "air fryer" search).
Output
product (one per search result):
{ "type": "product", "position": 1, "searchPosition": 1, "keyword": "air fryer", "productId": "1732306737130869211","title": "6-Quart Air Fryer with Window, 12-in-1 Square Design …", "url": "https://shop.tiktok.com/us/pdp/6-quart-air-fryer-with-window/1732306737130869211","price": 59.03, "originalPrice": 81.98, "discountPct": 28, "currency": "USD", "saving": 22.95,"rating": 5, "reviewCount": 6, "soldCount": 25, "sellerId": "7496210586501679579", "shopName": "Floft", "shopVerified": false, "brand": null,"freeShipping": true, "limitedTimeDeal": true, "labels": ["Limited time deal", "Free shipping"], "skuCount": 4, "seoUpdatedAt": "2026-04-01T15:47:54.251Z","image": "https://p16-oec-general-useast5.ttcdn-us.com/…600.webp","video": { "itemId": "7648948884764462367", "authorName": "Brenda Paola", "playCount": 1500, "likeCount": 161, "durationSec": 82, "isCreatorCommission": true, "url": "https://www.tiktok.com/@_/video/7648948884764462367" },"verdict": "skip", "verdictReason": "25 sold · 5★ — little proof of demand yet" }
| New field (0.1.8) | Meaning |
|---|---|
verdict, verdictReason | free shortlist label and its reason (see above) |
shopVerified | TikTok's blue-check shop badge |
searchPosition | place in TikTok's search order among the products read (position is the place in your output after sorting and filters) |
product-detail (one per product id):
{ "type": "product-detail", "productId": "1732306737130869211", "title": "6-Quart Air Fryer with Window …", "price": 59.03, "originalPrice": 81.98, "discountPct": 28,"rating": 5, "reviewCount": 6, "soldCount": 25, "shopName": "Floft", "available": true, "freeShipping": true, "deliveryMinDays": 3, "deliveryMaxDays": 6,"description": "6 Quart Air Fryer with Window: Your Versatile Kitchen Companion\n✨ Spacious 6.34QT Capacity …","images": ["https://p16-oec-general-useast5.ttcdn-us.com/…"], "videoCount": 1,"skuCount": 4, "totalStock": 311, "soldOut": false, "variantDimensions": { "Color": ["pink", "black", "White", "Gray"] },"skus": [{ "skuId": "1732306737131000283", "options": { "Color": "pink" }, "price": 59.03, "originalPrice": 81.98, "stock": 311, "inStock": true, "weightKg": 5.448, "dimensionsCm": "31x39x38" }],"dealEndsAt": "2026-09-07T06:56:00.000Z","properties": { "CA prop 65: repro. chems": "No" }, "businessName": "Shenzhen Yunqi Network Technology Co Ltd", "businessAddress": "Room 502, …, Shenzhen, Guangdong, China","verdict": "skip", "verdictReason": "25 sold · 5★ — little proof of demand yet" }
soldOut is true only when every SKU shows 0 stock. dealEndsAt is the end of the limited-time-deal countdown shown on the page (null without one).
market-summary (free, per keyword): listings, priceMin, priceP25, priceMedian, priceP75, priceMax, avgRating, totalSoldCount, avgSoldCount, estimatedGmv, withVideoPct, freeShippingPct, discountedPct, avgDiscountPct, topShops[], top3ShopSoldShare, verdictCounts {shortlist, watch, skip}, relatedSearches[], relatedCategories[] {name, categoryId, url} — plus matchedFilters, filters when filters are on. relatedSearches / relatedCategories are the related links TikTok shows on the search page: ready-made next keywords.
Failed ids / blocked keywords are pushed as type: "failed" rows and are never charged.
Trends between runs (what a one-off scraper can't tell you)
Run it on a schedule with trackTrends: true and every product carries what actually happened since the last run:
| Field | Meaning |
|---|---|
soldCountChange, soldPerDay | units sold since last run and the observed daily velocity — not an estimate |
priceChange, priceChangePct | price moves; trendSignal: "price-drop" when ≥10 % cheaper |
rankChange | position change for the same keyword (positive = climbed) |
isNewListing | product not seen in the previous run |
trendSignal | hot (≥50 sold/day observed), selling, flat, price-drop, price-up |
lowestPriceSeen, isNewLowestPrice | lowest price seen across your runs, and whether today's price is below every earlier one (0.1.8) |
stockChange | product-detail rows: total stock now minus at the last run (0.1.8) |
changes-digest (free, 0.1.8) — one row per keyword and one for your productUrls watch-list, so you don't have to read every product:
| Field | Meaning |
|---|---|
headline | one line, e.g. "<keyword>: <n> hot, <n> price drops ≥10 %, <n> new in results, <n> dropped out · top: "<title>" <n>/day" |
counts | hot, selling, flat, priceDrops, priceRises, newLowestPrice, newEntries, droppedOut, soldOut, unavailable |
topSoldPerDay | up to 10 products with the highest observed soldPerDay |
priceDrops, priceRises | price moves of 10 % or more, with previousPrice |
newEntries, droppedOut | products that entered / left this keyword's results since its last run (droppedOut only judges positions this run covered; lists restart when your filters change) |
soldOutProducts, unavailableProducts | details now at 0 stock (with previousStock), watch-list products that no longer load |
The first run only saves a baseline (baseline: true). Add onlyChanges: true for a watch-list: unchanged products are skipped and not charged — the digest still covers all of them. Add includeShopLeaderboard: true for a free per-keyword ranking of the shops that dominate the results (shop-leaderboard rows: listings, sold share, median price, rating, best position, shopVerified).
Example (daily schedule): { "keywords": ["air fryer", "led mask"], "maxResultsPerKeyword": 100, "trackTrends": true, "includeShopLeaderboard": true } · watch-list: { "productUrls": ["…"], "trackTrends": true, "onlyChanges": true } · rising products only: { "keywords": ["air fryer"], "trackTrends": true, "minSoldPerDay": 20 }
Trend memory lives in a key-value store named tiktok-shop-trends in your own account (one small record per product, plus the last result list per keyword).
Pricing (pay per event)
| Event | Price |
|---|---|
| Product (search result) | $0.005 |
| Product detail | $0.01 |
| Actor start | $0.001 |
1,000 search results ≈ $5 · 1,000 full product pages ≈ $10. Products skipped by filters or onlyChanges, summary, leaderboard, digest, failed and duplicate rows are free.
Changelog
- 0.1.8 (18 Oct 2026) — Filters before charging, shortlist verdict, daily changes digest. New optional filters
minSoldCount,maxSoldCount,minPrice,maxPrice,minRating,minReviewCount,minDiscountPct,freeShippingOnly,onlyDiscounted,onlyWithCreatorVideo,minSoldPerDay(with trackTrends) andminVerdict: products that don't match are skipped and not charged, andmaxResultsPerKeywordcounts only matching products (paging goes deeper, up to offset 2,000, and stops after 2 pages with no new products). Every product and detail row gets a freeverdict(shortlist / watch / skip) withverdictReason; the market summary counts verdicts and addspriceP25/priceP75,discountedPct,avgDiscountPct,top3ShopSoldShare,relatedSearchesandrelatedCategories. WithtrackTrends: a freechanges-digestrow per keyword and per watch-list,lowestPriceSeen/isNewLowestPrice, andstockChangeon product details. Also new:shopVerified,searchPosition,soldOut,dealEndsAt, and the dataset now declares its fields with Shortlist / Changes / Market views. A run that charged rows ends its status line with a short review invitation. Without the new options, rows, charges and defaults are unchanged — fields are only added, none removed or renamed;trackTrendsstays off by default. No price change. Also: a run that reaches its maximum cost stops searching and delivers only the rows it charges for (the status says how many were held, and a watch-list gets them on the next run); an impossible filter range (a minimum above its maximum) is reported without searching; with filters a keyword stops after scanning max(300, 10 × maxResultsPerKeyword) products;minSoldPerDayapplies from the second scheduled run. - 0.1.7 (18 Oct 2026) — Fixes.
savingis now the strike-through price minus the price (it used to show the shop's promo threshold, e.g. 100 on a $29.99 item) and is empty when there is no strike-through price. The example keyword "air fryer" that the input form pre-fills is no longer searched or charged when you also give product URLs, so a watch-list run only returns the products you listed. No price change. - 0.1.6 (2 Oct 2026) — The run header now points to
trackTrends(sold velocity between scheduled runs) and, when it is on, says how many products are hot / selling / dropping in price since your last run. No field, default or price changed. - 0.1.5 (24 Sep 2026) — Reliability: A non-US region without a proxy in that country now ends right away as a normal run with 0 rows and a clear explanation (only the start fee), and TikTok's short Security Check waves get two patient retries. Runs close to their timeout stop early and keep everything collected. No price or field change.
- 0.1.4 (21 Sep 2026) — Clearer failure reason for geo-fenced regions. A non-US
regionwithout a proxy in that country cannot work from Apify's US infrastructure; the run now fails with that exact explanation (and what to set) instead of a generic "US refused every request". No fields, defaults or prices changed. - 0.1.3 (19 Sep 2026) — Typo guard on input. Apify accepts input fields an Actor does not know without complaining, so a misspelled option used to produce a successful run with that setting silently inactive. The run log now warns for every unknown field and suggests the closest real one.
- 0.1.2 (18 Sep 2026) — Fix:
sortBy: newestsilently returned relevance order (it sorted on a field the search API never provides). New fieldseoUpdatedAt(the only date TikTok exposes on search cards — the listing page's last update, not the original listing date; null when TikTok sends 0) andnewestnow orders by it, newest first, unknown dates last. No other output or price change. - 0.1.1 (16 Sep 2026) — Reliability: V8 heap capped at 70 % of run memory so garbage is collected before the container limit (prevents out-of-memory kills on big pages). No output change.
- 0.3.0 (12 Sep 2026) — AIO update.
trackTrends: observed changes between runs —soldCountChange,soldPerDay(real sold velocity),priceChange/priceChangePct,rankChangeper keyword,isNewListing,trendSignal(hot / selling / flat / price-drop / price-up).onlyChanges: watch-list mode — unchanged products are skipped and not charged.includeShopLeaderboard: free per-keyword shop rankings (listings, sold share, median price, rating). All opt-in; defaults, fields and prices unchanged. Reviews / shop catalogues are intentionally not offered: TikTok gates them behind an interactive CAPTCHA. - 12 Sep 2026 — Price cut: product $0.012 → $0.005, product detail $0.02 → $0.01 (plus Store discounts for paid plans). No feature or field changes.
- 0.0.14 (11 Sep 2026) — Fix:
sortByhad no effect. The server-rendered page ignores sort and TikTok's search API currently ignores sort tokens too, so the requested order is now applied to the fetched result set (documented in the input schema). RaisemaxResultsPerKeywordto sort over a larger pool. - 0.0.4 (11 Sep 2026) — Honest regions +
proxyConfiguration. Verified that from Apify's US infrastructure onlyusreturns products (uk/id answer with an empty page, my/th/vn/ph/sg redirect). Non-US regions now require your own in-country proxy via the newproxyConfigurationinput; without it the run ends with 0 rows and a clear status message instead of a silent empty dataset. - 0.2.0 (9 Sep 2026) — Sort, shops and filters, plus a faster, safer engine. New
sortBy(best sellers, price low/high, newest — using TikTok's own filter tokens),includeShops(freeshoprows: seller id, shop name, logo, verified badge, shop URL — taken from the page the products already come from, so no extra requests and no extra charge) andincludeFilters(one freesearch-filtersrow per keyword listing every category, colour, price band and rating filter with its exact token). Alsoregion(defaultus; other storefronts only answer if the run's IP is allowed in that country — the log tells you when one refuses). Engine work from the same audit: a failing billing call can no longer kill a run that already has data, result de-duplication is O(n) instead of O(n²), rows are flattened before storage so a large JSON page can't pin memory, and concurrency follows the memory the run was given. Default behaviour is unchanged — a run with none of the new options set returns exactly what it did before.
Notes
- US marketplace only (shop.tiktok.com/us). Other regions are served by different storefronts and are not covered yet — open an issue if you need one.
soldCountis TikTok's own lifetime counter shown on the listing;estimatedGmvin the summary = Σ soldCount × current price (rough, lower-bound-ish).- Default order is TikTok's relevance;
sortByre-orders the fetched set. Results are de-duplicated per keyword. - TikTok changes its storefront often; if a field turns
nullwhere you can see it on the page, open an issue with the product id.
Found this useful? A review helps more than you'd think
If this Actor saved you time, a short review on the Reviews tab of this Store page takes 30 seconds and helps other users decide before they spend anything. If something is broken instead, open a ticket on the Issues tab — parser bugs and field requests get fixed.
Related Actors from the same account