UGC campaigns on TikTok are hard to track because content is spread across hundreds of creators. This tracker monitors your campaign hashtag, counts creator participation, aggregates engagement metrics, and identifies top-performing UGC posts. Each campaign check costs $0.005.
Prerequisites
- Python 3.8+
- requests library
- A Scavio API key from scavio.dev
- Campaign hashtag to track
Walkthrough
Step 1: Monitor campaign hashtag performance
Pull all videos using your campaign hashtag and aggregate metrics.
import os, requests, json
from datetime import datetime
from collections import Counter
API_KEY = os.environ['SCAVIO_API_KEY']
TH = {'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'}
CAMPAIGN_HASHTAG = 'scaviochallenge'
def track_campaign(hashtag):
data = requests.post('https://api.scavio.dev/api/v1/tiktok/hashtag/videos',
headers=TH, json={'hashtag': hashtag}).json()
videos = data.get('videos', data.get('data', {}).get('videos', []))
campaign = {
'hashtag': hashtag,
'date': datetime.now().strftime('%Y-%m-%d'),
'total_videos': len(videos),
'total_plays': sum(v.get('stats', {}).get('playCount', 0) for v in videos),
'total_likes': sum(v.get('stats', {}).get('diggCount', 0) for v in videos),
'total_comments': sum(v.get('stats', {}).get('commentCount', 0) for v in videos),
'total_shares': sum(v.get('stats', {}).get('shareCount', 0) for v in videos),
'unique_creators': len(set(v.get('author', {}).get('uniqueId', '') for v in videos)),
'videos': videos,
}
return campaign
campaign = track_campaign(CAMPAIGN_HASHTAG)
print(f'Campaign: #{campaign["hashtag"]}')
print(f' Videos: {campaign["total_videos"]}')
print(f' Unique creators: {campaign["unique_creators"]}')
print(f' Total plays: {campaign["total_plays"]:,}')
print(f' Total likes: {campaign["total_likes"]:,}')
print(f' Total shares: {campaign["total_shares"]:,}')
if campaign['total_plays'] > 0:
er = (campaign['total_likes'] + campaign['total_comments'] + campaign['total_shares']) / campaign['total_plays']
print(f' Engagement rate: {er*100:.1f}%')
print(f'\nCost: $0.005')Step 2: Identify top creators and viral posts
Rank creators by performance and find the highest-performing UGC content.
def analyze_campaign(campaign):
videos = campaign['videos']
if not videos:
print(' No videos found.')
return
# Top videos by plays
sorted_by_plays = sorted(videos, key=lambda v: v.get('stats', {}).get('playCount', 0), reverse=True)
print(f'\n=== Top UGC Posts ===')
for v in sorted_by_plays[:5]:
stats = v.get('stats', {})
author = v.get('author', {}).get('uniqueId', 'unknown')
print(f' @{author:20} | {stats.get("playCount", 0):>10,} plays | {stats.get("diggCount", 0):>8,} likes')
print(f' {v.get("desc", "")[:60]}')
# Creator leaderboard
creator_stats = {}
for v in videos:
author = v.get('author', {}).get('uniqueId', 'unknown')
if author not in creator_stats:
creator_stats[author] = {'videos': 0, 'plays': 0, 'likes': 0}
creator_stats[author]['videos'] += 1
creator_stats[author]['plays'] += v.get('stats', {}).get('playCount', 0)
creator_stats[author]['likes'] += v.get('stats', {}).get('diggCount', 0)
print(f'\n=== Creator Leaderboard ===')
sorted_creators = sorted(creator_stats.items(), key=lambda x: x[1]['plays'], reverse=True)
for author, stats in sorted_creators[:5]:
print(f' @{author:20} | {stats["videos"]} videos | {stats["plays"]:>10,} plays')
return creator_stats
creator_stats = analyze_campaign(campaign)Step 3: Generate campaign performance report
Compile all metrics into a UGC campaign report with ROI estimates.
def campaign_report(campaign, creator_stats):
print(f'\n{"=" * 60}')
print(f' UGC CAMPAIGN REPORT - #{campaign["hashtag"]}')
print(f' Date: {campaign["date"]}')
print(f'{"=" * 60}')
print(f'\n Reach Metrics:')
print(f' Total plays: {campaign["total_plays"]:>12,}')
print(f' Total likes: {campaign["total_likes"]:>12,}')
print(f' Total comments: {campaign["total_comments"]:>12,}')
print(f' Total shares: {campaign["total_shares"]:>12,}')
print(f'\n Participation:')
print(f' Videos created: {campaign["total_videos"]}')
print(f' Unique creators: {campaign["unique_creators"]}')
if campaign['total_videos'] > 0:
avg_plays = campaign['total_plays'] / campaign['total_videos']
print(f' Avg plays/video: {avg_plays:,.0f}')
# Estimated CPM
if campaign['total_plays'] > 0:
er = (campaign['total_likes'] + campaign['total_comments']) / campaign['total_plays'] * 100
print(f'\n Quality Metrics:')
print(f' Engagement rate: {er:.1f}%')
if creator_stats:
multi_post = sum(1 for s in creator_stats.values() if s['videos'] > 1)
print(f' Repeat creators: {multi_post} ({multi_post/len(creator_stats)*100:.0f}%)')
print(f'\n Tracking cost: $0.005/scan')
print(f' Daily tracking: $0.15/month')
campaign_report(campaign, creator_stats)Python Example
import os, requests
TH = {'Authorization': f'Bearer {os.environ["SCAVIO_API_KEY"]}', 'Content-Type': 'application/json'}
def track_ugc(hashtag):
data = requests.post('https://api.scavio.dev/api/v1/tiktok/hashtag/videos',
headers=TH, json={'hashtag': hashtag}).json()
videos = data.get('videos', data.get('data', {}).get('videos', []))
plays = sum(v.get('stats', {}).get('playCount', 0) for v in videos)
print(f'#{hashtag}: {len(videos)} videos, {plays:,} plays')
track_ugc('scaviochallenge')
print('Cost: $0.005')JavaScript Example
const TH = { 'Authorization': `Bearer ${process.env.SCAVIO_API_KEY}`, 'Content-Type': 'application/json' };
const data = await fetch('https://api.scavio.dev/api/v1/tiktok/hashtag/videos', {
method: 'POST', headers: TH, body: JSON.stringify({ hashtag: 'scaviochallenge' })
}).then(r => r.json());
const videos = data.videos || data.data?.videos || [];
console.log(`Videos: ${videos.length}, Plays: ${videos.reduce((s, v) => s + (v.stats?.playCount || 0), 0)}`);Expected Output
Campaign: #scaviochallenge
Videos: 18
Unique creators: 12
Total plays: 450,000
Total likes: 38,000
Total shares: 5,200
Engagement rate: 9.6%
=== Top UGC Posts ===
@techreviewer123 | 120,000 plays | 10,500 likes
This search API changed my workflow #scaviochallenge
=== Creator Leaderboard ===
@techreviewer123 | 2 videos | 180,000 plays
============================================================
UGC CAMPAIGN REPORT - #scaviochallenge
Date: 2026-05-21
============================================================
Tracking cost: $0.005/scan
Daily tracking: $0.15/month