How to Build an Instagram Competitor Monitoring Dashboard with an API

Knowing what your competitors post — and which of those posts actually land — is one of the highest-leverage inputs a social or marketing team has. Doing it by hand means opening a dozen profiles every morning and eyeballing like counts. A monitoring dashboard does it automatically: it snapshots each competitor on a schedule, records engagement over time, and flags the posts that break out.

This guide shows how to build the data layer for that dashboard with an Instagram API — the Instagram Cheapest API on RapidAPI. You'll poll a watchlist of accounts, store engagement history, compute share-of-voice, and detect viral posts — all on real-time, uncached public data at as little as $0.10 per 1,000 requests.

The architecture in one paragraph

A competitor monitor is a scheduled job, not a live API. It runs (say) once a day, pulls each competitor's latest posts and Reels, writes a row per post into a database, and compares against yesterday's snapshot. The dashboard reads from your database, never from Instagram directly — so the UI is instant even though each fetch takes a few seconds. Because the data is real-time and uncached, every snapshot reflects the true current state.

Step 1: Resolve your watchlist to user IDs

Store competitors as usernames, but most endpoints key off the numeric user_id. Resolve each once with user/{username} and cache the ID (it doesn't change).

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 resolve(username):
    r = requests.get(f"{BASE}/user/{username}", headers=HEADERS)
    r.raise_for_status()
    p = r.json()
    return {
        "username": username,
        "user_id": p.get("user_id"),          # confirm field from raw JSON
        "followers": p.get("follower_count"), # confirm field from raw JSON
    }

WATCHLIST = ["competitor_a", "competitor_b", "competitor_c"]
profiles = [resolve(u) for u in WATCHLIST]

Re-running user/{username} on each cycle also gives you a follower-count time series — useful for spotting growth spurts or follower drops.

Step 2: Snapshot posts and Reels each cycle

For every competitor, pull the most recent page of user_media and user_reels. You usually don't need full history every run — just the latest page is enough to catch new posts and update engagement on recent ones.

def latest_media(user_id):
    r = requests.get(f"{BASE}/user_media", headers=HEADERS,
                     params={"user_id": user_id})
    r.raise_for_status()
    return r.json().get("items", [])  # confirm key from raw JSON

def latest_reels(user_id):
    r = requests.get(f"{BASE}/user_reels", headers=HEADERS,
                     params={"user_id": user_id})
    r.raise_for_status()
    return r.json()

def snapshot(profile):
    posts = latest_media(profile["user_id"])
    rows = []
    for p in posts:
        rows.append({
            "username": profile["username"],
            "code": p.get("code"),
            "likes": p.get("like_count", 0),
            "comments": p.get("comment_count", 0),
            "taken_at": p.get("taken_at"),
        })
    return rows

Write each row to your database keyed on (code, snapshot_date). Storing the same post across multiple days is what lets you watch engagement accumulate and compute velocity.

If you need a competitor's full back catalogue (for a one-time baseline), paginate with the next_max_id cursor for posts and the after cursor for Reels — the full looping pattern is in the pagination guide.

Step 3: Detect viral posts with engagement velocity

A "viral" post isn't just one with high total engagement — it's one engaging fast relative to the account's norm. Compare a post's engagement to the competitor's recent average:

def viral_flags(rows, threshold=3.0):
    by_user = {}
    for r in rows:
        by_user.setdefault(r["username"], []).append(r)
    alerts = []
    for username, posts in by_user.items():
        engagements = [p["likes"] + p["comments"] for p in posts]
        if not engagements:
            continue
        avg = sum(engagements) / len(engagements)
        for p in posts:
            eng = p["likes"] + p["comments"]
            if avg and eng > avg * threshold:
                alerts.append({"username": username, "code": p["code"],
                               "engagement": eng, "x_avg": round(eng / avg, 1)})
    return alerts

# alerts = viral_flags(all_rows)  # e.g. "competitor_a post is 4.2x their average"

Wire these alerts to Slack or email and your team learns about a competitor's breakout post the same day it happens — not a week later.

Step 4: Track user-generated content and collaborations

The user_tag_media endpoint returns posts a competitor is tagged in — a window into their UGC, ambassador activity, and brand collaborations. Poll it to see who's promoting them and how often.

def tagged_media(user_id, after=None):
    params = {"user_id": user_id}
    if after:
        params["after"] = after
    r = requests.get(f"{BASE}/user_tag_media", headers=HEADERS, params=params)
    r.raise_for_status()
    return r.json()  # paginates with the `after` cursor (page_info.end_cursor)

A spike in tagged posts often signals a paid campaign or influencer push — exactly the kind of competitive move worth knowing about early.

Step 5: Compute share-of-voice and benchmarks

With snapshots flowing into your database, the dashboard metrics fall out of simple aggregation:

To go deeper on any single account — comment sentiment, audience authenticity — combine this with the influencer analysis and fake-engagement detection workflows.

What does monitoring cost?

Per competitor per daily cycle you need roughly: 1 profile + 1 media page + 1 Reels page (+ optionally 1 tagged-media page) ≈ 3–4 requests. Tracking 50 competitors daily is ~50 × 4 × 30 = 6,000 requests/month — comfortably inside the Pro tier's included quota.

Use the optional fields parameter on every call to trim the raw JSON to just the metrics you store — that keeps you inside the 10 GB/month bandwidth allowance even with a large watchlist.

Compliance and responsible use

This API returns public Instagram data only. Competitive benchmarking from public profiles is a standard business use, but you remain responsible for complying with Instagram's terms of service and applicable privacy laws (GDPR, CCPA). The API is not affiliated with or endorsed by Meta or Instagram.

Conclusion

A competitor monitoring dashboard is fundamentally a scheduled snapshot job plus a database. With user/{username}, user_media, user_reels, and user_tag_media, you can track posting cadence, engagement trends, collaborations, and viral breakouts across an entire watchlist — and at $0.10–$0.13 per 1,000 requests, monitoring dozens of competitors daily costs just a few dollars a month.

Get started on RapidAPI →

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.

Start Building Today

Get 30 free requests per month on the Basic plan. No commitment required.

Get Started on RapidAPI