TikTok Brand Safety: Creator Vetting API
Vet TikTok creators before paying them. API checks: follower authenticity, content history, engagement patterns, audience demographics. Automated pipeline.
Before spending $5K or more on a TikTok creator partnership, vet their content and audience programmatically. A creator vetting pipeline checks comment sentiment, follower authenticity via follower-to-following ratio, content history for brand safety red flags, and existing brand mention context. Total API cost per creator: roughly $0.04.
What the Vetting Pipeline Checks
- Profile metrics: follower count, video count, total likes, engagement rate
- Follower authenticity: follower/following ratio. Ratios below 2:1 for accounts with 100K+ followers are suspect.
- Content history: scan recent posts for controversial topics, competitor mentions, brand safety issues
- Comment sentiment: are real people engaging, or is it bot comments and spam?
- Brand mention context: if they have mentioned your brand or competitors, what was the tone?
Step 1: Profile Analysis
import requests, os
API_KEY = os.environ["SCAVIO_API_KEY"]
BASE = "https://api.scavio.dev/api/v1/tiktok"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def get_creator_profile(username: str) -> dict:
resp = requests.post(f"{BASE}/profile",
headers=HEADERS,
json={"username": username}, timeout=15)
user = resp.json()["data"]["user"]
stats = resp.json()["data"]["stats"]
follower_ratio = round(stats["followerCount"] / max(stats["followingCount"], 1), 1)
engagement_rate = round(stats["heartCount"] / max(stats["followerCount"], 1) * 100 / max(stats["videoCount"], 1), 2)
return {
"username": user["uniqueId"],
"followers": stats["followerCount"],
"following": stats["followingCount"],
"videos": stats["videoCount"],
"total_likes": stats["heartCount"],
"follower_ratio": follower_ratio,
"engagement_rate": engagement_rate,
"verified": user.get("verified", False),
"flags": get_profile_flags(stats, follower_ratio),
}
def get_profile_flags(stats: dict, ratio: float) -> list:
flags = []
if stats["followerCount"] > 100000 and ratio < 2:
flags.append("Low follower/following ratio - possible purchased followers")
if stats["videoCount"] < 10:
flags.append("Very few videos for claimed audience size")
if stats["heartCount"] / max(stats["videoCount"], 1) < 100:
flags.append("Low average likes per video")
return flagsStep 2: Content History Scan
BRAND_SAFETY_KEYWORDS = {
"politics", "conspiracy", "scam", "fake", "lawsuit",
"controversy", "arrested", "banned", "exposed",
}
def scan_content_history(username: str, count: int = 20) -> dict:
resp = requests.post(f"{BASE}/user/posts",
headers=HEADERS,
json={"username": username, "count": count}, timeout=15)
videos = resp.json().get("data", {}).get("aweme_list", [])
flagged = []
topics = []
for v in videos:
desc = v.get("desc", "").lower()
words = set(desc.split())
matches = words & BRAND_SAFETY_KEYWORDS
if matches:
flagged.append({"desc": v["desc"][:100], "flags": list(matches),
"views": v["statistics"]["play_count"]})
topics.append(desc[:80])
return {
"total_scanned": len(videos),
"flagged_count": len(flagged),
"flagged_posts": flagged,
"recent_topics": topics[:10],
}Step 3: Comment Sentiment Analysis
def analyze_comments(username: str, video_count: int = 5) -> dict:
resp = requests.post(f"{BASE}/user/posts",
headers=HEADERS,
json={"username": username, "count": video_count}, timeout=15)
videos = resp.json().get("data", {}).get("aweme_list", [])
all_comments = []
bot_signals = 0
for v in videos[:video_count]:
video_id = v["aweme_id"]
c_resp = requests.post(f"{BASE}/video/comments",
headers=HEADERS,
json={"video_id": video_id, "count": 20}, timeout=15)
comments = c_resp.json().get("data", {}).get("comments", [])
for c in comments:
text = c.get("text", "")
all_comments.append(text)
# Bot signals: very short, generic praise, emoji-only
if len(text) < 5 or text in ("nice", "wow", "amazing", "love it"):
bot_signals += 1
total = max(len(all_comments), 1)
return {
"total_comments_analyzed": len(all_comments),
"bot_signal_pct": round(bot_signals / total * 100, 1),
"sample_comments": all_comments[:10],
"flags": ["High bot comment percentage"] if bot_signals / total > 0.4 else [],
}Step 4: Full Vetting Report
def vet_creator(username: str) -> dict:
profile = get_creator_profile(username) # 1 credit
content = scan_content_history(username, count=20) # 1 credit
comments = analyze_comments(username, video_count=5) # 6 credits (1 posts + 5 comments)
all_flags = profile["flags"] + content.get("flagged_posts", []) + comments["flags"]
risk_score = min(len(all_flags) * 20, 100)
report = {
"username": username,
"profile": profile,
"content_scan": content,
"comment_analysis": comments,
"risk_score": risk_score,
"risk_level": "low" if risk_score < 30 else "medium" if risk_score < 60 else "high",
"total_flags": len(all_flags),
"recommendation": "proceed" if risk_score < 30 else "review flags" if risk_score < 60 else "do not proceed",
"api_credits_used": 8,
"api_cost": "$0.04",
}
return report
report = vet_creator("example_creator")
print(f"Risk: {report['risk_level']} (score: {report['risk_score']})")
for f in report["profile"]["flags"]:
print(f" Profile: {f}")
if report["content_scan"]["flagged_count"] > 0:
print(f" Content: {report['content_scan']['flagged_count']} flagged posts")Cost Breakdown
- Profile lookup: 1 credit
- Post history (20 posts): 1 credit
- Comments on 5 videos: 5 credits
- Brand mention search (optional): 1 credit
- Total per creator: ~8 credits = $0.04
- Vetting 50 creators for a campaign: 400 credits = $2.00
- Compare: manual vetting takes 15-30 min per creator. At $50/hr, 50 creators = $625-$1,250 in labor.
Limitations
Keyword-based brand safety scanning catches obvious issues but misses context. A creator discussing a brand "controversy" might be defending the brand. Bot detection via short comments is a rough heuristic -- real humans also write "nice" and "wow." Follower/following ratio is a signal, not proof. Use the automated pipeline as a first pass to filter out obvious risks, then have a human review the shortlisted creators before signing contracts.