# Instagram hashtag API

Platform: Instagram.

Call `GET /v1/instagram/hashtags/{name}/posts` with the hashtag name, without the `#`. Each request returns one page of public posts and a cursor for the next page.

There is no weekly hashtag limit, and you do not need a business account or app review.

## GET /v1/instagram/hashtags/{name}/posts?sort=recent

```bash
curl "https://api.openhandle.dev/v1/instagram/hashtags/syntheticvolume/posts?sort=recent" \
  -H "Authorization: Bearer $OPENHANDLE_API_KEY"
```

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

const openhandle = new OpenHandle({ apiKey: process.env.OPENHANDLE_API_KEY! });
let page = await openhandle.instagram.hashtag('syntheticvolume').posts.list({ sort: 'recent' });

while (page) {
    for (const post of page.data) console.log(post.author.handle, post.metrics.likes);
    page = await page.next();
}
```

200 OK:

```json
{
  "platform": "instagram",
  "resource": "post",
  "capturedAt": "2026-09-18T10:11:05Z",
  "source": "live",
  "data": [
    {
      "id": "910100000001",
      "createdAt": "2026-08-10T09:00:00Z",
      "author": { "id": "910000000001", "handle": "northstar_forge_test" },
      "metrics": { "likes": 840, "comments": 24, "views": 12000 }
    }
  ],
  "meta": { "cursors": { "next": "b3BhcXVlLWN1cnNvcg" } }
}
```

Trimmed to one post and the fields most apps need. The example is a Test hashtag with paginated posts, so you can test paging on a free Test key.

## What you get

- **Posts.** Each post has `id`, `createdAt`, the `author`, and likes, comments, and views in `metrics`.
- **Recent or top.** Use `sort=recent` for the newest posts first. Use `sort=top` for the posts Instagram ranks highest.
- **Reels only.** Call `GET /v1/instagram/hashtags/{name}/reels` for the reels under the hashtag.
- **The hashtag itself.** Call `GET /v1/instagram/hashtags/{name}` for its name, avatar, and whether Instagram marks it trending.

## Price

- **Per request.** $0.0025 per live request. $0.002 per request after 100,000 requests in a month. One page of results is one request.
- **Older data costs less.** Set `freshness` to say how old the data may be. Data up to 24 hours old: $0.0005. Data up to 7 days old: $0.0001. Data up to 30 days old: free.
- **Failed means free.** Errors and invalid requests are never billed. You pay for answers, and a confirmed not-found is an answer.
- **Free to start.** Every new workspace starts with 100 free live requests, no card needed. Test keys are never charged.

## When this does not work

Empty is an answer. A cursor from another request is a mistake.

| Situation | Status | Code |
|---|---|---|
| The hashtag has no public posts or Instagram hides it | 200 | `empty data` |
| The cursor came from another hashtag, sort, or freshness | 400 | `CURSOR_MISMATCH` |
| The hashtag name is malformed | 400 | `INVALID_IDENTIFIER` |

```json
{
  "error": {
    "code": "CURSOR_MISMATCH",
    "message": "The cursor does not belong to this request.",
    "requestId": "req_01j8…",
    "retryable": false
  }
}
```

An empty page bills as an answered request.

## Related

- [Instagram API](https://openhandle.dev/apis/instagram): Every Instagram endpoint with examples.
- [List hashtag posts](https://openhandle.dev/docs/api-reference/instagram-hashtag-posts-list): The endpoint reference with every parameter and SDK.
- [How do I get Instagram hashtag posts past the 30 hashtag limit?](https://openhandle.dev/questions/how-do-i-get-instagram-hashtag-posts-past-the-30-hashtag-limit): Where the limit comes from and how to collect posts on a schedule.
