Tutorial

How to Build a TikTok Influencer Scorer

Score TikTok influencers by engagement, consistency, and audience quality using the TikTok API. Automated vetting pipeline in Python.

Vetting TikTok influencers for brand partnerships requires analyzing multiple signals: engagement rate, posting consistency, follower growth patterns, and content relevance. Manual vetting takes hours per creator. This tutorial builds an automated scoring system using the Scavio TikTok API that fetches creator profiles and recent videos, calculates engagement metrics, and outputs a composite score. Each API call costs 1 credit ($0.005), and a full creator analysis uses 2-3 credits.

Prerequisites

  • Python 3.9+ installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • TikTok usernames or secUids of influencers to evaluate

Walkthrough

Step 1: Fetch creator profile data

Get the creator profile including follower count, following count, total likes, and video count. This is the foundation for all scoring metrics.

Python
import requests, os

API_KEY = os.environ['SCAVIO_API_KEY']
TIKTOK_URL = 'https://api.scavio.dev/api/v1/tiktok'

def get_profile(username: str) -> dict:
    resp = requests.post(f'{TIKTOK_URL}/user/info',
        headers={'Authorization': f'Bearer {API_KEY}',
                 'Content-Type': 'application/json'},
        json={'username': username})
    resp.raise_for_status()
    user = resp.json().get('data', {}).get('user', {})
    stats = resp.json().get('data', {}).get('stats', {})
    return {
        'username': user.get('uniqueId', ''),
        'nickname': user.get('nickname', ''),
        'verified': user.get('verified', False),
        'followers': stats.get('followerCount', 0),
        'following': stats.get('followingCount', 0),
        'likes': stats.get('heartCount', 0),
        'videos': stats.get('videoCount', 0)
    }

profile = get_profile('example_creator')
print(f'{profile["username"]}: {profile["followers"]:,} followers, {profile["videos"]} videos')

Step 2: Fetch recent videos for engagement analysis

Get the creator's recent videos to calculate actual engagement rates. Profile-level stats can be misleading without per-video analysis.

Python
def get_recent_videos(username: str, count: int = 20) -> list:
    resp = requests.post(f'{TIKTOK_URL}/user/posts',
        headers={'Authorization': f'Bearer {API_KEY}',
                 'Content-Type': 'application/json'},
        json={'username': username, 'count': count, 'cursor': 0})
    resp.raise_for_status()
    videos = resp.json().get('data', {}).get('videos', [])
    return [{
        'id': v.get('id', ''),
        'desc': v.get('desc', ''),
        'plays': v.get('stats', {}).get('playCount', 0),
        'likes': v.get('stats', {}).get('diggCount', 0),
        'comments': v.get('stats', {}).get('commentCount', 0),
        'shares': v.get('stats', {}).get('shareCount', 0),
        'create_time': v.get('createTime', 0)
    } for v in videos]

videos = get_recent_videos('example_creator')
print(f'Fetched {len(videos)} recent videos')

Step 3: Calculate engagement and consistency scores

Compute engagement rate per video, average engagement, posting frequency, and content consistency. These metrics form the scoring components.

Python
import statistics
from datetime import datetime

def calculate_metrics(profile: dict, videos: list) -> dict:
    if not videos:
        return {'engagement_rate': 0, 'consistency': 0, 'avg_plays': 0}
    followers = max(profile['followers'], 1)
    # Per-video engagement rate
    engagement_rates = []
    for v in videos:
        total_engagement = v['likes'] + v['comments'] + v['shares']
        rate = (total_engagement / max(v['plays'], 1)) * 100
        engagement_rates.append(rate)
    avg_engagement = statistics.mean(engagement_rates)
    engagement_stdev = statistics.stdev(engagement_rates) if len(engagement_rates) > 1 else 0
    # Posting consistency (days between posts)
    timestamps = sorted([v['create_time'] for v in videos if v['create_time']])
    if len(timestamps) > 1:
        gaps = [(timestamps[i+1] - timestamps[i]) / 86400
                for i in range(len(timestamps) - 1)]
        avg_gap = statistics.mean(gaps)
        gap_stdev = statistics.stdev(gaps) if len(gaps) > 1 else avg_gap
    else:
        avg_gap = 30
        gap_stdev = 30
    avg_plays = statistics.mean([v['plays'] for v in videos])
    return {
        'avg_engagement_rate': round(avg_engagement, 2),
        'engagement_consistency': round(100 - min(engagement_stdev * 10, 100), 1),
        'avg_days_between_posts': round(avg_gap, 1),
        'posting_consistency': round(100 - min(gap_stdev * 10, 100), 1),
        'avg_plays': int(avg_plays),
        'likes_to_followers': round((statistics.mean([v['likes'] for v in videos]) / followers) * 100, 2)
    }

Step 4: Build the composite influencer score

Combine all metrics into a single 0-100 score with weighted components. Higher scores indicate better partnership potential.

