TikTok Shop Analytics: Track Sales, Revenue & Competitor Products in 2026
TikTok Shop did $20 billion in US GMV in 2025. Analysts expect $35 billion in 2026.
If you sell products online — dropshipping, private label, agency, brand — ignoring TikTok Shop analytics is leaving money on the table. The sellers who win aren't guessing what products to launch. They're tracking competitor sales, monitoring price changes, analyzing review sentiment, and finding trending products before they saturate.
The problem? TikTok's Seller Center gives you analytics for your own shop only. You can't see competitor sales. You can't track trending products across the platform. You can't export data for analysis.
Tools like Kalodata and FastMoss charge $100-500/month for TikTok Shop analytics. They work, but they're expensive, and you can't customize them.
This guide shows you how to build your own TikTok Shop analytics system — pulling real product data, tracking competitors, estimating revenue, and finding winning products — using API data and code.
What TikTok Shop Data Can You Access?
Here's everything you can pull from any public TikTok Shop:
Shop-Level Data
- Shop name and seller ID
- Total products sold (with formatted counts like "3.7M")
- Number of products listed
- Total reviews
- Follower count
- Shop rating (out of 5)
- Shop bio/slogan
Product-Level Data
- Product name and ID
- Current sale price and original price
- Discount percentage
- Review count and average rating
- Units sold
- Seller information
- Product images
Product Detail Data
- Full description
- All SKU variants (sizes, colors, etc.)
- Stock availability
- Shipping information
- Related TikTok videos (if requested)
- Complete review data with text and ratings
That's more data than most paid analytics tools show you. Let's use it.
Use Case 1: Analyze a Competitor's Shop
You've spotted a competitor doing well on TikTok Shop. You want to know: how many products do they sell, what's their best seller, what's their average price point?
const axios = require('axios');
const API_KEY = process.env.SOCIAVAULT_API_KEY;
const BASE_URL = 'https://api.sociavault.com';
async function analyzeShop(shopUrl) {
const response = await axios.get(`${BASE_URL}/v1/scrape/tiktok-shop/products`, {
params: { url: shopUrl, region: 'US' },
headers: { 'X-API-Key': API_KEY }
});
const { shopInfo, products } = response.data;
console.log('\n=== SHOP ANALYSIS ===');
console.log(`Shop: ${shopInfo.shop_name}`);
console.log(`Rating: ${shopInfo.shop_rating}/5`);
console.log(`Products listed: ${shopInfo.on_sell_product_count}`);
console.log(`Total sold: ${shopInfo.format_sold_count || shopInfo.sold_count?.toLocaleString()}`);
console.log(`Reviews: ${shopInfo.review_count?.toLocaleString()}`);
console.log(`Followers: ${shopInfo.followers_count}`);
// Analyze product catalog
const productData = products.map(p => ({
title: p.title,
salePrice: parseFloat(p.product_price_info.sale_price_decimal),
originalPrice: parseFloat(p.product_price_info.origin_price_decimal),
discount: p.product_price_info.discount_format,
sold: p.sold_info.sold_count,
rating: p.rate_info.score,
reviews: parseInt(p.rate_info.review_count) || 0
}));
// Sort by units sold
productData.sort((a, b) => b.sold - a.sold);
// Calculate shop metrics
const avgPrice = productData.reduce((s, p) => s + p.salePrice, 0) / productData.length;
const totalRevenue = productData.reduce((s, p) => s + (p.salePrice * p.sold), 0);
console.log(`\nAverage sale price: $${avgPrice.toFixed(2)}`);
console.log(`Estimated total revenue: $${totalRevenue.toLocaleString()}`);
console.log(`\nTop 5 Best Sellers:`);
productData.slice(0, 5).forEach((p, i) => {
const revenue = p.salePrice * p.sold;
console.log(` ${i + 1}. ${p.title.substring(0, 60)}...`);
console.log(` $${p.salePrice} (was $${p.originalPrice}) | ${p.sold.toLocaleString()} sold | ~$${revenue.toLocaleString()} revenue`);
console.log(` ${p.rating}★ (${p.reviews.toLocaleString()} reviews)`);
});
return { shopInfo, products: productData, avgPrice, totalRevenue };
}
// Analyze Goli Nutrition's TikTok Shop
await analyzeShop('https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079');
Example output:
=== SHOP ANALYSIS ===
Shop: Goli Nutrition
Rating: 4.6/5
Products listed: 36
Total sold: 3.7M
Reviews: 284,185
Followers: 237,879
Average sale price: $18.47
Estimated total revenue: $68,339,000
Top 5 Best Sellers:
1. Goli Ashwagandha & Vitamin D Gummy...
$14.96 (was $24.99) | 1,235,089 sold | ~$18,476,931 revenue
4.5★ (91,316 reviews)
Cost: 1 API credit.
Use Case 2: Track Competitor Pricing
Prices on TikTok Shop change constantly — flash sales, creator promotions, volume discounts. Track them:
import requests
import json
import os
from datetime import datetime
API_KEY = os.getenv('SOCIAVAULT_API_KEY')
BASE_URL = 'https://api.sociavault.com'
headers = {'X-API-Key': API_KEY}
def track_prices(product_urls):
"""Track prices for a list of competitor products"""
timestamp = datetime.now().isoformat()
results = []
for url in product_urls:
response = requests.get(
f'{BASE_URL}/v1/scrape/tiktok-shop/product-details',
params={'url': url, 'get_related_videos': 'false', 'region': 'US'},
headers=headers
)
data = response.json()
product = {
'timestamp': timestamp,
'product_id': data.get('product_id'),
'title': data.get('title', 'Unknown'),
'sale_price': data.get('sale_price_decimal'),
'original_price': data.get('origin_price_decimal'),
'discount': data.get('discount_format'),
'sold_count': data.get('sold_count'),
'review_count': data.get('review_count'),
'rating': data.get('rating'),
'in_stock': data.get('in_stock', True)
}
results.append(product)
print(f" {product['title'][:50]}... → ${product['sale_price']} ({product['discount']} off)")
# Append to tracking file
log_file = 'tiktok-price-tracking.json'
history = []
if os.path.exists(log_file):
with open(log_file, 'r') as f:
history = json.load(f)
history.extend(results)
with open(log_file, 'w') as f:
json.dump(history, f, indent=2)
print(f"\nTracked {len(results)} products at {timestamp}")
return results
# Track competitor products daily
track_prices([
'https://www.tiktok.com/shop/pdp/product-name-1234567890',
'https://www.tiktok.com/shop/pdp/another-product-0987654321',
])
Run this daily with a cron job. After a week, you'll know:
- When competitors run discounts
- How prices fluctuate around payday/weekends
- Whether they adjust prices after sales velocity changes
Cost: 1 credit per product per check.
Use Case 3: Find Winning Products in Your Niche
This is the big one. Instead of scrolling TikTok hoping to spot trends, search systematically:
async function findWinningProducts(keyword, minSold = 1000) {
const response = await axios.get(`${BASE_URL}/v1/scrape/tiktok-shop/products`, {
params: { url: `https://www.tiktok.com/shop/search?q=${encodeURIComponent(keyword)}`, region: 'US' },
headers: { 'X-API-Key': API_KEY }
});
const products = response.data.products || [];
// Filter for proven sellers
const winners = products
.filter(p => p.sold_info.sold_count >= minSold)
.map(p => ({
title: p.title,
price: parseFloat(p.product_price_info.sale_price_decimal),
originalPrice: parseFloat(p.product_price_info.origin_price_decimal),
sold: p.sold_info.sold_count,
rating: p.rate_info.score,
reviews: parseInt(p.rate_info.review_count) || 0,
revenue: parseFloat(p.product_price_info.sale_price_decimal) * p.sold_info.sold_count,
shop: p.seller_info.shop_name
}))
.sort((a, b) => b.revenue - a.revenue);
console.log(`\n"${keyword}" — ${winners.length} products with ${minSold.toLocaleString()}+ sales\n`);
winners.forEach((p, i) => {
console.log(`${i + 1}. ${p.title.substring(0, 65)}`);
console.log(` $${p.price} | ${p.sold.toLocaleString()} sold | ~$${p.revenue.toLocaleString()} revenue`);
console.log(` ${p.rating}★ (${p.reviews.toLocaleString()} reviews) | Shop: ${p.shop}`);
console.log('');
});
return winners;
}
// Research trending niches
await findWinningProducts('protein powder', 5000);
await findWinningProducts('LED mirror', 1000);
await findWinningProducts('phone case', 10000);
What you're looking for:
- High sales + high rating → validated product, but might be saturated
- Moderate sales + rising velocity → opportunity window
- High sales + low rating → opportunity to launch a better version
- Low price + high volume → potential for premium alternative
Cost: 1 credit per search.
Use Case 4: Review Sentiment Analysis
Before sourcing a product, check what customers actually think:
def analyze_reviews(product_url, pages=3):
"""Analyze customer review sentiment for a TikTok Shop product"""
all_reviews = []
cursor = None
for page in range(pages):
params = {'url': product_url}
if cursor:
params['cursor'] = cursor
response = requests.get(
f'{BASE_URL}/v1/scrape/tiktok-shop/reviews',
params=params,
headers=headers
)
data = response.json()
reviews = data.get('data', {}).get('reviews', [])
cursor = data.get('data', {}).get('cursor')
all_reviews.extend(reviews)
if not cursor:
break
# Analyze
ratings = [r.get('rating', 0) for r in all_reviews]
avg_rating = sum(ratings) / len(ratings) if ratings else 0
# Simple keyword-based analysis
complaints = []
praise = []
complaint_keywords = ['broken', 'fake', 'cheap', 'waste', 'refund', 'terrible',
'smell', 'doesn\'t work', 'scam', 'disappointed']
praise_keywords = ['love', 'amazing', 'perfect', 'great quality', 'recommend',
'works great', 'fast shipping', 'exceeded', 'repurchase']
for review in all_reviews:
text = (review.get('comment', '') or '').lower()
for kw in complaint_keywords:
if kw in text:
complaints.append(text[:100])
break
for kw in praise_keywords:
if kw in text:
praise.append(text[:100])
break
print(f"\nReview Analysis ({len(all_reviews)} reviews)")
print(f"Average rating: {avg_rating:.1f}/5")
print(f"5★: {ratings.count(5)} | 4★: {ratings.count(4)} | 3★: {ratings.count(3)} | "
f"2★: {ratings.count(2)} | 1★: {ratings.count(1)}")
print(f"\nComplaints found: {len(complaints)}")
for c in complaints[:5]:
print(f" - \"{c}...\"")
print(f"\nPraise found: {len(praise)}")
for p in praise[:5]:
print(f" + \"{p}...\"")
# Opportunity signal
if avg_rating < 4.0 and len(all_reviews) > 50:
print("\n💡 OPPORTUNITY: Moderate rating with volume = room for a better product")
elif avg_rating >= 4.5 and len(complaints) < 3:
print("\n⚠️ SATURATED: High rating, few complaints = hard to differentiate")
return {
'total_reviews': len(all_reviews),
'avg_rating': avg_rating,
'complaints': len(complaints),
'praise': len(praise)
}
analyze_reviews('https://www.tiktok.com/shop/pdp/product-name-1234567890')
Cost: 1 credit per page of reviews.
Use Case 5: Full Competitor Dashboard
Combine everything into a competitor monitoring script:
async function competitorDashboard(shops) {
console.log('\n╔══════════════════════════════════════════════════╗');
console.log('║ TIKTOK SHOP COMPETITOR DASHBOARD ║');
console.log('╚══════════════════════════════════════════════════╝\n');
const allData = [];
for (const shopUrl of shops) {
const response = await axios.get(`${BASE_URL}/v1/scrape/tiktok-shop/products`, {
params: { url: shopUrl, region: 'US' },
headers: { 'X-API-Key': API_KEY }
});
const { shopInfo, products } = response.data;
const totalRevenue = products.reduce((sum, p) => {
return sum + (parseFloat(p.product_price_info.sale_price_decimal) * p.sold_info.sold_count);
}, 0);
const avgPrice = products.reduce((sum, p) => {
return sum + parseFloat(p.product_price_info.sale_price_decimal);
}, 0) / products.length;
allData.push({
name: shopInfo.shop_name,
rating: shopInfo.shop_rating,
products: shopInfo.on_sell_product_count,
totalSold: shopInfo.sold_count,
reviews: shopInfo.review_count,
followers: shopInfo.followers_count,
estRevenue: totalRevenue,
avgPrice,
topProduct: products.sort((a, b) =>
b.sold_info.sold_count - a.sold_info.sold_count
)[0]
});
}
// Display comparison
allData.sort((a, b) => b.estRevenue - a.estRevenue);
allData.forEach((shop, i) => {
console.log(`${i + 1}. ${shop.name}`);
console.log(` Rating: ${shop.rating}★ | Products: ${shop.products} | Followers: ${shop.followers}`);
console.log(` Total sold: ${shop.totalSold?.toLocaleString()} | Reviews: ${shop.reviews?.toLocaleString()}`);
console.log(` Avg price: $${shop.avgPrice.toFixed(2)} | Est. revenue: $${shop.estRevenue.toLocaleString()}`);
if (shop.topProduct) {
console.log(` Top product: ${shop.topProduct.title.substring(0, 55)}...`);
console.log(` → ${shop.topProduct.sold_info.sold_count.toLocaleString()} sold at $${shop.topProduct.product_price_info.sale_price_decimal}`);
}
console.log('');
});
return allData;
}
// Monitor your niche competitors
await competitorDashboard([
'https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079',
'https://www.tiktok.com/shop/store/another-shop/1234567890',
'https://www.tiktok.com/shop/store/third-shop/0987654321'
]);
Cost: 1 credit per shop.
How This Compares to Paid Tools
| Feature | Kalodata ($199/mo) | FastMoss ($99/mo) | SociaVault API |
|---|---|---|---|
| Product discovery | ✅ | ✅ | ✅ (build your own) |
| Revenue estimates | ✅ | ✅ | ✅ (calculate from data) |
| Price tracking | ✅ | ❌ | ✅ (run on schedule) |
| Review analysis | ❌ | ❌ | ✅ (full review text) |
| Custom dashboards | ❌ | ❌ | ✅ (built to your specs) |
| Raw data export | Limited | Limited | ✅ (full JSON) |
| Custom alerts | ❌ | ❌ | ✅ (build your own) |
| Cost at 100 lookups/mo | $199 | $99 | ~$5 (100 credits) |
The paid tools are slicker out of the box. They have dashboards, charts, trend graphs. But you can't customize them, you can't integrate them into your own systems, and they cost 20-40x more if you're doing light research.
If you need plug-and-play dashboards and don't care about cost, Kalodata is fine. If you want raw data, custom analysis, and cost control — build it yourself with the API.
Combining TikTok Shop + Creator Data
The real power move: connect product data with creator data. Who's promoting this product? How much reach are they getting?
async function productCreatorAnalysis(productUrl) {
// Get product with related videos
const product = await axios.get(`${BASE_URL}/v1/scrape/tiktok-shop/product-details`, {
params: { url: productUrl, get_related_videos: true, region: 'US' },
headers: { 'X-API-Key': API_KEY }
});
const data = product.data;
console.log(`\nProduct: ${data.title}`);
console.log(`Price: $${data.sale_price_decimal} (${data.discount_format} off)`);
console.log(`Sold: ${data.sold_count?.toLocaleString()}`);
// If related videos are returned, analyze the creators promoting it
const relatedVideos = data.related_videos || [];
if (relatedVideos.length > 0) {
console.log(`\nCreators promoting this product:`);
for (const video of relatedVideos.slice(0, 5)) {
const creator = video.author || {};
const stats = video.statistics || {};
console.log(` @${creator.uniqueId || creator.unique_id} — ${stats.play_count?.toLocaleString()} views, ${stats.digg_count?.toLocaleString()} likes`);
}
}
return data;
}
await productCreatorAnalysis('https://www.tiktok.com/shop/pdp/product-1234567890');
This tells you: which creators are successfully promoting a product, how much reach they're getting, and whether it's worth reaching out to them for your own product launch.
Tips for TikTok Shop Research
-
Track weekly, not daily. Most shops don't change prices daily. Weekly snapshots capture meaningful trends without burning credits.
-
Focus on sold_count velocity. A product with 10K sales that launched 2 weeks ago is more interesting than one with 100K sales over 12 months.
-
Check review quality, not just rating. A 4.8★ product with reviews like "haven't tried yet, 5 stars" has fake reviews. A 4.2★ product with detailed feedback has real customers.
-
Use region codes. Results differ by market. US products don't show up in UK searches and vice versa. Always set
region=US(or your target market). -
Cross-reference with TikTok creator data. Use the TikTok profile endpoint and TikTok videos endpoint to see what content is driving traffic to products.
Get Started
Sign up free — 100 credits lets you analyze 100 shops or products.
Full TikTok Shop API docs: docs.sociavault.com/api-reference/tiktok-shop
Related Reading
Found this helpful?
Share it with others who might benefit
Ready to Try SociaVault?
Start extracting social media data with our powerful API. No credit card required.