# TikTok Fake Followers Checker · Engagement & Views Audit (`memo23/tiktok-fake-followers-checker`) Actor

Check a TikTok creator for fake or empty followers and a dead audience before you pay them. Scores their newest followers one by one, compares the fake share and median views with over 150 measured active creators of similar size, and returns a low, medium or high risk with the reasons. No login.

- **URL**: https://apify.com/memo23/tiktok-fake-followers-checker.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Social media, AI, Automation
- **Stats:** 3 total users, 2 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $210.00 / 1,000 profile audits

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## TikTok Fake Followers Checker · Engagement & Views Audit

Check a TikTok creator before you pay them. For every account you give it, this Actor scores the creator's newest followers one by one, measures how many people actually watch their recent videos, and compares both with active creators of a similar size. You get a **low, medium or high risk** and the exact reasons behind it. No login, no cookies.

### Why use this checker?

- **Judged against real creators, not a fixed number.** Across 157 active creators, the typical one had 9% of new followers that score as likely fake. A checker that alarms at any fake share would call most honest creators risky. This one flags a creator only when it looks worse than 90% of creators of a similar size.
- **Two measurements that cover each other.** A follower sample only sees recent followers, so followers bought months ago never show in it. Comparing views with followers catches that case.
- **Every verdict can be checked.** Each follower gets a score from named traits, and each risk flag states its numbers and the line it crossed. Turn on follower rows to see every scored follower.
- **Pinned videos are excluded.** Creators pin old hits, which would inflate views and hide a creator who stopped posting.
- **Honest about what it cannot see.** Private accounts, hidden follower lists and thin video histories come back as explicit rows or flags, never as an invented score.

### What each audit tells you

| Field | What it means |
|---|---|
| `riskLevel` | `low`, `medium` or `high`; `unknown` when neither the followers nor 3 recent videos could be read |
| `riskFlags` | Each finding, with a `code`, a `severity` and a `detail` sentence carrying the numbers |
| `likelyFakePercent` | Share of the sampled newest followers that score 50 or more |
| `suspiciousPercent` | Share that score 30 to 49 |
| `audienceQualityScore` / `audienceGrade` | 100 minus the average follower score, and its grade: A from 85, B from 70, C from 55, D from 40, F below |
| `medianViews` / `viewsToFollowersPct` | Median views on recent non-pinned videos, and that number as a percentage of followers |
| `engagementRateByViewsPct` | Likes, comments, shares and saves as a percentage of views |
| `postsPerWeek` / `daysSinceLastPost` | Posting cadence and recency |
| `recentVideos` | The videos analysed, with views, likes, comments, shares and saves |

### How it works

#### 1. Score the newest followers

TikTok lists a creator's followers newest first, 30 at a time, and each entry carries that follower's own public counters. Every sampled follower gets the sum of the weights below. A score of 50 or more counts as likely fake, 30 to 49 as suspicious. Verified accounts always count as real.

| Flag | Weight | What triggers it |
|---|---|---|
| `default_avatar` | 25 | TikTok's stock profile picture. In a 360-follower test sample, 7 of the 9 followers using it had never posted |
| `placeholder_handle` | 22 | `user` followed by 6 or more digits, the handle TikTok assigns when none is chosen |
| `lopsided_follow_ratio` | 20 | Follows 500 or more accounts, and over 20 times as many as follow it |
| `promo_handle` | 18 | Handle ends in followers, likes, gain, promo or bot |
| `empty_shell_following` | 14 | Never posted and no likes received, yet follows 200 or more accounts |
| `long_digit_suffix` | 12 | Handle ends in 6 or more digits |
| `mostly_digits` | 10 | Handle has 8 or more digits and more digits than letters |
| `no_vowels` | 10 | 8 or more letters without a vowel |
| `mass_following` | 10 | Follows 2,000 or more accounts |
| `almost_no_followers` | 8 | Fewer than 5 followers |
| `no_videos` | 6 | Never posted |
| `nickname_is_handle` | 6 | Display name left as the handle |
| `private_and_empty` | 6 | Private account with no videos |
| `digit_suffix` | 4 | Handle ends in 4 or 5 digits |
| `empty_bio` | 3 | No bio |

No trait reaches suspicious on its own; the heaviest weighs 25. Never posting and having no bio weigh little because they describe many real viewers: in the NASA audit below, 80 of the 200 newest followers had never posted and 113 had no bio.

#### 2. Compare views with followers

The median views across recent non-pinned videos is divided by the follower count. Each size tier has a floor, the ratio that 90% of active creators in that tier exceed.

| Tier | Followers | Floor | Creators measured |
|---|---|---|---|
| Nano | under 10k | 10.9% | 26 |
| Micro | 10k to 100k | 1.3% | 42 |
| Mid | 100k to 1M | 0.59% | 60 |
| Macro and mega | 1M and above | 0.68% | 41 |

