How to Detect Fake Instagram Followers & Engagement with an API
Influencer fraud is expensive. A creator with 500,000 bought followers and a few thousand bot comments can look like a great partner on paper and deliver nothing. If you place brand deals, run an affiliate program, or build influencer-marketing software, you need to score authenticity programmatically — before money changes hands.
This guide shows how to build a fake-follower and bot-engagement checker with the Instagram Cheapest API on RapidAPI. You can't see who someone's followers are (that's private data), but you don't need to — fake audiences leave clear statistical fingerprints in public engagement data. We'll compute those signals in Python on real-time data at as little as $0.10 per 1,000 requests.
The fingerprints of a fake audience
Purchased followers and engagement distort the relationship between numbers that should move together. Four public signals expose the gap:
- Engagement rate that's far too low — millions of followers, but only a few hundred likes per post.
- A skewed like-to-comment ratio — bought likes rarely come with matching comments, so the ratio looks unnatural.
- Generic, repetitive comments — single emojis, "Nice!", "follow back", and copy-paste spam instead of on-topic conversation.
- Erratic engagement across posts — real audiences are fairly consistent; bot bursts spike on some posts and vanish on others.
All four come from three endpoints: user/{username} for the follower count, user_media for per-post likes and comments, and media_comments for the comment text.
Step 1: Get the baseline numbers
import requests
API_HOST = "instagram-cheapest.p.rapidapi.com"
BASE = f"https://{API_HOST}/api/v1/instagram"
API_KEY = "YOUR_RAPIDAPI_KEY"
HEADERS = {"x-rapidapi-host": API_HOST, "x-rapidapi-key": API_KEY}
def get_profile(username):
r = requests.get(f"{BASE}/user/{username}", headers=HEADERS)
r.raise_for_status()
return r.json()
profile = get_profile("some_creator")
# Pull follower count and user_id from the raw JSON (inspect field names once).
Step 2: Engagement-rate check
Average the likes and comments across recent posts (user_media returns ~12 per page and echoes next_max_id), then compare to the follower count.
def get_media(user_id, next_max_id=None):
params = {"user_id": user_id}
if next_max_id:
params["next_max_id"] = next_max_id
r = requests.get(f"{BASE}/user_media", headers=HEADERS, params=params)
r.raise_for_status()
return r.json()
def collect_posts(user_id, pages=3):
posts, next_max_id = [], None
for _ in range(pages):
data = get_media(user_id, next_max_id)
posts.extend(data.get("items", [])) # confirm key from raw JSON
next_max_id = data.get("next_max_id")
if not data.get("more_available"):
break
return posts
def engagement_rate(posts, followers):
if not posts or not followers:
return None
likes = sum(p.get("like_count", 0) for p in posts)
comments = sum(p.get("comment_count", 0) for p in posts)
n = len(posts)
return (likes / n + comments / n) / followers * 100
Interpretation: legitimate engagement rates usually fall between ~1% and ~5% depending on account size (smaller accounts trend higher). A 1M-follower account posting at 0.1–0.3% is a strong fraud signal — there simply aren't enough engaged humans behind the follower number.
Step 3: Like-to-comment ratio & consistency
Genuine audiences comment at a fairly stable fraction of likes. A wildly high like-to-comment ratio (e.g. tens of thousands of likes but almost no comments) suggests purchased likes. High variance across posts suggests bursty bot activity.
import statistics
def ratio_and_variance(posts):
ratios, engagements = [], []
for p in posts:
likes = p.get("like_count", 0)
comments = p.get("comment_count", 0)
if comments > 0:
ratios.append(likes / comments)
engagements.append(likes + comments)
avg_ratio = statistics.mean(ratios) if ratios else None
# Coefficient of variation: stdev / mean — higher = more erratic
cv = (statistics.pstdev(engagements) / statistics.mean(engagements)
if engagements and statistics.mean(engagements) else None)
return avg_ratio, cv
There's no universal cutoff — calibrate against accounts you trust in the same niche — but extreme outliers on either metric are worth flagging for manual review.
Step 4: Comment authenticity
The richest signal is the comment text itself. Pull comments from a few of the creator's recent posts with media_comments?code= and look for bot patterns.
def get_comments(code, after=None):
params = {"code": code}
if after:
params["after"] = after
r = requests.get(f"{BASE}/media_comments", headers=HEADERS, params=params)
r.raise_for_status()
return r.json()
SPAM_PHRASES = {"follow me", "follow back", "check my page", "dm me", "promo"}
def comment_authenticity(comments):
texts = [c.get("text", "") for c in comments.get("comments", [])]
if not texts:
return None
total = len(texts)
emoji_only = sum(1 for t in texts if t and not any(ch.isalnum() for ch in t))
spammy = sum(1 for t in texts if any(p in t.lower() for p in SPAM_PHRASES))
# Repetition: how many comments are duplicates of another
duplicates = total - len(set(t.strip().lower() for t in texts))
return {
"emoji_only_pct": emoji_only / total * 100,
"spam_pct": spammy / total * 100,
"duplicate_pct": duplicates / total * 100,
}
A healthy post has varied, on-topic comments. When a large share are emoji-only, duplicated, or full of "follow back" spam, the engagement is likely inorganic — even if the raw comment count looks impressive.
Step 5: Combine into one authenticity score
def authenticity_report(username):
profile = get_profile(username)
user_id = profile.get("user_id") # confirm field name
followers = profile.get("follower_count") # confirm field name
posts = collect_posts(user_id, pages=3)
er = engagement_rate(posts, followers)
avg_ratio, cv = ratio_and_variance(posts)
# Sample comments from the 3 most recent posts that have a shortcode
codes = [p.get("code") for p in posts[:3] if p.get("code")]
comment_stats = [comment_authenticity(get_comments(c)) for c in codes]
return {
"followers": followers,
"engagement_rate_pct": er,
"like_to_comment_ratio": avg_ratio,
"engagement_cv": cv,
"comment_signals": comment_stats,
}
# print(authenticity_report("some_creator"))
Turn the raw signals into a 0–100 score with weights that fit your risk tolerance, or simply flag accounts that trip two or more red lines for a human to review. Either way, you've replaced "they have a lot of followers" with evidence.
What does a check cost?
One authenticity check is roughly 1 profile call + 3 media pages + comments for 3 posts ≈ 7 requests — well under a cent.
- Free Basic tier: 30 requests/month — a few checks while you build
- Pro tier ($59/mo): 150,000 requests included, then $0.13 per 1,000
- Ultra tier ($119/mo): 900,000 requests included, then $0.11 per 1,000
- Mega tier ($249/mo): 3,000,000 requests included, then $0.10 per 1,000
Screening 20,000 creators a month (~140,000 requests) fits inside the Pro tier. Add the fields parameter to each call to keep payloads — and bandwidth — small.
A note on what's possible
These methods detect statistical fraud from public engagement; they can't inspect the follower list directly (that's private). Treat the output as a strong screening signal, not a verdict — calibrate thresholds per niche and keep a human in the loop for borderline cases. For the positive side of the same data — measuring genuine influence — see How to analyze an Instagram influencer with an API.
Compliance and responsible use
This API returns public Instagram data only. Fraud screening for your own partnerships is a legitimate use, but you are responsible for complying with Instagram's terms of service and applicable privacy laws (GDPR, CCPA), especially when storing commenter data or making decisions about individuals. The API is not affiliated with or endorsed by Meta or Instagram.
Conclusion
Fake audiences can't hide from math. By comparing follower counts against real engagement (user/{username} + user_media) and inspecting comment quality (media_comments), you can flag inflated accounts before a brand deal — programmatically, at scale, and for pennies per check. At $0.10–$0.13 per 1,000 requests, building authenticity screening into your workflow costs almost nothing compared to the money it saves.
Compliance note: this API returns public Instagram data only. You are responsible for complying with Instagram's terms and applicable privacy law (GDPR/CCPA). Not affiliated with or endorsed by Meta/Instagram.