Social listening tools like Brandwatch or Sprout Social charge $200-500/month for TikTok monitoring. This tutorial builds a lightweight brand mention tracker using the Scavio TikTok API that runs on a cron job and costs under $1/month. It searches for your brand name, tracks new mentions, and sends alerts when high-engagement content mentions your brand. Each search costs 1 credit ($0.005).
Prerequisites
- Python 3.9+ installed
- requests library installed
- A Scavio API key from scavio.dev
- A cron job runner or scheduler
Walkthrough
Step 1: Set up brand mention search
Search TikTok for videos mentioning your brand. Track unique video IDs to detect new mentions on each run.
import requests, os, json, time
from pathlib import Path
API_KEY = os.environ['SCAVIO_API_KEY']
TT_URL = 'https://api.scavio.dev/api/v1/tiktok'
STATE_FILE = 'tiktok_mentions_state.json'
def load_state() -> dict:
if Path(STATE_FILE).exists():
return json.loads(Path(STATE_FILE).read_text())
return {'seen_ids': [], 'total_mentions': 0, 'last_run': ''}
def save_state(state: dict):
Path(STATE_FILE).write_text(json.dumps(state, indent=2))
def search_brand(brand_name: str, count: int = 20) -> list:
resp = requests.post(f'{TT_URL}/search/videos',
headers={'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'},
json={'keyword': brand_name, 'count': count, 'cursor': 0})
resp.raise_for_status()
videos = resp.json().get('data', {}).get('videos', [])
return [{
'id': v.get('id', ''),
'author': v.get('author', {}).get('uniqueId', ''),
'desc': v.get('desc', ''),
'plays': v.get('stats', {}).get('playCount', 0),
'likes': v.get('stats', {}).get('diggCount', 0),
'create_time': v.get('createTime', 0),
} for v in videos]
videos = search_brand('scavio')
print(f'Found {len(videos)} videos mentioning brand')Step 2: Detect new mentions and score importance
Compare current results against previously seen video IDs. Score new mentions by engagement to prioritize which deserve attention.
from datetime import datetime
def check_mentions(brand_name: str) -> dict:
state = load_state()
seen = set(state['seen_ids'])
videos = search_brand(brand_name)
new_mentions = [v for v in videos if v['id'] not in seen]
# Score new mentions by engagement
for v in new_mentions:
engagement = v['plays'] + v['likes'] * 10 # likes weighted higher
if engagement > 100_000:
v['priority'] = 'high'
elif engagement > 10_000:
v['priority'] = 'medium'
else:
v['priority'] = 'low'
# Update state
state['seen_ids'] = list(seen | {v['id'] for v in videos})
state['total_mentions'] += len(new_mentions)
state['last_run'] = datetime.now().isoformat()
save_state(state)
return {
'new_mentions': len(new_mentions),
'total_tracked': len(state['seen_ids']),
'high_priority': [v for v in new_mentions if v.get('priority') == 'high'],
'all_new': new_mentions
}
result = check_mentions('scavio')
print(f'New mentions: {result["new_mentions"]}')
print(f'High priority: {len(result["high_priority"])}')
for v in result['all_new'][:5]:
print(f' [{v["priority"]}] @{v["author"]}: {v["plays"]:,} plays - {v["desc"][:40]}')Step 3: Set up automated monitoring with cost tracking
Run the monitor on a schedule and track monthly costs. At 4 checks per day with 2 brand terms, monthly cost is under $1.20.
def daily_monitor(brand_terms: list) -> dict:
"""Run once per scheduled check (e.g., every 6 hours via cron)."""
all_new = []
credits_used = 0
for term in brand_terms:
result = check_mentions(term)
all_new.extend(result['all_new'])
credits_used += 1
time.sleep(0.3)
# Alert on high-priority mentions
high = [v for v in all_new if v.get('priority') == 'high']
if high:
print(f'ALERT: {len(high)} high-engagement mentions detected!')
for v in high:
print(f' @{v["author"]}: {v["plays"]:,} plays')
daily_cost = credits_used * 0.005
checks_per_day = 4
monthly_cost = daily_cost * checks_per_day * 30
print(f'\nCredits this run: {credits_used} (${daily_cost:.3f})')
print(f'Estimated monthly cost: ${monthly_cost:.2f}')
print(f'vs Brandwatch: $200+/month')
return {'new': len(all_new), 'high_priority': len(high), 'cost': daily_cost}
# Run with your brand terms
brand_terms = ['scavio', 'scavio api']
daily_monitor(brand_terms)
# Cron setup (every 6 hours):
# 0 */6 * * * cd /path/to/project && python tiktok_monitor.pyPython Example
import requests, os, json, time
from pathlib import Path
API_KEY = os.environ['SCAVIO_API_KEY']
TT = 'https://api.scavio.dev/api/v1/tiktok'
def monitor(brand):
state_file = Path(f'{brand}_state.json')
seen = set(json.loads(state_file.read_text())['ids']) if state_file.exists() else set()
resp = requests.post(f'{TT}/search/videos',
headers={'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'},
json={'keyword': brand, 'count': 20, 'cursor': 0})
videos = resp.json().get('data', {}).get('videos', [])
new_ids = [v for v in videos if v.get('id', '') not in seen]
seen.update(v.get('id', '') for v in videos)
state_file.write_text(json.dumps({'ids': list(seen)}))
print(f'{brand}: {len(new_ids)} new mentions')
for v in new_ids[:3]:
print(f' @{v.get("author",{}).get("uniqueId","")} {v.get("stats",{}).get("playCount",0):,} plays')
monitor('scavio')JavaScript Example
const fs = require('fs');
const API_KEY = process.env.SCAVIO_API_KEY;
const TT = 'https://api.scavio.dev/api/v1/tiktok';
async function monitor(brand) {
const stateFile = `${brand}_state.json`;
const seen = new Set(fs.existsSync(stateFile) ? JSON.parse(fs.readFileSync(stateFile)).ids : []);
const resp = await fetch(`${TT}/search/videos`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ keyword: brand, count: 20, cursor: 0 })
});
const videos = (await resp.json()).data?.videos || [];
const newVids = videos.filter(v => !seen.has(v.id));
videos.forEach(v => seen.add(v.id));
fs.writeFileSync(stateFile, JSON.stringify({ ids: [...seen] }));
console.log(`${brand}: ${newVids.length} new mentions`);
newVids.slice(0, 3).forEach(v =>
console.log(` @${v.author?.uniqueId} ${v.stats?.playCount?.toLocaleString()} plays`));
}
monitor('scavio');Expected Output
Found 20 videos mentioning brand
New mentions: 4
High priority: 1
[high] @techreviewer: 250,000 plays - Just discovered scavio for my AI age
[medium] @devtips: 15,000 plays - Using scavio search API in my n8n wor
[low] @codelearn: 800 plays - Tutorial: adding search to your bot wi
ALERT: 1 high-engagement mentions detected!
@techreviewer: 250,000 plays
Credits this run: 2 ($0.010)
Estimated monthly cost: $1.20
vs Brandwatch: $200+/month