A creator sends you a media kit claiming 480,000 followers. That number tells you almost nothing about whether their audience will actually click, comment, or convert. Bought followers, giveaway spikes, and years of follow-for-follow churn all inflate the same vanity metric. The question that matters for a campaign is: when this account posts, does anyone react?
Engagement rate answers that. It normalizes likes and comments against the audience size, so a 40K micro-creator at 5% and a 2M celebrity at 0.4% become directly comparable. This guide shows the exact formula, then walks through computing ER for any public Instagram account with one authenticated request — the profile summary and the per-post like and comment counts both come back in the same { data, meta } envelope.
The engagement rate formula
The standard, defensible definition of engagement rate by followers (ERF) is average interactions per post divided by follower count:
avg_interactions = sum(likes + comments over N recent posts) / N
engagement_rate = (avg_interactions / followers) * 100Two decisions make or break the number. First, use recent posts — the last 10 to 12 are enough to smooth out one viral outlier without dragging in years of stale history. Second, average per post before dividing by followers; summing raw interactions across a random post count produces a meaningless figure you cannot compare between accounts.
Likes + comments is the honest baseline
Public Instagram exposes likes and comments per post, which is what almost every published ER benchmark is built on. Saves, shares, and reach live behind the account owner's private Insights and are not available for arbitrary third-party accounts — so any tool claiming a "true reach" ER on someone else's profile is estimating, not measuring. Stick to likes + comments and your numbers stay comparable across every creator you evaluate.
Pull the profile and posts from their exact contracts
Use GET /v1/live/instagram/profile for the canonical follower count and GET /v1/live/instagram/posts for canonical recent posts. The two operations archive different first-party documents—the public profile REST response and exact timeline pages—so the product does not pretend one response contains data it did not observe.
curl "https://api.virev.ai/v1/live/instagram/profile?q=nike" \
-H "Authorization: Bearer $VIREV_API_KEY"A 12-post timeline sample is usually enough for a clean ER. Need a deeper sample? /v1/live/instagram/posts?q=nike&limit=-1 walks up to 240 posts at $0.0005 per 12, archiving every exact page before returning canonical post projections.
const headers = { Authorization: "Bearer kb_live_..." };
const [profileRes, postsRes] = await Promise.all([
fetch("https://api.virev.ai/v1/live/instagram/profile?q=nike", { headers }),
fetch("https://api.virev.ai/v1/live/instagram/posts?q=nike&limit=12", { headers }),
]);
const profilePayload = await profileRes.json();
const postsPayload = await postsRes.json();
const followers = profilePayload.data.followers;
const posts = postsPayload.data.posts;
const totalInteractions = posts.reduce(
(sum, post) => sum + (post.likes ?? 0) + (post.comments ?? 0),
0
);
const avgPerPost = totalInteractions / posts.length;
const engagementRate = (avgPerPost / followers) * 100;
console.log(`ER: ${engagementRate.toFixed(2)}%`);Run it yourself — edit the username to pull a live profile and post batch
A complete ER function in Python
Here is a self-contained function you can drop into a vetting pipeline. It pulls a recent batch, computes ER from likes and comments, and returns the intermediate numbers so you can show your work in a report instead of a single opaque percentage.
import requests
API = "https://api.virev.ai"
HEADERS = {"Authorization": "Bearer kb_live_..."}
def engagement_rate(handle: str) -> dict:
profile_res = requests.get(
f"{API}/v1/live/instagram/profile", params={"q": handle}, headers=HEADERS
)
posts_res = requests.get(
f"{API}/v1/live/instagram/posts",
params={"q": handle, "limit": 12},
headers=HEADERS,
)
profile_res.raise_for_status()
posts_res.raise_for_status()
profile = profile_res.json()["data"]
posts = posts_res.json()["data"]["posts"]
followers = profile["followers"]
interactions = sum((post.get("likes") or 0) + (post.get("comments") or 0) for post in posts)
avg_per_post = interactions / len(posts)
er = (avg_per_post / followers) * 100
return {
"handle": handle,
"followers": followers,
"posts_sampled": len(posts),
"avg_interactions": round(avg_per_post),
"engagement_rate": round(er, 2),
}
print(engagement_rate("nike"))Guard against thin samples
If a batch comes back with fewer posts than you asked for — a brand-new account, or one that mostly posts private content — dividing by a tiny denominator produces a wild ER. In production, skip accounts with fewer than ~6 recent posts and flag them for manual review rather than trusting a two-post average.
Why ER beats follower count for vetting
Follower count is the number creators optimize and inflate; engagement rate is the number that is expensive to fake at scale. Running ER across a shortlist turns a pile of media-kit claims into a ranked, comparable table in minutes. It surfaces two failure modes instantly: big accounts with dead audiences (high followers, sub-1% ER) and hidden gems (modest followers, 5%+ ER that punches above its tier).
Benchmarks vary by source, but the tiering below reflects the widely reported pattern that engagement falls as audience grows. Treat these as directional guardrails for spotting outliers, not hard pass/fail thresholds — always compare within the same follower tier and niche.
| Follower tier | Typical ER range | Read |
|---|---|---|
| Nano (1K-10K) | 4-8% | Highest intimacy; small but reactive audiences |
| Micro (10K-50K) | 2-5% | Sweet spot for most campaigns |
| Mid (50K-500K) | 1.5-3% | Reach scales, engagement dilutes |
| Macro (500K-1M) | 1-2% | Solid brand reach, lower per-post reaction |
| Mega (1M+) | 0.5-1.5% | Below ~0.5% is a red flag worth investigating |
The mechanics are identical whether you are checking one creator or ten thousand: resolve the canonical profile, then fetch the post sample. The same contracts power a full influencer discovery tool; for field mappings, see the Instagram profile data API guide.
Costs and the envelope
Every response returns { data, meta }, and meta carries cost, balance, and request_id so you can reconcile spend per call. You are never charged for a non-200 — a 404 on a misspelled handle or an upstream 502/504 costs nothing, so a vetting run that hits a few dead accounts only bills the successful pulls.
| Endpoint | Returns | Cost |
|---|---|---|
/v1/live/instagram/profile | Canonical profile and follower count | $0.0005 |
/v1/live/instagram/posts | Canonical posts from exact pages | $0.0005 per 12 posts |
/v1/live/instagram/post | Canonical single post + media | $0.0005 |
A 12-post ER calculation uses one profile call and one timeline unit, or $0.001 total. The intro offer — pay $1, get a $5 balance — therefore covers roughly 5,000 complete ER calculations before you top up. Default rate limit is 100 requests per minute, surfaced via X-RateLimit-* headers; a 429 includes Retry-After so you can pace bulk runs cleanly.
Score any creator on real engagement, not vanity followers
10,000 Instagram profiles for $1. No subscription. Compute ER for your whole shortlist in one afternoon.
Get your API key →