How to monitor competitors on Instagram with an API
Watching a competitor's Instagram account comes down to a handful of numbers that move over time: how fast they gain followers, how often they post, and which posts actually land. There is no official feed for any of that, so you poll a real-time Instagram data API — one call returns a competitor's profile or a page of their posts as clean JSON, synchronously, in about a second. This guide walks through tracking competitor accounts with herascrape, the same building blocks behind the competitor monitoring solution.
Create one in the dashboard — $1 free on signup, no card. Pass it as the x-api-key header and start calling.
What to track
Most competitor monitoring reduces to three signals, all readable from public accounts:
- Follower growth — the
follower_counton the profile, snapshotted on a schedule so you can chart the slope rather than a single number. - New posts and reels — the account's posts grid and reels feed, so you see what they shipped and when.
- Per-post engagement — the
like_countandcomment_counton each post, which tell you which content resonated and let you compute an engagement rate against their follower base.
Everything below is just those three signals, pulled on a timer and stored.
Snapshot a profile
Start by resolving the competitor's username to a profile. GET /users/username/{username} returns the account in one call, including follower_count, media_count, and verification status. It also returns the numeric id (pk) you will reuse for every posts and reels request — so keep it.
import os, httpx
KEY = os.environ["HERASCRAPE_KEY"]
BASE = "https://api.herascrape.com"
r = httpx.get(f"{BASE}/users/username/nike",
headers={"x-api-key": KEY})
p = r.json()
print(p["pk"], p["follower_count"], p["media_count"], p["is_verified"])Once you have the pk, you can skip the lookup on later runs and hit GET /users/{id} directly. See the profile endpoint for the full field list.
Pull the latest posts and reels
With the id in hand, GET /users/{id}/posts returns the account's posts grid. Like every list endpoint, it answers in a uniform envelope — { items, next_cursor, has_more } — so you page by passing next_cursor back as the cursor query parameter until has_more is false. For monitoring you usually only want the newest page or two, since posts come back newest-first.
Each item carries like_count and comment_count alongside the caption and media, which is all you need to score engagement.
def latest_posts(user_id, pages=1):
cursor = None
with httpx.Client(headers={"x-api-key": KEY}) as c:
for _ in range(pages):
params = {"cursor": cursor} if cursor else {}
page = c.get(f"{BASE}/users/{user_id}/posts", params=params).json()
for post in page["items"]:
print(post["like_count"], post["comment_count"], post["caption"])
if not page["has_more"]:
return
cursor = page["next_cursor"]
latest_posts("528817151")Reels work the same way at GET /users/{id}/reels, and GET /users/{id}/tagged covers posts other accounts tagged them in — swap the path, keep the cursor loop. The user posts endpoint reference lists every field an item returns.
Put it on a schedule
Monitoring is just these calls on a timer. A daily run is enough to chart follower growth and catch new posts; drop to hourly if you are watching a launch or a campaign in close to real time. Because each call maps to a single Instagram request, polling stays cheap and predictable:
- $0.0004 per request, flat — $0.40 per 1,000. A daily profile snapshot plus one posts page for 50 competitors is 100 requests a day, about $0.04.
- Only successful
2xxresponses are billed. A429from exceeding your rate limit, or any error, costs nothing — so a retry on a transient failure is free. - The default limit is 50 requests per second per key, which is far more than any polling schedule needs, and it can be raised on request.
See pricing for the full breakdown. There are no batch jobs or webhooks to manage: you call the endpoint on your own cron, and the response comes back synchronously.
Turn it into a dashboard
The one piece the API does not do for you is remember yesterday. Growth and engagement only mean something as a series, so write each run's result to your own store — a row per account per day is plenty:
{
"username": "nike",
"captured_at": "2026-10-25",
"follower_count": 307000000,
"media_count": 1284,
"last_post": { "like_count": 412000, "comment_count": 3100 }
}
With a few days of rows you can chart the follower slope, flag a day where a competitor's post beat their median engagement, or diff media_count to detect new posts without re-reading the whole grid. The API gives you a fresh, accurate snapshot on every call; your database turns those snapshots into the trend line that actually answers "are they pulling ahead?"
Create one in the dashboard — $1 free on signup, no card. Pass it as the x-api-key header and start calling.