ScavioScavio
ProductPricingDocs
Sign InGet Started
  1. Home
  2. Workflows
  3. TikTok Hashtag Campaign Tracker
Workflow

TikTok Hashtag Campaign Tracker

Monitor TikTok campaign hashtag video counts and engagement every 6 hours. Detect viral moments and engagement spikes automatically.

Start FreeAPI Docs

Overview

Polls tracked campaign hashtags every 6 hours, records video count and engagement totals, calculates growth velocity, and flags viral moments when video count or engagement grows more than 50% in a 6-hour window.

Trigger

Every 6 hours (cron: 0 */6 * * *)

Schedule

Every 6 hours (cron: 0 */6 * * *)

Workflow Steps

1

Fetch hashtag stats

POST to Scavio TikTok hashtag endpoint for each tracked hashtag. Extract video_count and total_view_count from the response.

2

Store snapshot

Write hashtag, video_count, view_count, and timestamp to a snapshots table.

3

Calculate growth velocity

Compare current video_count and view_count against the snapshot from 6 hours ago. Calculate new_videos and new_views in the window.

4

Detect viral threshold

Flag if new_videos in the window exceeds a threshold (e.g., 200 new videos in 6 hours for a mid-size campaign). Thresholds are configurable per hashtag.

5

Alert on viral detection

Send Slack or webhook alert with hashtag name, new video count, view velocity (views per hour), and a TikTok link to the hashtag page.

Python Implementation

Python
import sqlite3
import requests
from datetime import datetime, timedelta
import time

DB_PATH = "tiktok_campaigns.db"
SCRAVIO_KEY = "YOUR_API_KEY"
API_BASE = "https://api.scavio.dev/api/v1/tiktok"
HEADERS = {"Authorization": f"Bearer {SCRAVIO_KEY}"}
ALERT_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK"
VIRAL_VIDEO_THRESHOLD = 200  # new videos per 6h window

def init_db():
    conn = sqlite3.connect(DB_PATH)
    conn.executescript("""
        CREATE TABLE IF NOT EXISTS hashtags (hashtag TEXT PRIMARY KEY, viral_threshold INTEGER DEFAULT 200);
        CREATE TABLE IF NOT EXISTS snapshots (
            hashtag TEXT, video_count INTEGER, view_count INTEGER, ts TEXT
        );
    """)
    conn.commit()
    return conn

def fetch_hashtag_stats(hashtag: str) -> dict:
    resp = requests.post(
        f"{API_BASE}/hashtag/info",
        headers=HEADERS,
        json={"hashtag": hashtag}
    )
    resp.raise_for_status()
    data = resp.json().get("data", {})
    return {
        "video_count": data.get("videoCount", 0),
        "view_count": data.get("viewCount", 0)
    }

def run():
    conn = init_db()
    now = datetime.utcnow().isoformat()
    six_hours_ago = (datetime.utcnow() - timedelta(hours=6)).isoformat()
    hashtags = conn.execute("SELECT hashtag, viral_threshold FROM hashtags").fetchall()
    for hashtag, threshold in hashtags:
        stats = fetch_hashtag_stats(hashtag)
        conn.execute("INSERT INTO snapshots VALUES (?,?,?,?)",
                     (hashtag, stats["video_count"], stats["view_count"], now))
        prev = conn.execute(
            "SELECT video_count, view_count FROM snapshots "
            "WHERE hashtag=? AND ts <= ? ORDER BY ts DESC LIMIT 1",
            (hashtag, six_hours_ago)
        ).fetchone()
        if prev:
            new_videos = stats["video_count"] - prev[0]
            new_views = stats["view_count"] - prev[1]
            views_per_hour = new_views // 6
            if new_videos >= (threshold or VIRAL_VIDEO_THRESHOLD):
                requests.post(ALERT_WEBHOOK, json={
                    "text": f"Viral alert #{hashtag}: +{new_videos} videos in 6h, +{views_per_hour:,} views/hr. https://tiktok.com/tag/{hashtag}"
                })
        conn.commit()
        time.sleep(0.5)

if __name__ == "__main__":
    run()

JavaScript Implementation

JavaScript
const Database = require('better-sqlite3');
const fetch = require('node-fetch');

const DB_PATH = 'tiktok_campaigns.db';
const API_BASE = 'https://api.scavio.dev/api/v1/tiktok';
const SCRAVIO_KEY = 'YOUR_API_KEY';
const HEADERS = { 'Authorization': `Bearer ${SCRAVIO_KEY}`, 'Content-Type': 'application/json' };
const ALERT_WEBHOOK = 'https://hooks.slack.com/services/YOUR/WEBHOOK';

const db = new Database(DB_PATH);
db.exec(`
  CREATE TABLE IF NOT EXISTS hashtags (hashtag TEXT PRIMARY KEY, viral_threshold INTEGER DEFAULT 200);
  CREATE TABLE IF NOT EXISTS snapshots (hashtag TEXT, video_count INTEGER, view_count INTEGER, ts TEXT);
`);

async function fetchHashtagStats(hashtag) {
  const res = await fetch(`${API_BASE}/hashtag/info`, {
    method: 'POST', headers: HEADERS,
    body: JSON.stringify({ hashtag })
  });
  const data = (await res.json()).data || {};
  return { video_count: data.videoCount || 0, view_count: data.viewCount || 0 };
}

async function run() {
  const now = new Date().toISOString();
  const sixHoursAgo = new Date(Date.now() - 6 * 3600000).toISOString();
  const hashtags = db.prepare('SELECT hashtag, viral_threshold FROM hashtags').all();
  for (const { hashtag, viral_threshold } of hashtags) {
    const stats = await fetchHashtagStats(hashtag);
    db.prepare('INSERT INTO snapshots VALUES (?,?,?,?)').run(hashtag, stats.video_count, stats.view_count, now);
    const prev = db.prepare(
      'SELECT video_count, view_count FROM snapshots WHERE hashtag=? AND ts <= ? ORDER BY ts DESC LIMIT 1'
    ).get(hashtag, sixHoursAgo);
    if (prev) {
      const newVideos = stats.video_count - prev.video_count;
      const newViews = stats.view_count - prev.view_count;
      if (newVideos >= (viral_threshold || 200)) {
        await fetch(ALERT_WEBHOOK, {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ text: `Viral alert #${hashtag}: +${newVideos} videos, +${Math.round(newViews/6).toLocaleString()} views/hr. https://tiktok.com/tag/${hashtag}` })
        });
      }
    }
    await new Promise(r => setTimeout(r, 500));
  }
}

run().catch(console.error);

Platforms Used

TikTok

Trending video, creator, and product discovery

Frequently Asked Questions

Polls tracked campaign hashtags every 6 hours, records video count and engagement totals, calculates growth velocity, and flags viral moments when video count or engagement grows more than 50% in a 6-hour window.

This workflow uses a every 6 hours (cron: 0 */6 * * *). Every 6 hours (cron: 0 */6 * * *).

This workflow uses the following Scavio platforms: tiktok. Each platform is called via the same unified API endpoint.

Yes. Scavio's free tier includes 50 credits on signup with no credit card required. That is enough to test and validate this workflow before scaling it.

TikTok Hashtag Campaign Tracker

Monitor TikTok campaign hashtag video counts and engagement every 6 hours. Detect viral moments and engagement spikes automatically.

Get Your API KeyRead the Docs
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy