How to track TikTok Shop product sales signals over time
TikTok Shop does not publish a competitor's sales. It does show public signals on product pages, such as a sold count, the price and reviews. Snapshot those signals every day and the differences become a usable estimate of sales over time. Here is the method, the math and the honest limits.
The signals
| Signal | What it tells you | Caveat |
|---|---|---|
| Sold count | Cumulative units, as shown on the product page | May be rounded for large numbers |
| Price | Current selling price | Variants and promotions change it |
| Review count | Cumulative reviews | Only a fraction of buyers review |
| Rank in store and search | Position among best sellers and for search terms | Varies by region and time |
| Creator videos | New videos mentioning the product | Leads sales by a day or two |
The math
- Units sold in a period = sold count at the end minus sold count at the start.
- Revenue estimate = sum over days of (daily units x that day's price). Use the daily price, not the current one.
- Review velocity = new reviews per day. A second, independent check on the sold count.
- Review ratio = new reviews / new units. If it jumps, either sales slowed or the shop is pushing for reviews.
If the sold count is shown rounded, such as 12.3K, your daily delta is only as precise as the rounding step. For big products, track weekly instead of daily, or lean on review velocity.
A tracker in 40 lines
import sqlite3, datetime, requests
KEY = "YOUR_KEY"
PRODUCTS = open("product_urls.txt").read().split()
db = sqlite3.connect("shop.db")
db.execute("""CREATE TABLE IF NOT EXISTS snap(
day TEXT, url TEXT, region TEXT, sold INTEGER, price REAL, reviews INTEGER, raw TEXT,
PRIMARY KEY(day, url, region))""")
def pick(d, *keys):
for k in keys: # map to the field names in your first response
if d.get(k) is not None:
return d[k]
return None
today = datetime.date.today().isoformat()
for url in PRODUCTS:
r = requests.get("https://scrapeio.com/v1/tiktok/product",
params={"url": url, "region": "US"},
headers={"x-api-key": KEY}, timeout=60).json()
if not r.get("success"):
continue
d = r["data"]
db.execute("INSERT OR REPLACE INTO snap VALUES (?,?,?,?,?,?,?)",
(today, url, "US", pick(d, "sold_count"), pick(d, "price"),
pick(d, "review_count"), str(d)))
db.commit()
-- Daily units and revenue estimate per product
SELECT url, day,
sold - LAG(sold) OVER (PARTITION BY url ORDER BY day) AS units,
(sold - LAG(sold) OVER (PARTITION BY url ORDER BY day)) * price AS revenue_est
FROM snap ORDER BY url, day;
Keep the raw response in every row. If you later find a better field, you can recompute history without re-pulling.
Reading the chart
- Spike with new creator videos: an affiliate push worked. Find the creators with keyword search for the product name.
- Spike with a price drop: a promotion. Check whether units stay up after the price returns.
- Flat sold count, rising reviews: a review campaign, or the count is rounded. Look closer.
- Steady growth, no spikes: the product sells from search. Check its search rank.
Limits to state with any estimate
- It is an estimate from public signals, not the seller's real numbers.
- Sold counts can include orders that are later cancelled or refunded.
- Each country's Shop is separate. Track one region per row and do not add regions together without saying so.
- If a product page shows no sold count, this method does not work for that product. Fall back to review velocity.
Choosing what to track
Do not try to track a whole category. Pick three groups: your own products, the top 10 best sellers from each of three competitor stores, and the top 20 results for your two most important search terms. That is usually under 100 products, small enough to check daily and big enough to see the market. Review the list monthly: drop products that stopped selling and add new entries that broke into the best sellers.
Sanity-check your estimates
Before you share a number, compare it with something you know. Track your own products with the same method and compare the estimate with your real sales. If the estimate is 20% low on your products, it is probably low on competitors too, and you can say so.
How to do it with ScrapeIO
tiktok product API returns a product by URL and region. tiktok shop products API lists a store's best sellers to choose what to track, and tiktok shop product reviews API gives review detail. tiktok search keyword API finds the creator videos behind a spike. Tracking 200 products daily is 6,000 credits a month, about $11 on the Starter pack. Check the field names on the endpoint page and in your first response, then fill in the pick() keys above. For the wider picture, see the TikTok Shop data guide.
100 free credits, no card. Credits never expire.
Get API key