Macro and mega share one floor because the mega tier alone had 13 creators, too few for a stable figure.

#### 3. Judge both against creators of a similar size

The share of likely fake followers is compared with the line that 90% of active creators stay at or below, measured on their 200 newest followers.

| Creator size | Median fake share | Line | Creators measured |
|---|---|---|---|
| Under 1M followers | 10% | 17.5% | 119 |
| 1M followers and above | 5.5% | 12% | 38 |

- **High:** a fake share at least twice its line (35% or 24%), or median views below half the tier floor.
- **Medium:** a fake share above its line, median views below the tier floor, or a last post more than 60 days ago.
- **Low:** none of the above.

On the 157 creators used to set these lines, the rules rate 76% low, 20% medium and 4% high. Medium means worth a question, and one creator in five got it, so read the flags before drawing conclusions.

### The limits, stated plainly

- **The follower sample is the newest followers.** TikTok offers no way to sample older ones, so followers bought months ago do not appear in it. In testing, one creator had 49,900 followers and a median of 134 views per video. Only 0.5% of its 200 newest followers looked fake, and the audit still rated it **high** on views.
- **"Fake" means the traits of auto-created or empty accounts.** Some of those are real people who never set up a profile, and no public signal tells them apart from bots. That is why a fake share counts against a creator only when it is unusual for creators of that size.
- **The benchmarks are a sample, measured once.** They come from 169 active creators found through eleven hashtags and a list of large accounts on 2026-09-11, with 157 of them used for the follower lines. A useful reference, not a census of TikTok.
- **Smaller samples are noisier.** The fake-share lines were measured on 200 followers. On the same creators, a 90-follower sample crosses them 12% of the time instead of 10%, and a 30-follower sample 14%.
- **Engagement by views is reported, not scored.** The median creator in every size tier sat between 8% and 11%, and the rate runs high on small view counts: the low-view creator above scored 25.23%.
- **Suspicious share is reported, not scored.** 95% of the creators measured stayed at or below 25.5%, too narrow a spread to separate anyone.
- **Private accounts cannot be audited.** Their videos and followers are not public, so they return an error row, which is not charged.

### Input

| Field | Default | Notes |
|---|---|---|
| `usernames` | required | Handles, `@handles` or profile URLs |
| `followersToAnalyze` | `200` | Newest followers to score, 30 to 1,000 |
| `videosToAnalyze` | `12` | Recent non-pinned videos to analyse, 3 to 30 |
| `includeFollowerRows` | `false` | Also return every sampled follower as its own row |

On Apify's free plan, a run audits the first 3 profiles and samples at most 90 followers each.

```json
{
  "usernames": ["nasa", "https://www.tiktok.com/@khaby.lame"],
  "followersToAnalyze": 200,
  "videosToAnalyze": 12,
  "includeFollowerRows": false
}
```

### Output

Rows from a test run on 2026-09-11. `recentVideos` is cut to two entries, and the handles of private individuals are replaced with placeholders.

**A low-risk account**

```json
{
  "rowType": "audit",
  "username": "nasa",
  "profileUrl": "https://www.tiktok.com/@nasa",
  "nickname": "NASA",
  "isVerified": true,
  "followerCount": 1600000,
  "followingCount": 23,
  "likeCount": 8400000,
  "videoCount": 42,
  "creatorTier": "macro",
  "riskLevel": "low",
  "riskFlags": [],
  "likelyFakePercent": 5.5,
  "suspiciousPercent": 12.5,
  "likelyRealPercent": 82,
  "audienceQualityScore": 84,
  "audienceGrade": "B",
  "sampledFollowers": 200,
  "followerSample": "newest",
  "followerListHidden": false,
  "followerSampleComplete": true,
  "topFollowerFlags": [
    {
      "flag": "empty_bio",
      "count": 113
    },
    {
      "flag": "no_videos",
      "count": 80
    },
    {
      "flag": "empty_shell_following",
      "count": 37
    },
    {
      "flag": "mass_following",
      "count": 36
    },
    {
      "flag": "private_and_empty",
      "count": 35
    }
  ],
  "videosAnalyzed": 12,
  "pinnedExcluded": 1,
  "avgViews": 377620,
  "medianViews": 306880,
  "viewsToFollowersPct": 19.18,
  "engagementRateByViewsPct": 11.55,
  "engagementRateByFollowersPct": 2.73,
  "avgLikes": 38082,
  "avgComments": 808,
  "avgShares": 1651,
  "avgSaves": 3091,
  "postsPerWeek": 4.1,
  "daysSinceLastPost": 2,
  "recentVideos": [
    {
      "videoId": "7665075736742530317",
      "url": "https://www.tiktok.com/@nasa/video/7665075736742530317",
      "postedAt": "2026-07-21T20:09:02.000Z",
      "isPinned": true,
      "isPhotoPost": false,
      "views": 1277254,
      "likes": 86600,
      "comments": 2610,
      "shares": 2973,
      "saves": 6467
    },
    {
      "videoId": "7683502372135505165",
      "url": "https://www.tiktok.com/@nasa/video/7683502372135505165",
      "postedAt": "2026-09-09T11:53:38.000Z",
      "isPinned": false,
      "isPhotoPost": false,
      "views": 209286,
      "likes": 23160,
      "comments": 476,
      "shares": 1982,
      "saves": 2104
    }
  ],
  "auditedAt": "2026-09-11T20:11:02.039Z"
}
```

