Knowing what your competitors post on TikTok and how their audience responds reveals gaps you can exploit. This tutorial builds a competitor monitoring pipeline that tracks posting frequency, content themes, top-performing video styles, and engagement benchmarks for a list of competitor accounts. Each profile check costs $0.005 and each post fetch costs $0.005 via the Scavio TikTok API with Bearer token authentication.
Prerequisites
- Python 3.9+ installed
- requests library installed
- A Scavio API key from scavio.dev
- A list of competitor TikTok usernames
Walkthrough
Step 1: Set up the competitor list and fetch profiles
Define your competitors and pull their profile stats to establish baseline metrics.
import os, requests, json, time
from datetime import datetime
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
TT_URL = 'https://api.scavio.dev/api/v1/tiktok'
TT_H = {'Authorization': f'Bearer {SCAVIO_KEY}', 'Content-Type': 'application/json'}
COMPETITORS = ['competitor1', 'competitor2', 'competitor3']
def get_competitor_profile(username: str) -> dict:
resp = requests.post(f'{TT_URL}/profile', headers=TT_H,
json={'username': username})
data = resp.json().get('data', {})
stats = data.get('stats', {})
return {
'username': username,
'followers': stats.get('followerCount', 0),
'total_likes': stats.get('heartCount', 0),
'video_count': stats.get('videoCount', 0),
'sec_user_id': data.get('user', {}).get('secUid', ''),
}
for c in COMPETITORS:
profile = get_competitor_profile(c)
print(f'@{c}: {profile["followers"]:,} followers, {profile["video_count"]} videos')
time.sleep(0.3)Step 2: Fetch and analyze competitor posting patterns
Pull each competitor's recent posts and analyze posting frequency, typical engagement rates, and content themes.
def analyze_competitor(username: str, sec_user_id: str) -> dict:
resp = requests.post(f'{TT_URL}/user/posts', headers=TT_H,
json={'sec_user_id': sec_user_id, 'count': 30})
posts = resp.json().get('data', {}).get('videos', [])
if not posts:
return {'username': username, 'error': 'No posts found'}
engagement_rates = []
view_counts = []
descriptions = []
for p in posts:
stats = p.get('stats', {})
views = stats.get('playCount', 0)
likes = stats.get('diggCount', 0)
comments = stats.get('commentCount', 0)
if views > 0:
engagement_rates.append((likes + comments) / views)
view_counts.append(views)
descriptions.append(p.get('desc', '').lower())
# Posting frequency
timestamps = sorted([p.get('createTime', 0) for p in posts if p.get('createTime')])
if len(timestamps) >= 2:
days_span = (timestamps[-1] - timestamps[0]) / 86400
posts_per_week = len(timestamps) / max(days_span / 7, 1)
else:
posts_per_week = 0
return {
'username': username,
'posts_analyzed': len(posts),
'avg_engagement': sum(engagement_rates) / len(engagement_rates) if engagement_rates else 0,
'avg_views': sum(view_counts) / len(view_counts) if view_counts else 0,
'posts_per_week': posts_per_week,
'top_video_views': max(view_counts) if view_counts else 0,
}Step 3: Generate a competitive benchmark report
Compile all competitor data into a benchmark report that shows where you stand relative to competitors and identifies content gaps.
def competitor_report(competitors: list) -> dict:
results = []
for username in competitors:
profile = get_competitor_profile(username)
time.sleep(0.3)
if profile.get('sec_user_id'):
analysis = analyze_competitor(username, profile['sec_user_id'])
analysis['followers'] = profile['followers']
results.append(analysis)
time.sleep(0.3)
print('Competitor Benchmark Report')
print('=' * 70)
for r in sorted(results, key=lambda x: x.get('avg_views', 0), reverse=True):
print(f' @{r["username"]:15s} | {r["followers"]:>10,} followers | '
f'{r.get("avg_engagement", 0):5.1%} eng | '
f'{r.get("posts_per_week", 0):4.1f}/wk | '
f'{r.get("avg_views", 0):>10,.0f} avg views')
# Averages
avg_eng = sum(r.get('avg_engagement', 0) for r in results) / len(results) if results else 0
avg_freq = sum(r.get('posts_per_week', 0) for r in results) / len(results) if results else 0
print(f'\n Benchmark avg: {avg_eng:.1%} engagement, {avg_freq:.1f} posts/week')
print(f' Cost: ${len(competitors) * 0.010:.3f} ({len(competitors)} competitors x 2 calls)')
return {'results': results, 'avg_engagement': avg_eng, 'avg_frequency': avg_freq}
competitor_report(COMPETITORS)Python Example
import os, requests, time
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
TT_H = {'Authorization': f'Bearer {SCAVIO_KEY}', 'Content-Type': 'application/json'}
def monitor_competitor(username):
resp = requests.post('https://api.scavio.dev/api/v1/tiktok/profile', headers=TT_H,
json={'username': username})
data = resp.json().get('data', {})
stats = data.get('stats', {})
uid = data.get('user', {}).get('secUid', '')
time.sleep(0.3)
resp2 = requests.post('https://api.scavio.dev/api/v1/tiktok/user/posts', headers=TT_H,
json={'sec_user_id': uid, 'count': 10})
posts = resp2.json().get('data', {}).get('videos', [])
views = [v.get('stats', {}).get('playCount', 0) for v in posts]
avg = sum(views) / len(views) if views else 0
print(f'@{username}: {stats.get("followerCount", 0):,} followers, {avg:,.0f} avg views')
for c in ['competitor1', 'competitor2']:
monitor_competitor(c)
time.sleep(0.3)JavaScript Example
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const TT_H = { Authorization: `Bearer ${SCAVIO_KEY}`, 'Content-Type': 'application/json' };
async function monitorCompetitor(username) {
const profile = await fetch('https://api.scavio.dev/api/v1/tiktok/profile', {
method: 'POST', headers: TT_H, body: JSON.stringify({ username })
}).then(r => r.json());
const stats = profile.data?.stats || {};
const uid = profile.data?.user?.secUid || '';
const posts = await fetch('https://api.scavio.dev/api/v1/tiktok/user/posts', {
method: 'POST', headers: TT_H, body: JSON.stringify({ sec_user_id: uid, count: 10 })
}).then(r => r.json());
const views = (posts.data?.videos || []).map(v => v.stats?.playCount || 0);
const avg = views.length ? views.reduce((a, b) => a + b, 0) / views.length : 0;
console.log(`@${username}: ${(stats.followerCount || 0).toLocaleString()} followers, ${avg.toLocaleString()} avg views`);
}
(async () => { for (const c of ['competitor1', 'competitor2']) { await monitorCompetitor(c); } })();Expected Output
Competitor Benchmark Report
======================================================================
@competitor1 | 250,000 followers | 6.2% eng | 4.5/wk | 890,000 avg views
@competitor2 | 180,000 followers | 7.8% eng | 3.2/wk | 650,000 avg views
@competitor3 | 120,000 followers | 5.1% eng | 5.0/wk | 320,000 avg views
Benchmark avg: 6.4% engagement, 4.2 posts/week
Cost: $0.030 (3 competitors x 2 calls)