# TikTok Competitor Viral Outlier & Growth Monitor (`herazur/tiktok-competitor-viral-outlier-growth-monitor`) Actor

Monitor competitor TikTok accounts and detect breakout videos, viral outliers, engagement spikes, follower growth, new hashtags, sounds, and profile changes.

- **URL**: https://apify.com/herazur/tiktok-competitor-viral-outlier-growth-monitor.md
- **Developed by:** [Furkan Toluç](https://apify.com/herazur) (community)
- **Categories:** Social media, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 account checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## TikTok Competitor Viral Outlier & Growth Monitor

Stop checking competitor TikTok profiles manually. This Actor tells you when a competitor publishes something that materially outperforms their normal content.

It is a stateful competitor-momentum monitor—not a bulk TikTok scraper. Schedule it daily or several times per day and receive only newly observed signals: new posts, 2× and 5× breakouts, engagement outliers, follower acceleration, new hashtags and sounds, and profile changes.

### What it detects

- **Viral outlier monitoring:** compares each refreshed video with that account's own previous recent median, not an arbitrary global benchmark.
- **Delayed breakout detection:** a post first seen at 1.1× can trigger later when observed at 2× or 5×. Each threshold is emitted once.
- **Competitor growth:** reports follower change and emits a spike only after at least three historical growth observations support it.
- **Content strategy changes:** identifies new hashtags, stable sound IDs, profile edits, and large posting-cadence changes.
- **Scheduled monitoring:** persistent Apify Key-Value Store state makes recurring runs useful; no external database is required.

### Example input

```json
{
  "accounts": [
    { "username": "nike", "name": "Nike" },
    { "username": "https://www.tiktok.com/@gymshark", "name": "Gymshark" }
  ],
  "maxVideosPerAccount": 30,
  "baselineVideoCount": 20,
  "onlyChanges": true,
  "minimumViewsForOutlier": 1000,
  "outlierMultiplier": 2,
  "strongOutlierMultiplier": 5,
  "detectFollowerGrowth": true,
  "detectHashtags": true,
  "detectSounds": true
}
```

Usernames, `@usernames`, and full profile URLs are accepted. Duplicate normalized usernames are checked once. A friendly `name` is optional and never used as account identity.

### Example breakout event

```json
{
  "recordType": "EVENT",
  "eventType": "BREAKOUT_5X",
  "severity": "HIGH",
  "accountName": "Example Brand",
  "accountId": "123456789",
  "username": "examplebrand",
  "videoId": "7412345678901234567",
  "videoUrl": "https://www.tiktok.com/@examplebrand/video/7412345678901234567",
  "caption": "Our newest product...",
  "views": 141000,
  "baselineMedianViews": 24000,
  "viewMultiple": 5.875,
  "likes": 12400,
  "comments": 491,
  "shares": 2102,
  "publishedAt": "2026-08-28T14:02:00.000Z",
  "detectedAt": "2026-08-29T12:00:00.000Z"
}
```

The wording is deliberately observational: the video is *currently performing above its recent baseline*. The Actor does not predict future virality.

### Baseline and thresholds

The first successful check stores the profile, recent stable video IDs, metrics, hashtags, sounds, and a median baseline. It does not label existing posts as `NEW_VIDEO` and normally emits no event rows when `onlyChanges=true`.

On later runs, events are evaluated against the **previous saved baseline**, then the next baseline is calculated and saved. This avoids a newly viral post raising the baseline before it is classified.

The baseline includes median views, likes, comments, shares, engagement rate, and approximate hours between posts. At least five videos with valid view counts are required. Below that, `baselineStatus` is `INSUFFICIENT_DATA` and relative outlier claims are skipped.

Default view logic:

```text
VIRAL_OUTLIER: views >= 1,000 and views / previous median >= 2
BREAKOUT_2X:   views >= 1,000 and views / previous median >= 2
BREAKOUT_5X:   views >= 1,000 and views / previous median >= 5
```

The minimum-view safeguard prevents a small account's 100-view median and 400-view post from being called commercially meaningful merely because it is 4× larger.

Engagement rate is `(likes + comments + shares) / views`. It is calculated only when all four public metrics are present and views are positive. An engagement outlier is 2× the previous median engagement rate and also obeys the minimum-view safeguard.

### Only-changes and snapshot modes

With `onlyChanges=true` (default), the Dataset contains only new `EVENT` records. An unchanged recurring run intentionally produces zero Dataset rows; its `OUTPUT` record still contains a complete monitoring summary.

With `onlyChanges=false`, the Dataset also contains normalized `PROFILE_SNAPSHOT` and `VIDEO_SNAPSHOT` rows for one-time analysis or troubleshooting.

### Extraction approach and cost

The Actor uses TikTok's public, logged-out creator and video embed pages over HTTP. One creator request obtains a stable numeric account ID and recent stable video IDs. Limited concurrent video-embed requests enrich those IDs with current public engagement, publish time, duration, sound, and profile counts.

- Browser: **not used**
- TikTok login: **not required**
- Personal cookies: **not required**
- TikTok developer app or API key: **not required**
- Video downloads: **not performed**
- External AI or database: **not used**
- Proxy: optional; useful when public embeds are rate-limited in a region

Temporary 429, 5xx, and timeout failures use capped exponential backoff with jitter. A failed account does not overwrite its previous valid state and does not stop other accounts.

The source includes an `account_checked` pay-per-event adapter: one event is charged only after a successfully monitored account has written output and committed state. Final Store pricing must be configured in Apify Console; no price is invented in code.

### Scheduling

Create an Apify Task with your input, run it once to establish the baseline, then attach an Apify Schedule. Daily checks suit slower brand accounts; several checks per day provide better observed growth resolution for fast-moving accounts.

`viewsPerHour` should always be interpreted as average observed growth between checks, not exact real-time velocity. The MVP prioritizes deterministic breakout thresholds over noisy velocity alerts.

### Data and privacy

Only publicly available TikTok profile and post metadata is processed. Use the Actor lawfully, respect TikTok's terms, and comply with privacy and data-protection requirements applicable to your use case. Private or restricted accounts are not accessible.

### Known limitations

- TikTok public web access is unofficial and can change without notice. Challenge or malformed responses are treated as failures, never as empty real results.
- The unsigned creator embed exposes only a limited recent window (commonly around 10, with an observed upper bound near 22), even if `maxVideosPerAccount` is higher. There is no full-history pagination in this MVP.
- Metrics reflect what TikTok served at check time and can be cached, delayed, rounded, or geographically personalized.
- Private, deleted, age-restricted, region-restricted, and unavailable posts cannot be monitored.
- Bio links are currently not exposed reliably by the unsigned embed route and therefore remain `null`; they are never invented.
- Hashtags are normalized from public captions. Sound metadata can be absent for unavailable or partially enriched posts.
- A deleted video is retained in capped known history but no disappearance event is emitted.
- Stable numeric account/video IDs are used when TikTok exposes them; username changes can be tracked only when the supplied public route continues to resolve the same account ID.

### Output storage

- Default Dataset: events and optional snapshots
- Default Key-Value Store `OUTPUT`: run summary and isolated account errors
- Named Key-Value Store `tiktok-competitor-monitor-state` (or a Task-ID-specific store): capped cross-run monitoring state (up to 100 known videos per account)

No secrets are required. Optional Apify Proxy settings are accepted through the standard proxy input.

# Actor input Schema

## `accounts` (type: `array`):

TikTok usernames or profile URLs. The optional name is the friendly account label used in output.

## `onlyChanges` (type: `boolean`):

Return only newly detected events. The first run establishes a baseline and normally emits zero rows.

## `maxVideosPerAccount` (type: `integer`):

Maximum recent public videos requested per account. TikTok's public embed may expose fewer.

## `outlierMultiplier` (type: `number`):

Emit VIRAL\_OUTLIER when views reach this multiple of the account's previous median.

## `minimumViewsForOutlier` (type: `integer`):

A video must have at least this many views before any relative view-outlier event is emitted.

## `baselineVideoCount` (type: `integer`):

Number of recent videos used for median performance. At least 5 valid videos are required.

## `strongOutlierMultiplier` (type: `number`):

View multiple used for the high-severity BREAKOUT\_5X signal.

## `detectFollowerGrowth` (type: `boolean`):

Track follower deltas and emit a spike only after enough historical observations exist.

## `detectHashtags` (type: `boolean`):

Emit a low-severity event when a new post uses a normalized hashtag not seen for the account.

## `detectSounds` (type: `boolean`):

Emit a low-severity event when a new post uses a previously unseen stable sound ID.

## `proxyConfiguration` (type: `object`):

Optional. Apify Proxy can improve consistency in regions where TikTok public embeds are rate-limited.

## Actor input object example

```json
{
  "accounts": [
    {
      "username": "nike",
      "name": "Nike"
    }
  ],
  "onlyChanges": true,
  "maxVideosPerAccount": 30,
  "outlierMultiplier": 2,
  "minimumViewsForOutlier": 1000,
  "baselineVideoCount": 20,
  "strongOutlierMultiplier": 5,
  "detectFollowerGrowth": true,
  "detectHashtags": true,
  "detectSounds": true
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset rows. With onlyChanges=true, a successful unchanged run intentionally contains zero rows.

## `summary` (type: `string`):

Run status, counts, request totals, and isolated account errors.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("herazur/tiktok-competitor-viral-outlier-growth-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("herazur/tiktok-competitor-viral-outlier-growth-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call herazur/tiktok-competitor-viral-outlier-growth-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,herazur/tiktok-competitor-viral-outlier-growth-monitor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0cHOdvXOgCpogOblZ/builds/jePhvEWMlYlMczvYf/openapi.json