**A high-risk account: plenty of followers, few viewers**

```json
{
  "rowType": "audit",
  "username": "example.creator",
  "profileUrl": "https://www.tiktok.com/@example.creator",
  "nickname": "Example Creator",
  "isVerified": false,
  "followerCount": 49900,
  "followingCount": 351,
  "likeCount": 223700,
  "videoCount": 4255,
  "creatorTier": "micro",
  "riskLevel": "high",
  "riskFlags": [
    {
      "code": "views_far_below_followers",
      "severity": "high",
      "detail": "Median 134 views per video is 0.27% of 49,900 followers, below the 1.3% that 90% of active micro creators exceed."
    }
  ],
  "likelyFakePercent": 0.5,
  "suspiciousPercent": 4,
  "likelyRealPercent": 95.5,
  "audienceQualityScore": 92,
  "audienceGrade": "A",
  "sampledFollowers": 200,
  "followerSample": "newest",
  "followerListHidden": false,
  "followerSampleComplete": true,
  "topFollowerFlags": [
    {
      "flag": "empty_bio",
      "count": 64
    },
    {
      "flag": "mass_following",
      "count": 55
    },
    {
      "flag": "digit_suffix",
      "count": 34
    },
    {
      "flag": "nickname_is_handle",
      "count": 20
    },
    {
      "flag": "no_videos",
      "count": 17
    }
  ],
  "videosAnalyzed": 12,
  "pinnedExcluded": 2,
  "avgViews": 134,
  "medianViews": 134,
  "viewsToFollowersPct": 0.27,
  "engagementRateByViewsPct": 25.23,
  "engagementRateByFollowersPct": 0.07,
  "avgLikes": 32,
  "avgComments": 2,
  "avgShares": 0,
  "avgSaves": 0,
  "postsPerWeek": 5.4,
  "daysSinceLastPost": 0,
  "recentVideos": [
    {
      "videoId": "…",
      "url": "https://www.tiktok.com/@example.creator/video/…",
      "postedAt": "2026-09-11T07:34:56.000Z",
      "isPinned": false,
      "isPhotoPost": false,
      "views": 81,
      "likes": 22,
      "comments": 2,
      "shares": 0,
      "saves": 1
    },
    {
      "videoId": "…",
      "url": "https://www.tiktok.com/@example.creator/video/…",
      "postedAt": "2026-09-10T14:18:52.000Z",
      "isPinned": false,
      "isPhotoPost": false,
      "views": 104,
      "likes": 30,
      "comments": 1,
      "shares": 0,
      "saves": 0
    }
  ],
  "auditedAt": "2026-09-11T20:10:58.121Z"
}
```

**An account that cannot be audited**

```json
{
  "rowType": "error",
  "sourceUsername": "private.example",
  "error": "private_account",
  "message": "Account @private.example is private, so its videos and followers are not public and it cannot be audited.",
  "errorKind": "unavailable"
}
```

**A follower row** (with `includeFollowerRows` on)

```json
{
  "rowType": "follower",
  "auditedUsername": "another.creator",
  "username": "user0000000000",
  "profileUrl": "https://www.tiktok.com/@user0000000000",
  "nickname": "user0000000000",
  "isPrivate": false,
  "isVerified": false,
  "hasDefaultAvatar": false,
  "followerCount": 1283,
  "followingCount": 7602,
  "likesReceived": 0,
  "videoCount": 0,
  "fakeScore": 52,
  "verdict": "likely_fake",
  "flags": [
    "placeholder_handle",
    "no_videos",
    "mass_following",
    "empty_shell_following"
  ]
}
```

### Pricing

Pay per event:

- **One charge per profile audited**, which includes up to 200 sampled followers.
- **One charge per further 100 followers** when you sample more than 200.
- **One charge per follower row**, only if you turn follower rows on.

Error rows for private, missing or invalid accounts are never charged. Current prices are on the Pricing tab.

### FAQ

