# How do I get a competitor’s Instagram engagement rate?

Instagram. Checked September 2026.

Read the public profile for `metrics.followers`, then the profile posts endpoint for the last 12 or so posts. Engagement rate is likes plus comments, averaged over those posts, divided by followers. Two calls with Openhandle. No account link, no Graph API.

Use only what is public. Reach, impressions, and saves live in the owner’s insights. A vendor that shows a competitor’s reach is estimating.

## GET /v1/instagram/profiles/@username/posts

```bash
curl "https://api.openhandle.dev/v1/instagram/profiles/@northstar_forge_test/posts" \
  -H "Authorization: Bearer $OPENHANDLE_API_KEY"
```

```ts
import { OpenHandle } from '@openhandle/sdk';

const openhandle = new OpenHandle({ apiKey: process.env.OPENHANDLE_API_KEY! });
const profile = openhandle.instagram.profile('northstar_forge_test');
const [{ data: account }, page] = await Promise.all([profile.get(), profile.posts.list()]);

const posts = page.data.filter(post => post.metrics.likes !== null);
const perPost = posts.reduce((sum, post) => sum + post.metrics.likes! + post.metrics.comments!, 0) / posts.length;
console.log((perPost / account.metrics.followers!) * 100); // percent
```

200 OK:

```json
{
  "platform": "instagram",
  "resource": "post",
  "capturedAt": "2026-09-18T11:52:18Z",
  "source": "live",
  "data": [
    { "id": "910100000001", "metrics": { "likes": 840, "comments": 5, "views": 12000 } },
    { "id": "910100000002", "metrics": { "likes": null, "comments": 5, "views": 12700 } },
    { "id": "910100000003", "metrics": { "likes": 900, "comments": 5, "views": 13400 } }
  ],
  "meta": { "cursors": { "next": "b3BhcXVlLWN1cnNvcg" } }
}
```

Trimmed to metrics. The second post has hidden likes and returns null. Skip it, do not count it as zero. The example is a Test profile.

## Define the rate before you compute it

- **Per follower.** (likes + comments) per post, averaged, divided by followers. The common benchmark. Depends on follower count, so compare accounts of similar size.
- **Per view, for reels.** (likes + comments) divided by `metrics.views`. Better for video-first accounts and not skewed by dead followers.
- **Window.** Last 12 posts is the usual window. Skip the newest post if it is less than a day old, it has not settled.

## What is public, and what is not

| Metric | Public | Where |
|---|---|---|
| Likes | Yes, unless hidden | `metrics.likes`, `null` when hidden |
| Comments | Yes | `metrics.comments` |
| Reel plays | Yes | `metrics.views`, `null` for images |
| Shares and saves | Sometimes | `metrics.shares`, `metrics.saves` where Instagram shows them |
| Reach, impressions | No | Owner insights only |

## Track it over time

Run the two calls once a week, store the rate with `capturedAt`, and chart it. Use `freshness=live` so each row is a fresh read. Store the profile `id`, not the handle, so a rename does not break the series.

## When this does not work

These answers are definitive. Store them, do not retry them.

| Situation | Status | Code |
|---|---|---|
| The account is private | 403 | `PROFILE_PRIVATE` |
| The account is deleted, banned, or never existed | 404 | `PROFILE_NOT_FOUND` |

```json
{
  "error": {
    "code": "PROFILE_PRIVATE",
    "message": "This profile is private.",
    "requestId": "req_01j8…",
    "retryable": false
  }
}
```

An account that hides likes on every post has no likes-based rate. Use comments per post, or the per-view rate on reels, and say which one you used.

## Related

- [Influencer vetting use case](https://openhandle.dev/use-cases/influencer-vetting): Sign creators on the platform’s numbers, not their media kit.
- [Metric semantics](https://openhandle.dev/docs/concepts/metric-semantics): What a view, a like, and a share mean on each platform.
- [How do I track a competitor’s follower growth?](https://openhandle.dev/questions/how-do-i-track-a-competitors-follower-growth): The scheduled read this builds on.
