The first three seconds of a TikTok video determine whether viewers keep watching or scroll away. This tutorial uses the Scavio TikTok API to pull video data for top-performing content in your niche, then analyzes which hook patterns correlate with the highest engagement rates. By comparing video descriptions, view-to-like ratios, and share counts across different hook styles, you can identify what opening patterns work best. Each API call costs $0.005.
Prerequisites
- Python 3.9+ installed
- requests library installed
- A Scavio API key from scavio.dev
- A niche or topic to analyze hooks for
Walkthrough
Step 1: Collect high-performing videos in your niche
Search for videos in your niche and pull the top performers. Their video descriptions often reflect the hook style used in the first few seconds.
import os, requests, time, re
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'}
def search_niche_videos(niche: str, count: int = 30) -> list:
resp = requests.post(f'{TT_URL}/search/videos', headers=TT_H,
json={'keyword': niche, 'count': count, 'cursor': 0})
videos = resp.json().get('data', {}).get('videos', [])
results = []
for v in videos:
stats = v.get('stats', {})
views = stats.get('playCount', 0)
likes = stats.get('diggCount', 0)
results.append({
'desc': v.get('desc', ''),
'views': views,
'likes': likes,
'comments': stats.get('commentCount', 0),
'shares': stats.get('shareCount', 0),
'like_rate': likes / views if views > 0 else 0,
'share_rate': stats.get('shareCount', 0) / views if views > 0 else 0,
})
results.sort(key=lambda x: x['views'], reverse=True)
return results
videos = search_niche_videos('python programming tutorial')
print(f'Collected {len(videos)} videos')Step 2: Classify hook patterns from video descriptions
Categorize videos by their hook style based on description text. Common hook types include question hooks, claim hooks, how-to hooks, and controversy hooks.
HOOK_PATTERNS = {
'question': [r'^(did you|have you|do you|why|what if|how)', r'\?'],
'claim': [r'^(this|the|I found|I discovered|most people)', r'(secret|trick|hack|mistake)'],
'how_to': [r'^(how to|step|tutorial|learn|guide)', r'(in \d+ (?:seconds|minutes|steps))'],
'controversy': [r'(stop|dont|never|wrong|bad|overrated)', r'(unpopular|hot take|controversial)'],
'listicle': [r'^(\d+ |top \d+|best \d+)', r'(things|tips|tools|ways|reasons)'],
}
def classify_hook(desc: str) -> str:
desc_lower = desc.lower()
scores = {}
for hook_type, patterns in HOOK_PATTERNS.items():
score = sum(1 for p in patterns if re.search(p, desc_lower))
scores[hook_type] = score
best = max(scores, key=scores.get)
return best if scores[best] > 0 else 'other'
for v in videos[:5]:
hook = classify_hook(v['desc'])
print(f' [{hook:12s}] {v["like_rate"]:.1%} like rate | {v["desc"][:50]}')Step 3: Analyze engagement by hook type
Group videos by hook type and compare average engagement rates. This reveals which hook styles drive the best performance in your niche.
def analyze_hooks(videos: list) -> dict:
by_hook = {}
for v in videos:
hook = classify_hook(v['desc'])
if hook not in by_hook:
by_hook[hook] = []
by_hook[hook].append(v)
report = {}
for hook_type, vids in by_hook.items():
avg_like_rate = sum(v['like_rate'] for v in vids) / len(vids)
avg_share_rate = sum(v['share_rate'] for v in vids) / len(vids)
avg_views = sum(v['views'] for v in vids) / len(vids)
report[hook_type] = {
'count': len(vids),
'avg_like_rate': avg_like_rate,
'avg_share_rate': avg_share_rate,
'avg_views': avg_views,
'best_video': max(vids, key=lambda x: x['views'])['desc'][:50],
}
print('Hook Analysis Report')
print('=' * 65)
for hook, stats in sorted(report.items(), key=lambda x: x[1]['avg_like_rate'], reverse=True):
print(f' {hook:12s} | {stats["count"]:3d} videos | {stats["avg_like_rate"]:5.1%} like rate | {stats["avg_views"]:>10,.0f} avg views')
print(f' | Best: {stats["best_video"]}')
return report
report = analyze_hooks(videos)Python Example
import os, requests, re
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
TT_H = {'Authorization': f'Bearer {SCAVIO_KEY}', 'Content-Type': 'application/json'}
def analyze_hooks(niche):
resp = requests.post('https://api.scavio.dev/api/v1/tiktok/search/videos', headers=TT_H,
json={'keyword': niche, 'count': 20, 'cursor': 0})
videos = resp.json().get('data', {}).get('videos', [])
hooks = {'question': [], 'how_to': [], 'claim': [], 'other': []}
for v in videos:
desc = v.get('desc', '').lower()
stats = v.get('stats', {})
views = stats.get('playCount', 1)
like_rate = stats.get('diggCount', 0) / views
if '?' in desc or desc.startswith(('did', 'why', 'what')): cat = 'question'
elif desc.startswith(('how to', 'tutorial', 'learn')): cat = 'how_to'
elif any(w in desc for w in ['secret', 'hack', 'trick']): cat = 'claim'
else: cat = 'other'
hooks[cat].append(like_rate)
for cat, rates in hooks.items():
avg = sum(rates) / len(rates) if rates else 0
print(f'{cat:12s}: {len(rates):3d} videos, {avg:.1%} avg like rate')
analyze_hooks('python programming')JavaScript Example
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const TT_H = { Authorization: `Bearer ${SCAVIO_KEY}`, 'Content-Type': 'application/json' };
async function analyzeHooks(niche) {
const resp = await fetch('https://api.scavio.dev/api/v1/tiktok/search/videos', {
method: 'POST', headers: TT_H, body: JSON.stringify({ keyword: niche, count: 20, cursor: 0 })
}).then(r => r.json());
const hooks = { question: [], how_to: [], claim: [], other: [] };
for (const v of (resp.data?.videos || [])) {
const desc = (v.desc || '').toLowerCase();
const views = v.stats?.playCount || 1;
const likeRate = (v.stats?.diggCount || 0) / views;
let cat = 'other';
if (desc.includes('?') || desc.startsWith('did') || desc.startsWith('why')) cat = 'question';
else if (desc.startsWith('how to') || desc.startsWith('tutorial')) cat = 'how_to';
else if (['secret', 'hack', 'trick'].some(w => desc.includes(w))) cat = 'claim';
hooks[cat].push(likeRate);
}
for (const [cat, rates] of Object.entries(hooks)) {
const avg = rates.length ? rates.reduce((a, b) => a + b, 0) / rates.length : 0;
console.log(`${cat}: ${rates.length} videos, ${(avg * 100).toFixed(1)}% avg like rate`);
}
}
analyzeHooks('python programming');Expected Output
Collected 30 videos
Hook Analysis Report
=================================================================
question | 8 videos | 8.2% like rate | 890,000 avg views
| Best: Did you know Python can do this in one lin
claim | 6 videos | 7.5% like rate | 1,200,000 avg views
| Best: This Python trick will save you hours of c
how_to | 10 videos | 5.8% like rate | 650,000 avg views
| Best: How to build an API in 60 seconds with Fas
controversy | 3 videos | 9.1% like rate | 780,000 avg views
| Best: Stop using print for debugging in Python
other | 3 videos | 4.2% like rate | 320,000 avg views