Workflow

Daily TikTok Winning Product Scan

Daily automated scan of trending TikTok hashtags to detect winning products with high engagement before they go mainstream.

Overview

This workflow scans trending TikTok hashtags daily to detect products gaining viral traction. It tracks engagement velocity across product-related hashtags, scores videos by view-to-engagement ratios, and surfaces products showing early viral signals. The output feeds into product research pipelines for dropshippers and DTC brand scouts.

Trigger

Cron schedule (daily at 10 AM UTC)

Schedule

Daily 7 AM

Workflow Steps

1

Load product hashtag list

Read the list of product-related TikTok hashtags to monitor from configuration.

2

Fetch trending videos per hashtag

Call the Scavio TikTok API for each hashtag and retrieve trending video data.

3

Calculate engagement scores

Compute engagement rate, view velocity, and creator authenticity signals for each video.

4

Filter high-signal products

Keep only videos with engagement above threshold and views suggesting early traction.

5

Deduplicate and rank

Group by product, deduplicate across hashtags, and rank by combined engagement signal.

6

Output product opportunities

Save ranked product list with engagement data and send top opportunities to Slack.

Python Implementation

Python
import requests
import json
from datetime import datetime
from pathlib import Path
from collections import defaultdict

API_KEY = "your_scavio_api_key"
BASE_URL = "https://api.scavio.dev/api/v1/tiktok"

PRODUCT_HASHTAGS = [
    "tiktokmademebuyit",
    "amazonfinds",
    "viralproducts",
    "dropshipping2026",
    "tiktokshop",
    "musthave",
    "gadgets",
    "homefinds",
]

MIN_VIEWS = 50000
MIN_ENGAGEMENT_RATE = 0.04

def fetch_hashtag_videos(hashtag: str) -> list[dict]:
    res = requests.post(
        f"{BASE_URL}/hashtag",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"hashtag": hashtag},
        timeout=15,
    )
    res.raise_for_status()
    return res.json().get("videos", [])

def score_video(video: dict) -> dict | None:
    views = video.get("views", 0)
    likes = video.get("likes", 0)
    shares = video.get("shares", 0)
    comments = video.get("comments", 0)

    if views < MIN_VIEWS:
        return None

    engagement_rate = (likes + shares + comments) / views if views > 0 else 0
    if engagement_rate < MIN_ENGAGEMENT_RATE:
        return None

    return {
        "video_id": video.get("id", ""),
        "description": video.get("description", "")[:200],
        "creator": video.get("creator", ""),
        "views": views,
        "likes": likes,
        "shares": shares,
        "engagement_rate": round(engagement_rate, 4),
        "score": round(engagement_rate * (views / 100000), 2),
    }

def run():
    opportunities = defaultdict(list)

    for hashtag in PRODUCT_HASHTAGS:
        videos = fetch_hashtag_videos(hashtag)
        for video in videos:
            scored = score_video(video)
            if scored:
                scored["hashtag"] = hashtag
                opportunities[scored["creator"]].append(scored)

    # Rank by best single video score
    ranked = []
    for creator, videos in opportunities.items():
        best = max(videos, key=lambda x: x["score"])
        ranked.append(best)

    ranked.sort(key=lambda x: x["score"], reverse=True)

    date = datetime.utcnow().strftime("%Y-%m-%d")
    report = {
        "date": date,
        "total_opportunities": len(ranked),
        "top_products": ranked[:20],
    }

    Path(f"tiktok_products_{date}.json").write_text(json.dumps(report, indent=2))
    print(f"Found {len(ranked)} product opportunities")
    for item in ranked[:5]:
        print(f"  {item['hashtag']} | {item['views']:,} views | {item['engagement_rate']:.1%} ER | score: {item['score']}")

if __name__ == "__main__":
    run()

JavaScript Implementation

JavaScript
const API_KEY = "your_scavio_api_key";
const BASE_URL = "https://api.scavio.dev/api/v1/tiktok";

const PRODUCT_HASHTAGS = [
  "tiktokmademebuyit", "amazonfinds", "viralproducts", "dropshipping2026",
  "tiktokshop", "musthave", "gadgets", "homefinds",
];

const MIN_VIEWS = 10000;
const MIN_ENGAGEMENT = 0.03;

async function fetchHashtagVideos(hashtag) {
  const res = await fetch(BASE_URL + "/hashtag/videos", {
    method: "POST",
    headers: { Authorization: "Bearer " + API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ hashtag }),
  });
  if (!res.ok) throw new Error("tiktok " + res.status);
  const data = await res.json();
  return data.data?.videos || [];
}

function scoreVideo(video) {
  const views = video.play_count || 0;
  if (views < MIN_VIEWS) return null;
  const likes = video.digg_count || 0;
  const shares = video.share_count || 0;
  const comments = video.comment_count || 0;
  const er = views > 0 ? (likes + shares + comments) / views : 0;
  if (er < MIN_ENGAGEMENT) return null;
  return { videoId: video.id, creator: video.creator, views, likes, shares, er: Math.round(er * 10000) / 10000, score: Math.round(er * (views / 100000) * 100) / 100 };
}

async function run() {
  const opportunities = {};
  for (const hashtag of PRODUCT_HASHTAGS) {
    const videos = await fetchHashtagVideos(hashtag);
    for (const video of videos) {
      const scored = scoreVideo(video);
      if (scored) {
        scored.hashtag = hashtag;
        if (!opportunities[scored.creator]) opportunities[scored.creator] = [];
        opportunities[scored.creator].push(scored);
      }
    }
  }
  const ranked = Object.values(opportunities).map(vids => vids.sort((a, b) => b.score - a.score)[0]).sort((a, b) => b.score - a.score);
  console.log("Found " + ranked.length + " product opportunities");
  ranked.slice(0, 5).forEach(item => console.log("  " + item.hashtag + " | " + item.views + " views | score: " + item.score));
}

run();

Platforms Used

TikTok

Trending video, creator, and product discovery

Frequently Asked Questions

This workflow scans trending TikTok hashtags daily to detect products gaining viral traction. It tracks engagement velocity across product-related hashtags, scores videos by view-to-engagement ratios, and surfaces products showing early viral signals. The output feeds into product research pipelines for dropshippers and DTC brand scouts.

This workflow uses a cron schedule (daily at 10 am utc). Daily 7 AM.

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

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

Daily TikTok Winning Product Scan

Daily automated scan of trending TikTok hashtags to detect winning products with high engagement before they go mainstream.