**Is a high fake-follower share proof that a creator bought followers?**
No. It means an unusually large share of recent followers show the traits of auto-created or empty accounts. Treat it as a reason to ask questions, and check the follower rows to see which traits were found.

**Why does a creator with 5% fake followers come out low risk?**
Because 5% is ordinary. Across 157 active creators the median was 9%.

**Why can a creator with almost no fake followers be high risk?**
The follower sample only covers recent followers. If followers were bought long ago, the gap shows up in views instead, which is why the audit checks both.

**Why are pinned videos ignored?**
Creators pin old hits. Counting them would inflate views and make an inactive account look busy.

**How long does an audit take?**
In testing, one profile took 16 seconds with 200 followers and 57 seconds with 1,000. Up to 3 profiles run in parallel.

**What if an account hides its follower list?**
The audit runs on views alone and adds a `follower_list_hidden` flag.

### 🤖 For AI Agents & LLM Apps

**Purpose:** assess whether a public TikTok creator's audience looks real before a sponsorship or partnership.

**Minimal input:**

```json
{ "usernames": ["nasa"] }
```

**Output:** one `rowType: "audit"` row per account. Key fields: `riskLevel` (`low` | `medium` | `high` | `unknown`), `riskFlags[]` (`code`, `severity`, `detail`), `likelyFakePercent`, `suspiciousPercent`, `audienceGrade`, `followerCount`, `medianViews`, `viewsToFollowersPct`, `engagementRateByViewsPct`, `postsPerWeek`, `daysSinceLastPost`, `sampledFollowers`, `recentVideos[]`. Accounts that cannot be audited return `rowType: "error"` with `error` (`private_account`, `user_not_found`, `invalid_username`) and `errorKind`.

**Behaviour to rely on:**

- Branch on `riskLevel` and quote `riskFlags[].detail` when explaining a decision.
- Do not treat a non-zero `likelyFakePercent` as fraud. The median active creator scored 9%; only the flags mark an unusual share.
- `likelyFakePercent` covers the newest followers only. Do not extrapolate it to the whole audience.
- Error rows are answers, not failures, and are not charged. A run where every account was private still succeeds.
- Billing: one event per audit, one per extra 100 followers beyond 200, one per follower row if requested.

### ⚠️ Disclaimer

This Actor reads only information TikTok shows publicly to logged-out visitors. It does not log in, bypass privacy settings or access private accounts. Risk levels and fake-follower scores are statistical estimates from public signals and a measured benchmark. They are not statements of fact about any person or creator, some flagged followers are real people, and the results should not be the only basis for a decision about anyone. You are responsible for how you use the results, including compliance with TikTok's terms and applicable data-protection law. This Actor is not affiliated with or endorsed by TikTok.

### SEO Keywords

tiktok fake followers checker, tiktok fake follower audit, tiktok influencer audit, tiktok engagement rate checker, tiktok audience quality, tiktok bot followers, check tiktok followers real, tiktok creator vetting, influencer fraud detection tiktok, tiktok views to followers ratio, tiktok audit tool, tiktok follower analysis, influencer marketing due diligence

# Actor input Schema

## `usernames` (type: `array`):

Public TikTok accounts to check, one per line: a handle (khaby.lame), an @-prefixed handle (@khaby.lame) or a profile URL (https://www.tiktok.com/@khaby.lame). Each account produces one audit row. Private accounts cannot be audited and come back as an error row explaining why.

## `followersToAnalyze` (type: `integer`):

How many of the account's most recent followers to score one by one. TikTok only serves followers newest-first, so this measures recent follows, not the whole audience. 200 (the default) costs one audit; each further 100 followers is billed separately. Minimum 30, maximum 1000.

## `videosToAnalyze` (type: `integer`):

How many of the creator's latest non-pinned videos to use for median views, engagement rate and posting cadence. Pinned videos are always excluded because creators pin old hits. Default 12, minimum 3, maximum 30.

## `includeFollowerRows` (type: `boolean`):

Off: one audit row per account. On: also returns every sampled follower as its own row, with the fake-score, verdict and the exact flags behind it, so you can check any verdict yourself. Follower rows are billed per row.

## Actor input object example

```json
{
  "usernames": [
    "nasa"
  ],
  "followersToAnalyze": 200,
  "videosToAnalyze": 12,
  "includeFollowerRows": false
}
```

# Actor output Schema

## `audits` (type: `string`):

No description

# 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 = {
    "usernames": [
        "nasa"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/tiktok-fake-followers-checker").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 = { "usernames": ["nasa"] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/tiktok-fake-followers-checker").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 '{
  "usernames": [
    "nasa"
  ]
}' |
apify call memo23/tiktok-fake-followers-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/tiktok-fake-followers-checker"
        }
    }
}
```

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/NmpnAo9zFBdNagcOM/builds/ODzcgmzTXhd6GO7V7/openapi.json
