Tracking what competitors post on TikTok and how their content performs reveals content strategy patterns, optimal posting times, and engagement benchmarks for your niche. This tracker pulls competitor profiles and recent posts through the Scavio TikTok API, calculates engagement rates, and generates weekly comparison reports. Each profile pull costs $0.005 and each posts fetch costs $0.005.
Prerequisites
- Python 3.8+
- requests library
- A Scavio API key from scavio.dev
- Competitor TikTok usernames to track
Walkthrough
Step 1: Set up competitor profiles
Fetch and store baseline profile data for each competitor.
import os, requests, json
from datetime import datetime
API_KEY = os.environ['SCAVIO_API_KEY']
TH = {'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'}
COMPETITORS = ['competitor1', 'competitor2', 'competitor3']
def get_profile(username):
data = requests.post('https://api.scavio.dev/api/v1/tiktok/profile',
headers=TH, json={'username': username}).json()
user = data.get('user', data.get('data', {}).get('user', data))
return {
'username': username, 'followers': user.get('followerCount', user.get('fans', 0)),
'following': user.get('followingCount', 0),
'likes': user.get('heartCount', user.get('heart', 0)),
'videos': user.get('videoCount', 0),
'checked_at': datetime.now().isoformat()
}
profiles = []
for c in COMPETITORS:
p = get_profile(c)
profiles.append(p)
print(f'{c}: {p["followers"]:,} followers, {p["videos"]} videos, {p["likes"]:,} likes')
print(f'Cost: ${len(COMPETITORS) * 0.005:.3f}')Step 2: Fetch recent posts and calculate engagement
Pull recent posts and compute engagement rates per competitor.
def get_recent_posts(username):
profile = requests.post('https://api.scavio.dev/api/v1/tiktok/profile',
headers=TH, json={'username': username}).json()
sec_uid = profile.get('user', profile.get('data', {}).get('user', {})).get('secUid', '')
if not sec_uid:
return []
data = requests.post('https://api.scavio.dev/api/v1/tiktok/user/posts',
headers=TH, json={'sec_user_id': sec_uid}).json()
posts = data.get('videos', data.get('data', {}).get('videos', []))
return [{'desc': p.get('desc', '')[:80],
'plays': p.get('stats', {}).get('playCount', 0),
'likes': p.get('stats', {}).get('diggCount', 0),
'comments': p.get('stats', {}).get('commentCount', 0),
'shares': p.get('stats', {}).get('shareCount', 0),
'date': p.get('createTime', '')} for p in posts[:10]]
def engagement_rate(posts):
if not posts: return 0
total_eng = sum(p['likes'] + p['comments'] + p['shares'] for p in posts)
total_plays = sum(p['plays'] for p in posts) or 1
return total_eng / total_plays * 100
for c in COMPETITORS:
posts = get_recent_posts(c)
er = engagement_rate(posts)
avg_plays = sum(p['plays'] for p in posts) / len(posts) if posts else 0
print(f'{c}: {len(posts)} posts, {er:.2f}% engagement, {avg_plays:,.0f} avg plays')Step 3: Track changes over time
Store weekly snapshots and detect follower/engagement changes.
import sqlite3
db = sqlite3.connect('tiktok_tracker.db')
db.execute('''CREATE TABLE IF NOT EXISTS snapshots (
username TEXT, checked_at TEXT, followers INTEGER,
engagement_rate REAL, avg_plays INTEGER, post_count INTEGER
)''')
db.commit()
def save_snapshot(username, followers, er, avg_plays, post_count):
db.execute('INSERT INTO snapshots VALUES (?,?,?,?,?,?)',
(username, datetime.now().isoformat(), followers, er, avg_plays, post_count))
db.commit()
def get_change(username):
rows = db.execute(
'SELECT followers, engagement_rate, checked_at FROM snapshots WHERE username=? ORDER BY checked_at DESC LIMIT 2',
(username,)).fetchall()
if len(rows) < 2: return None
curr, prev = rows[0], rows[1]
return {
'follower_change': curr[0] - prev[0],
'er_change': curr[1] - prev[1],
'period': f'{prev[2][:10]} -> {curr[2][:10]}'
}
for c in COMPETITORS:
posts = get_recent_posts(c)
p = get_profile(c)
er = engagement_rate(posts)
avg_plays = sum(po['plays'] for po in posts) / len(posts) if posts else 0
save_snapshot(c, p['followers'], er, int(avg_plays), len(posts))
change = get_change(c)
if change:
print(f'{c}: followers {change["follower_change"]:+,}, ER {change["er_change"]:+.2f}pp')Step 4: Generate weekly comparison report
Build a comparison table ranking competitors by key metrics.
def weekly_report():
print(f'\n=== TikTok Competitor Report - {datetime.now().strftime("%Y-%m-%d")} ===')
data = []
total_cost = 0
for c in COMPETITORS:
p = get_profile(c)
total_cost += 0.005
posts = get_recent_posts(c)
total_cost += 0.010 # profile + posts
er = engagement_rate(posts)
avg_plays = sum(po['plays'] for po in posts) / len(posts) if posts else 0
data.append({'name': c, 'followers': p['followers'], 'er': er,
'avg_plays': avg_plays, 'posts': len(posts)})
data.sort(key=lambda x: x['er'], reverse=True)
print(f'{"Creator":20} | {"Followers":>12} | {"Eng Rate":>8} | {"Avg Plays":>12} | {"Posts":>5}')
print('-' * 75)
for d in data:
print(f'{d["name"]:20} | {d["followers"]:12,} | {d["er"]:7.2f}% | {d["avg_plays"]:12,.0f} | {d["posts"]:5}')
print(f'\nTotal cost: ${total_cost:.3f}')
return data
weekly_report()Python Example
import os, requests
TH = {'Authorization': f'Bearer {os.environ["SCAVIO_API_KEY"]}', 'Content-Type': 'application/json'}
def track(username):
p = requests.post('https://api.scavio.dev/api/v1/tiktok/profile',
headers=TH, json={'username': username}).json()
user = p.get('user', p.get('data', {}).get('user', p))
sec_uid = user.get('secUid', '')
posts = requests.post('https://api.scavio.dev/api/v1/tiktok/user/posts',
headers=TH, json={'sec_user_id': sec_uid}).json()
vids = posts.get('videos', posts.get('data', {}).get('videos', []))[:5]
total = sum(v.get('stats', {}).get('diggCount', 0) for v in vids)
print(f'{username}: {user.get("followerCount", 0):,} followers, {total:,} likes on last 5. Cost: $0.010')
track('competitor1')JavaScript Example
const TH = { 'Authorization': `Bearer ${process.env.SCAVIO_API_KEY}`, 'Content-Type': 'application/json' };
async function track(username) {
const p = await fetch('https://api.scavio.dev/api/v1/tiktok/profile', {
method: 'POST', headers: TH, body: JSON.stringify({ username })
}).then(r => r.json());
const user = p.user || p.data?.user || p;
const posts = await fetch('https://api.scavio.dev/api/v1/tiktok/user/posts', {
method: 'POST', headers: TH, body: JSON.stringify({ sec_user_id: user.secUid })
}).then(r => r.json());
const vids = (posts.videos || posts.data?.videos || []).slice(0, 5);
const likes = vids.reduce((s, v) => s + (v.stats?.diggCount || 0), 0);
console.log(`${username}: ${(user.followerCount||0).toLocaleString()} followers, ${likes.toLocaleString()} likes`);
}
track('competitor1').catch(console.error);Expected Output
competitor1: 45,200 followers, 312 videos, 1,230,000 likes
competitor2: 128,500 followers, 567 videos, 4,560,000 likes
competitor3: 23,100 followers, 189 videos, 890,000 likes
Cost: $0.015
=== TikTok Competitor Report - 2026-05-19 ===
Creator | Followers | Eng Rate | Avg Plays | Posts
---------------------------------------------------------------------------
competitor3 | 23,100 | 8.45% | 12,300 | 10
competitor1 | 45,200 | 5.23% | 34,500 | 10
competitor2 | 128,500 | 3.87% | 89,200 | 10
Total cost: $0.045