Fake Engagement & Bot Account Detector - IG, TikTok & YouTube
Pricing
Pay per event
Fake Engagement & Bot Account Detector - IG, TikTok & YouTube
Instagram, TikTok and YouTube audience-authenticity API for AI agents and pipelines: typed JSON per profile with authenticity score, bot likelihood, verdict, weighted signals and raw metrics. Strict output schema, per-profile pricing, MCP-ready, no login. 刷粉检测: 打款前识别假粉丝与虚假互动.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Creator Fusion
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 hours ago
Last modified
Categories
Share
Fake Engagement & Bot Account Detector — Instagram, TikTok & YouTube Audience Authenticity API
Score any creator's audience for fake followers and bot engagement across Instagram, TikTok and YouTube in a single call. Give it a list of handles; it returns typed JSON rows — authenticity score, bot likelihood, verdict, a weighted signal breakdown, and the raw follower/engagement metrics behind every number, so you can re-derive the maths yourself. Schema below.
Built for creator platforms, influencer agencies and brand-safety pipelines that check audiences at volume: priced per profile analyzed, not per report.
Why agents use this actor
- Deterministic typed output — one row per profile, stable field names, every nullable field declared in the dataset schema.
- Per-profile pricing — one
profile-analyzedevent per scored profile, so an autonomous budget maps 1:1 to work done. Profiles whose engagement could not be retrieved are not charged. - Never guesses — if engagement data is unavailable,
verdictisnull,confidenceisinsufficient-data, andunavailableSignalsnames exactly which signals were missing. Nulls are never scored as zeros. - Explainable, not a black box — every signal ships with its value, status, weight and a plain-language explanation an agent can quote straight to a user.
- No auth, no cookies — public data only. Retries with backoff on 429/5xx, 30 s timeouts, per-item pushes.
- Three platforms, one contract — the same row shape for Instagram, TikTok and YouTube.
Input schema
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
profiles | string[] | no* | [] | "instagram:handle", "tiktok:handle", "youtube:@handle", or a plain profile URL (platform auto-detected). |
instagramUsernames | string[] | no* | [] | Instagram usernames, with or without @. |
tiktokUsernames | string[] | no* | [] | TikTok usernames, with or without @. |
youtubeChannels | string[] | no* | [] | YouTube handles (@MrBeast) or channel IDs (UC...). |
maxPostsPerProfile | integer | no | 12 | Recent posts/videos sampled per profile for engagement, variance and cadence. 1–50. |
proxyConfiguration | object | no | { "useApifyProxy": true } | Apify Proxy settings. TikTok and YouTube run on datacenter/auto; Instagram automatically uses the residential group, billed at the standard residential rate. |
* At least one profile across the four lists is required. All four lists are merged and de-duplicated.
Output schema
One row per profile.
| Field | Type | Nullable | Description |
|---|---|---|---|
platform | string | no | instagram, tiktok or youtube. |
handle | string | no | Canonical handle as published by the platform. |
profileUrl | string | no | Public profile URL. |
displayName | string | yes | Display name / full name / channel title. |
verified | boolean | yes | Verification badge; null where the platform hides it. |
isPrivate | boolean | yes | True for private accounts. |
followers | integer | yes | Followers / subscribers. |
following | integer | yes | Accounts followed. Null on YouTube — it does not publish this. |
posts | integer | yes | Total posts / videos. |
totalLikes | integer | yes | Lifetime likes across all videos (TikTok). |
avgLikes | integer | yes | Average likes per sampled post (TikTok: lifetime likes ÷ video count). |
avgComments | integer | yes | Average comments per sampled post (Instagram). |
avgViews | integer | yes | Average views per sampled video (TikTok, YouTube, Instagram video posts). |
engagementRate | number | yes | Fraction of audience engaging — 0.032 = 3.2%. |
benchmarkEngagementRate | number | yes | Typical rate for this platform at this audience size — the benchmark used. |
engagementBasis | string | yes | Which observable metric fed the rate: recent-posts-likes-comments, lifetime-avg-likes-per-video, recent-video-views-per-subscriber. |
postsAnalyzed | integer | yes | Posts actually sampled. |
authenticityScore | integer | yes | 0–100. Null when engagement could not be retrieved. |
botLikelihood | number | yes | 0–1 weighted share of signals pointing to inauthentic engagement. |
verdict | string | yes | authentic (≥80) / likely-authentic (65–79) / suspicious (45–64) / likely-fake (<45). Null when confidence is insufficient-data. |
confidence | string | no | high / medium / low / insufficient-data, from how many signals were retrievable. |
signals | object[] | no | { name, value, status, weight, explanation } per signal. status ∈ ok/warn/bad/unavailable. |
redFlags | string[] | no | Explanations of every signal that scored bad. |
greenFlags | string[] | no | Explanations of every healthy signal. |
unavailableSignals | string[] | no | Signals with no retrievable data for this profile. |
bio, externalUrl, avatarUrl | string | yes | Profile completeness inputs, returned raw. |
channelId | string | yes | YouTube channel ID. |
analyzedAt | string | no | ISO 8601 timestamp. |
error | string | yes | Always null on pushed rows — failures go to the SUMMARY record. |
The signals
| Signal | Weight | What it catches |
|---|---|---|
engagementRate | 3 | Engagement graded against the typical rate for that audience size, never an absolute — large accounts naturally engage lower. Far below tier reads as inactive/purchased followers; implausibly above reads as purchased engagement. |
likeToCommentRatio | 2 | Bot engagement is likes-only. Real audiences comment. |
engagementVariance | 2 | Organic reach is spiky. Near-identical numbers post to post are a delivered quota. |
followerFollowingRatio | 1 | Mass-follow and follow/unfollow growth tactics. |
postingCadence | 1 | Burst-and-dormancy publishing patterns. |
accountCompleteness | 1 | Bio, link, avatar, name and verification — disposable accounts skip them. |
The score is the weighted share of available signals that came back clean. Unavailable signals are excluded from both numerator and denominator and lower confidence instead.
Example rows (real output)
{"platform": "instagram", "handle": "nasa","profileUrl": "https://www.instagram.com/nasa/", "displayName": "NASA","verified": true, "isPrivate": false,"followers": 104398251, "following": 92, "posts": 4882,"avgLikes": 457668, "avgComments": 1488, "avgViews": 1514238,"engagementRate": 0.004398, "benchmarkEngagementRate": 0.015,"engagementBasis": "recent-posts-likes-comments", "postsAnalyzed": 12,"authenticityScore": 75, "botLikelihood": 0.25,"verdict": "likely-authentic", "confidence": "high","signals": [{ "name": "engagementRate", "value": 0.004398, "status": "warn", "weight": 3,"explanation": "0.44% engagement — 0.29x the 1.5% typical for this audience size. Below the healthy band for the tier." },{ "name": "engagementVariance", "value": 1.259, "status": "ok", "weight": 2,"explanation": "Engagement varies by 126% across recent posts — the spiky pattern of organic reach." }],"redFlags": [], "greenFlags": ["..."], "unavailableSignals": [],"analyzedAt": "2026-08-15T10:09:49.079Z", "error": null}
{"platform": "tiktok", "handle": "charlidamelio","followers": 159343052, "following": 1433, "posts": 3221,"totalLikes": 12306793939, "avgLikes": 3820800, "avgComments": null, "avgViews": 2964850,"engagementRate": 0.023978, "benchmarkEngagementRate": 0.025,"engagementBasis": "lifetime-avg-likes-per-video", "postsAnalyzed": 10,"authenticityScore": 100, "botLikelihood": 0, "verdict": "authentic", "confidence": "medium","unavailableSignals": ["likeToCommentRatio", "postingCadence"]}
{"platform": "youtube", "handle": "@MrBeast","channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA","followers": 513000000, "following": null, "posts": 997,"avgViews": 110166667, "engagementRate": 0.21475, "benchmarkEngagementRate": 0.1,"engagementBasis": "recent-video-views-per-subscriber", "postsAnalyzed": 12,"authenticityScore": 100, "botLikelihood": 0, "verdict": "authentic", "confidence": "medium","unavailableSignals": ["followerFollowingRatio", "likeToCommentRatio"]}
Error semantics
- Bad input — no valid profile in any list: run fails fast, exit code 1, status message naming the accepted formats. Nothing is charged beyond
actor-start. - Per-profile failure — extraction errors never abort the run and never appear in the paid dataset. They are collected in the
SUMMARYkey-value record as{ platform, handle, error }, so retry logic can pick them up:GET /v2/key-value-stores/{storeId}/records/SUMMARY. - Partial data — a profile that resolves but exposes no engagement is pushed with
verdict: null,confidence: "insufficient-data"and populatedunavailableSignals, and is not charged. - Zero results — if every profile fails, the run exits 1 with the first error in the status message.
SUMMARYalways contains{ requested, analyzed, insufficientData, failed, failures, finishedAt }.
Use from AI agents (MCP)
{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?tools=apricot_blackberry/fake-engagement-detector","headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }}}}
Works in Claude, Cursor, ChatGPT deep-research connectors and any MCP client; the input schema above is the tool's parameter schema.
Use from code
curl -X POST "https://api.apify.com/v2/acts/apricot_blackberry~fake-engagement-detector/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"profiles":["tiktok:charlidamelio","youtube:@MrBeast"],"maxPostsPerProfile":12}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('apricot_blackberry/fake-engagement-detector').call({profiles: ['tiktok:charlidamelio', 'youtube:@MrBeast'],maxPostsPerProfile: 12,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.map((i) => [i.handle, i.verdict, i.authenticityScore]));
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("apricot_blackberry/fake-engagement-detector").call(run_input={"profiles": ["tiktok:charlidamelio", "youtube:@MrBeast"],"maxPostsPerProfile": 12,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["handle"], item["verdict"], item["authenticityScore"])
Use from automation platforms
- n8n / Make / Zapier — pick the Apify integration, choose Run actor, select Fake Engagement & Bot Account Detector, paste the input JSON above.
- LangChain / LlamaIndex — wrap it with the Apify actor tool (
ApifyActorsTool/ApifyWrapper) using actor idapricot_blackberry/fake-engagement-detector. - Webhooks — Apify can fire a webhook on
ACTOR.RUN.SUCCEEDED/FAILEDfor this actor, so a brand-safety pipeline picks up verdicts on run completion without polling.
Pricing
Pay per event:
| Event | When it fires |
|---|---|
actor-start | Once per run. |
profile-analyzed | Once per profile that returns a real verdict. Profiles with confidence: "insufficient-data" and failed extractions are not charged. |
Instagram profiles route through Apify residential proxy, billed to your account at the standard residential rate.
FAQ
How do you detect fake followers without follower-list access? By the fingerprint that purchased audiences leave in public metrics: engagement far below the norm for the audience size, likes without comments, and suspiciously uniform post-to-post numbers. Every one of those is computed from data the platform publishes on the profile itself.
Can I check Instagram, TikTok and YouTube in one run?
Yes — that is the point. Mix platforms freely in profiles; each row states its own platform and engagementBasis.
What does a good engagement rate look like?
It depends entirely on audience size, which is why every profile is graded against benchmarkEngagementRate for its tier rather than a fixed number. A 1.5% rate is healthy for a 10M-follower account and weak for a 5K one.
Why is avgComments null on TikTok and YouTube?
Those platforms publish likes and views on the profile surface but not per-post comment counts. The like-to-comment signal is then reported as unavailable and excluded from the score — it is never assumed to be zero.
Is a likely-fake verdict proof of fraud?
It is a statistical assessment of public engagement patterns, with the full evidence in signals and redFlags so you can review the reasoning behind it.
How many profiles can I check per run? As many as you pass. Profiles are processed sequentially with retries; a 100-profile run is routine.
Changelog
1.0 — Initial release. Instagram, TikTok and YouTube extraction; six-signal weighted authenticity scoring with tier-relative engagement benchmarks; typed dataset schema with per-signal breakdown; per-profile pay-per-event pricing.
中文说明(刷粉检测 / 假粉丝识别)
给达人打款之前,先查一查。 输入 Instagram / TikTok / YouTube 创作者账号,输出机器人粉丝/虚假互动评分,帮助你在投放前识别刷粉账号、僵尸粉和虚假互动。
- 覆盖三大平台:Instagram、TikTok、YouTube
- 评分为概率性参考指标,配合人工复核使用
- 按结果计费,批量筛选达人名单成本可控
适合 MCN、达人投放团队、跨境电商卖家在建联和签约前做尽调。Apify 每月 $5 免费额度,无需信用卡。
For AI agents
Bot-likelihood scoring rows with per-signal breakdown — machine-consumable for automated creator vetting pipelines:
$curl -X POST "https://api.apify.com/v2/acts/apricot_blackberry~fake-engagement-detector/run-sync-get-dataset-items?token=$APIFY_TOKEN" -H "Content-Type: application/json" -d '{"profiles": ["https://www.tiktok.com/@natgeo"]}'