Overview
Collect user-generated content from a branded TikTok campaign by monitoring campaign hashtags and brand mention searches. Catalog every UGC video with creator info, engagement metrics, and content metadata. Track campaign reach and identify top-performing creators for follow-up.
Trigger
Every 4 hours during active campaigns
Schedule
Every 4 hours during active campaigns
Workflow Steps
Monitor campaign hashtag
Pull latest videos from the campaign hashtag. Track total view count growth and new video submissions.
Search for untagged UGC
Search for videos mentioning the brand or product without the campaign hashtag. These are organic UGC that missed the official tag.
Catalog each video
Record video ID, creator username, post time, views, likes, comments, shares, and description text.
Rank creators by impact
Sort UGC creators by total engagement generated. Identify micro-creators with outsized engagement relative to follower count.
Export campaign report
Generate a campaign UGC report with total submissions, reach, top creators, and engagement benchmarks.
Python Implementation
import requests, os, json
H = {"Authorization": f"Bearer {os.environ['SCAVIO_API_KEY']}", "Content-Type": "application/json"}
BASE = "https://api.scavio.dev"
def collect_ugc(campaign_hashtag, brand_query, max_pages=5):
ugc = {}
params = {"hashtag": campaign_hashtag, "count": 20}
for _ in range(max_pages):
resp = requests.post(f"{BASE}/api/v1/tiktok/hashtag/videos",
headers=H, json=params).json()
for v in resp["data"].get("videos", []):
ugc[v["aweme_id"]] = {
"creator": v.get("author", {}).get("unique_id", ""),
"views": v.get("statistics", {}).get("play_count", 0),
"likes": v.get("statistics", {}).get("digg_count", 0),
"desc": v.get("desc", "")[:100],
"source": "hashtag",
}
if not resp["data"].get("has_more"):
break
params["cursor"] = resp["data"].get("cursor")
search_resp = requests.post(f"{BASE}/api/v1/tiktok/search/videos",
headers=H, json={"query": brand_query, "count": 20}).json()
for v in search_resp["data"].get("videos", []):
if v["aweme_id"] not in ugc:
ugc[v["aweme_id"]] = {
"creator": v.get("author", {}).get("unique_id", ""),
"views": v.get("statistics", {}).get("play_count", 0),
"likes": v.get("statistics", {}).get("digg_count", 0),
"desc": v.get("desc", "")[:100],
"source": "search",
}
ranked = sorted(ugc.values(), key=lambda x: x["likes"], reverse=True)
return ranked
results = collect_ugc("brandchallenge", "brand name review")
print(f"Collected {len(results)} UGC videos")
for r in results[:5]:
print(f" @{r['creator']}: {r['views']:,} views, {r['likes']:,} likes ({r['source']})")JavaScript Implementation
const BASE = "https://api.scavio.dev";
const H = { Authorization: `Bearer ${process.env.SCAVIO_API_KEY}`, "Content-Type": "application/json" };
async function collectUGC(hashtag, brandQuery) {
const hashResp = await fetch(`${BASE}/api/v1/tiktok/hashtag/videos`, {
method: "POST", headers: H, body: JSON.stringify({ hashtag, count: 20 })
}).then(r => r.json());
const searchResp = await fetch(`${BASE}/api/v1/tiktok/search/videos`, {
method: "POST", headers: H, body: JSON.stringify({ query: brandQuery, count: 20 })
}).then(r => r.json());
const videos = [...(hashResp.data.videos || []), ...(searchResp.data.videos || [])];
console.log(`Collected ${videos.length} UGC videos`);
videos.sort((a, b) => (b.statistics?.digg_count || 0) - (a.statistics?.digg_count || 0));
videos.slice(0, 5).forEach(v =>
console.log(` @${v.author?.unique_id}: ${v.statistics?.play_count?.toLocaleString()} views`));
}
collectUGC("brandchallenge", "brand name review");Platforms Used
TikTok
Trending video, creator, and product discovery