Python
def score_influencer(profile: dict, metrics: dict) -> dict:
    # Engagement score (0-40 points)
    eng_rate = metrics['avg_engagement_rate']
    engagement_score = min(eng_rate * 5, 40)  # 8%+ engagement = max score
    # Consistency score (0-20 points)
    consistency_score = (metrics['engagement_consistency'] +
                         metrics['posting_consistency']) / 10
    consistency_score = min(consistency_score, 20)
    # Reach score (0-20 points)
    followers = profile['followers']
    if followers >= 1000000:
        reach_score = 20
    elif followers >= 100000:
        reach_score = 15
    elif followers >= 10000:
        reach_score = 10
    elif followers >= 1000:
        reach_score = 5
    else:
        reach_score = 2
    # Authenticity score (0-20 points)
    # High following/follower ratio = potential fake engagement
    ratio = profile['following'] / max(profile['followers'], 1)
    auth_score = 20 if ratio < 0.1 else 15 if ratio < 0.3 else 10 if ratio < 0.5 else 5
    total = round(engagement_score + consistency_score + reach_score + auth_score, 1)
    return {
        'total_score': total,
        'engagement_score': round(engagement_score, 1),
        'consistency_score': round(consistency_score, 1),
        'reach_score': reach_score,
        'authenticity_score': auth_score,
        'grade': 'A' if total >= 80 else 'B' if total >= 60 else 'C' if total >= 40 else 'D'
    }

Step 5: Run the full scoring pipeline

Combine all steps into a single function that takes a username and returns a complete influencer report. Batch score multiple creators.

Python
import time

def full_influencer_report(username: str) -> dict:
    profile = get_profile(username)
    videos = get_recent_videos(username, count=20)
    metrics = calculate_metrics(profile, videos)
    scores = score_influencer(profile, metrics)
    return {
        'profile': profile,
        'metrics': metrics,
        'scores': scores,
        'credits_used': 2  # 1 for profile + 1 for videos
    }

def batch_score(usernames: list) -> list:
    reports = []
    for username in usernames:
        report = full_influencer_report(username)
        reports.append(report)
        p = report['profile']
        s = report['scores']
        print(f'{p["username"]}: {s["total_score"]}/100 ({s["grade"]}) - '
              f'{p["followers"]:,} followers, '
              f'{report["metrics"]["avg_engagement_rate"]}% engagement')
        time.sleep(0.3)
    total_credits = sum(r['credits_used'] for r in reports)
    print(f'\nTotal credits: {total_credits} (${total_credits * 0.005:.2f})')
    return sorted(reports, key=lambda r: r['scores']['total_score'], reverse=True)

# Score multiple influencers:
# ranked = batch_score(['creator1', 'creator2', 'creator3'])

Python Example

Python
import os, requests, statistics, time

API_KEY = os.environ['SCAVIO_API_KEY']
TT = 'https://api.scavio.dev/api/v1/tiktok'

def tiktok(endpoint, body):
    return requests.post(f'{TT}/{endpoint}',
        headers={'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'},
        json=body).json()

def score_creator(username):
    profile = tiktok('user/info', {'username': username}).get('data', {})
    stats = profile.get('stats', {})
    videos_data = tiktok('user/posts', {'username': username, 'count': 20, 'cursor': 0})
    videos = videos_data.get('data', {}).get('videos', [])
    if not videos:
        return {'username': username, 'score': 0}
    eng_rates = [(v['stats']['diggCount'] + v['stats']['commentCount']) /
                 max(v['stats']['playCount'], 1) * 100 for v in videos
                 if v.get('stats')]
    avg_eng = statistics.mean(eng_rates) if eng_rates else 0
    return {'username': username, 'followers': stats.get('followerCount', 0),
            'engagement': round(avg_eng, 2), 'score': min(round(avg_eng * 10), 100)}

result = score_creator('example_creator')
print(f'{result["username"]}: {result["score"]}/100 ({result["engagement"]}% engagement)')

JavaScript Example

JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
const TT = 'https://api.scavio.dev/api/v1/tiktok';

async function tiktokApi(endpoint, body) {
  const resp = await fetch(`${TT}/${endpoint}`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(body)
  });
  return resp.json();
}

async function scoreCreator(username) {
  const profile = await tiktokApi('user/info', { username });
  const stats = profile.data?.stats || {};
  const postsData = await tiktokApi('user/posts', { username, count: 20, cursor: 0 });
  const videos = postsData.data?.videos || [];
  const engRates = videos.map(v => {
    const s = v.stats || {};
    return ((s.diggCount || 0) + (s.commentCount || 0)) / Math.max(s.playCount || 1, 1) * 100;
  });
  const avgEng = engRates.reduce((a, b) => a + b, 0) / Math.max(engRates.length, 1);
  console.log(`${username}: ${Math.min(Math.round(avgEng * 10), 100)}/100 (${avgEng.toFixed(2)}% eng)`);
}

scoreCreator('example_creator').catch(console.error);

Expected Output

JSON
example_creator: 87,432 followers, 156 videos
Fetched 20 recent videos

example_creator: 72.5/100 (B)
  Engagement: 32.5/40 (6.5% avg rate)
  Consistency: 16.8/20
  Reach: 10/20
  Authenticity: 15/20

Total credits: 2 ($0.01)

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.9+ installed. requests library installed. A Scavio API key from scavio.dev. TikTok usernames or secUids of influencers to evaluate. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Score TikTok influencers by engagement, consistency, and audience quality using the TikTok API. Automated vetting pipeline in Python.