references/comparison.md
---
name: instagram-api-comparison
description: How fetcher.sh's Instagram endpoints compare to the official Instagram Graph API and a self-hosted headless-browser scraper, qualitative and scoped to what each actually does.
---
# Instagram data access — comparing your options
Three ways to get Instagram data programmatically. This is a qualitative
comparison of access models, not a pricing sheet — treat any specific
competitor price you see elsewhere as something to verify yourself, not
something repeated here.
## Official Instagram Graph API / Basic Display API
- Requires a Meta developer account, app review, and — for most business
data — a connected Instagram Business/Creator account with granted
permissions; you generally can't pull an arbitrary third-party profile's
full data the way you can your own connected account's.
- Access model is built around managing your own or your clients' connected
accounts, not general-purpose read access to any public profile.
- Best fit when you're building a product that manages Instagram accounts on
behalf of their owners (e.g. a scheduling or analytics tool with granted
permissions).
## Headless-browser scraper (self-hosted)
- No API key at all — you drive a real browser (Playwright/Puppeteer) against
instagram.com and parse the DOM or intercepted responses yourself.
- You own and pay for the infrastructure (proxies, browser fleet, login/
session handling) and the maintenance burden when Instagram changes its
frontend or anti-bot checks.
- No fixed per-call price — cost is your compute + proxy bill, which scales
with volume and gets more expensive as anti-bot defenses tighten.
- Best fit when you need something the same subdomain-per-service model
doesn't expose yet, or you're already running scraping infra for other
sites and want one more target.
## fetcher.sh (`instagram.fetcher.sh`)
- No developer account, no OAuth, no app review — authenticate to
`instagram.fetcher.sh` itself with a Bearer key or an x402 payment.
- Flat $0.004/call across all 16 endpoints (see
[`endpoints.md`](endpoints.md)), no monthly minimum, no tier to outgrow.
- Fixed endpoint set (profiles, posts, reels, stories, followers, hashtags,
audio, locations) mirrored across 11 services with the same JSON envelope
and the same MCP tool names — one integration pattern reused everywhere.
- Read-only, on-demand: no webhooks, no streaming, no writes/publishing. If
you need "notify me when X happens," you poll on a schedule yourself.
- Best fit when you want ad-hoc or moderate-volume reads on public profiles
and content without connecting or owning the account, and you're fine
treating Instagram as one of several data sources behind the same MCP/REST
pattern.
## Named providers to benchmark against
Don't take any provider's framing (including this one) at face value — pull
the same data from each and compare the actual response. A few concrete
starting points, current as of this writing (verify pricing and limits
yourself before deciding, since all three change their terms independently
of this repo):
| Provider | Docs | What to check |
| --- | --- | --- |
| Instagram Platform (Graph API) | [developers.facebook.com/docs/instagram-platform](https://developers.facebook.com/docs/instagram-platform) | Does your use case need a connected/owned account, or just public reads? |
| Apify Instagram Scraper | [apify.com/apify/instagram-scraper](https://apify.com/apify/instagram-scraper) | Does an Actor-based, dataset/export-oriented workflow fit your pipeline better than direct REST? |
| Bright Data Instagram Scraper API | [docs.brightdata.com/datasets/scrapers/instagram/introduction](https://docs.brightdata.com/datasets/scrapers/instagram/introduction) | Do you need bulk async collection (1000s of URLs) more than single-call reads? |
## Build your own comparison
Pick one fixed test — the same profile, the same hashtag, the same post — and
run it against fetcher.sh and whichever provider above is a candidate.
Record, per provider:
- Which required fields actually came back (not just which fields the docs
promise)
- Cost for the exact rows you kept, after discarding anything you didn't need
- Time from request to usable JSON
- What happens on the second and third call — does pagination stay stable,
does a cached/rate-limited path kick in, does the price change
A five-minute test like this is worth more than any comparison table,
including this one.
## Quick decision guide
| Need | Pick |
| --- | --- |
| Managing your own/clients' connected Instagram Business accounts | Official Graph API |
| Reading public profile/post/hashtag data, no account connection needed | fetcher.sh |
| Already running scraping infra, need something fetcher.sh doesn't expose | Headless browser |
| Same integration pattern across Instagram, TikTok, X, Reddit, etc. | fetcher.sh |
## See also
- [`endpoints.md`](endpoints.md) — full parameter reference
- [`scenarios.md`](scenarios.md) — worked `curl` examples
- [`faq.md`](faq.md) — task-oriented "how do I..." answers
references/endpoints.md
---
name: instagram-api-endpoints
description: Full parameter reference for every Instagram endpoint on instagram.fetcher.sh — path params, query params, required flags, and enum values, straight from the live OpenAPI contract.
---
# Instagram — full endpoint reference
Base URL: `https://instagram.fetcher.sh`. All 16 endpoints are `GET`,
authenticated with either `Authorization: Bearer bby_live_...` (credits) or
an x402 payment — see [`SKILL.md`](../SKILL.md) for the payment flow. Path
parameters are written as `{param}`; substitute the real value. `?` marks an
optional query param. Every endpoint on this host is a flat $0.004/call.
This file lists every parameter that exists. It does not describe response
fields — the response shape is generated at request time from the live
handlers, so the authoritative machine-readable version is always
[`/openapi.json`](https://instagram.fetcher.sh/openapi.json). Treat any field
name you haven't seen in an actual response as unverified.
## Profiles
| Endpoint | Params |
| --- | --- |
| `/api/user/handle/{handle}` | none |
| `/api/userid/{handle}` | none |
| `/api/user/{id}` | none |
| `/api/user/search` | `query` (required) · `cursor`? |
`/api/user/handle/{handle}` is the hero endpoint — it returns the full
profile in one call. `/api/userid/{handle}` is a lighter-weight lookup when
you only need the numeric ID, not the full profile, before calling one of the
`/api/user/{id}/...` endpoints below.
## User content
| Endpoint | Params |
| --- | --- |
| `/api/user/{id}/posts` | `cursor`? |
| `/api/user/{id}/posts/tagged` | `cursor`? |
| `/api/user/{id}/reels` | `cursor`? |
| `/api/user/{id}/stories` | none |
| `/api/user/{id}/followers` | `cursor`? |
| `/api/user/{id}/followings` | `cursor`? |
`{id}` is the numeric ID from either profile lookup above, not the `@handle`.
Stories return whatever is currently active on the account — there's no
archive/history param, since Instagram itself only exposes the live set.
## Posts
| Endpoint | Params |
| --- | --- |
| `/api/post/code/{code}` | none |
| `/api/post/{id}/comments` | `cursor`? |
`{code}` is the shortcode segment from a post URL
(`instagram.com/p/{code}/`) — use this when you have a link, not a numeric
post ID.
## Hashtags, audio, and locations
| Endpoint | Params |
| --- | --- |
| `/api/hashtag/{name}/posts` | `cursor`? · `page`? |
| `/api/hashtag/{name}/reels` | none |
| `/api/audio/{id}/posts` | `cursor`? |
| `/api/location/{id}/posts` | `tab`? · `cursor`? · `page`? |
`{name}` for hashtags is the tag text without the `#`. `tab` on the location
endpoint selects which content section to read (Instagram's own location
page tabbing) — leave unset for the default view.
## See also
- [`scenarios.md`](scenarios.md) — one worked `curl` per endpoint
- [`faq.md`](faq.md) — task-oriented "how do I..." answers
- [`comparison.md`](comparison.md) — fetcher.sh vs. the official Instagram Graph API vs. a browser scraper
references/faq.md
---
name: instagram-api-faq
description: Frequently asked questions about the Instagram API on fetcher.sh — profiles, hashtags, followers, and monitoring, answered with exact endpoints.
---
# Instagram API alternative — FAQ
## Getting started
### Do I need an Instagram/Meta developer account or app review?
No. `instagram.fetcher.sh` is a separate read-only proxy — you authenticate
to *it*, not to Meta. No developer account, no app review, no Graph API
permissions to request.
### What payment methods are supported?
Prepaid credits (`Authorization: Bearer bby_live_...`) or x402 micropayments
in USDC on Base, Polygon, Arbitrum, Monad, or Solana — see the [`fetcher`
skill](../../fetcher/SKILL.md) for setup.
### Is there a rate limit?
No fixed per-minute cap enforced by fetcher.sh itself — cost is the limiter:
each call is billed individually (credits or x402), so throughput is bounded
by your budget and by the upstream page latency, not by a quota.
### Can I access a private account's posts?
No. Every endpoint here reflects what's publicly visible on the platform —
if an account or post isn't public, fetcher.sh can't see it either. There's
no login or session step that would grant private-account access.
## Profiles
### How do I look up a profile by @handle?
`GET /api/user/handle/{handle}` on `instagram.fetcher.sh` — this is the hero
endpoint and returns the full profile in one call. See
[`scenarios.md`](scenarios.md).
### How do I get just the numeric user ID for a handle?
`GET /api/userid/{handle}` — lighter-weight than the full profile lookup,
useful when the only thing you need next is the ID for a
`/api/user/{id}/...` call.
### How do I get a user's follower list?
`GET /api/user/{id}/followers`, where `{id}` is the numeric ID from either
profile lookup above. Paginate with the returned `cursor` until the response
stops returning one.
### Can I export followers to CSV directly?
Not server-side. Fetcher.sh returns JSON; paginate through
`/api/user/{id}/followers` and write the pages to a CSV yourself. There's no
built-in export job.
## Posts, reels, and stories
### How do I look up a post if I only have the Instagram link?
`GET /api/post/code/{code}`, where `{code}` is the shortcode segment from
`instagram.com/p/{code}/` — no numeric ID needed.
### Can I get a user's Stories archive/history?
No — `/api/user/{id}/stories` returns whatever is currently active on the
account, matching what Instagram itself exposes. There's no historical
stories endpoint.
### How do I distinguish a user's own posts from posts they're tagged in?
`/api/user/{id}/posts` is what they posted; `/api/user/{id}/posts/tagged` is
what other accounts posted and tagged them in.
### Does fetcher.sh host or download the actual media files?
No — responses return whatever metadata (including any media URLs) the
underlying page exposes; fetcher.sh doesn't host, re-encode, or proxy the
media itself. Treat any media URL in a response as pointing back to
Instagram's own infrastructure, not fetcher.sh's.
## Hashtags, audio, and locations
### How do I monitor a hashtag or location for new posts?
There's no webhook or streaming endpoint. Poll `/api/hashtag/{name}/posts`
or `/api/location/{id}/posts` on a schedule and diff against the post IDs
you've already seen — see the
[hashtag/location monitoring task guide](../../../task-guides/instagram-hashtag-and-location-monitoring.md).
### How do I find posts using a specific audio track?
`GET /api/audio/{id}/posts`, where `{id}` is the audio track's numeric ID
(visible in the track's Instagram URL).
## Discovery and reference
### Can an agent discover these endpoints without reading this file?
Yes — `instagram.fetcher.sh/mcp` exposes `search_endpoints`,
`describe_endpoint`, and `fetch_data` as MCP tools, so an MCP-connected agent
can explore the API live instead of relying on this document.
### Where's the authoritative schema if this doc goes stale?
`https://instagram.fetcher.sh/openapi.json` and
`https://instagram.fetcher.sh/llms.txt` are generated from the live route
handlers and always match production.
## See also
- [`endpoints.md`](endpoints.md) — full parameter reference
- [`scenarios.md`](scenarios.md) — worked `curl` examples
- [`comparison.md`](comparison.md) — fetcher.sh vs. the official Instagram Graph API vs. a browser scraper
references/scenarios.md
---
name: instagram-api-scenarios
description: Worked curl examples for every Instagram endpoint on instagram.fetcher.sh, one per endpoint, including pagination.
---
# Instagram — full scenario cookbook
Every call below assumes:
```bash
export FETCHER_API_KEY="bby_live_xxxxxxxxxxxx"
```
Swap the `curl -H "Authorization: Bearer $FETCHER_API_KEY"` prefix for a bare
`curl` if you're paying per call with x402 instead — see the [`fetcher`
skill](../../fetcher/SKILL.md).
## Profiles
**Full profile by handle (the hero call):**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/handle/natgeo"
```
**Just the numeric ID for a handle:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/userid/natgeo"
```
**Profile by numeric ID:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/787132"
```
**Search accounts by name:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
--data-urlencode "query=national geographic" -G \
"https://instagram.fetcher.sh/api/user/search"
```
## User content
**A user's posts:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/787132/posts"
```
**Posts the user is tagged in (not posted by them):**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/787132/posts/tagged"
```
**A user's reels:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/787132/reels"
```
**A user's currently active stories:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/787132/stories"
```
**A user's followers, paginated:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/787132/followers"
# next page
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
--data-urlencode "cursor=<cursor from previous response>" -G \
"https://instagram.fetcher.sh/api/user/787132/followers"
```
**Accounts a user follows:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/787132/followings"
```
## Posts
**Look up a post by its URL shortcode:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/post/code/CxYzAbC123d"
```
**Comments on a post:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/post/3123456789012345678/comments"
```
## Hashtags, audio, and locations
**Posts under a hashtag:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/hashtag/sunsetphotography/posts"
```
**Reels under a hashtag:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/hashtag/sunsetphotography/reels"
```
**Posts using a specific audio track:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/audio/<audioId>/posts"
```
**Posts tagged at a location:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/location/<locationId>/posts"
```
## See also
- [`endpoints.md`](endpoints.md) — full parameter reference
- [`faq.md`](faq.md) — task-oriented "how do I..." answers
- [`comparison.md`](comparison.md) — fetcher.sh vs. the official Instagram Graph API vs. a browser scraper
SKILL.md
---
name: instagram-api
description: >-
An Instagram API alternative on fetcher.sh — pay-per-call in USDC via x402,
or prepaid credits with a Bearer key, no login and no session cookies. Use
when the user wants to resolve an Instagram profile by @handle, search
users by keyword, pull a profile's posts, reels, stories, tagged posts,
followers, or followings, look up a single post by its shortcode, read a
post's comments, fetch posts under a hashtag or reel-only hashtag feed,
pull posts from a location, or pull posts using a specific audio/music
track. Also covers Instagram follower export, hashtag and location
monitoring, influencer discovery, competitor content tracking, and
Instagram data pipelines without an official Graph API business
verification or a headless browser.
keywords:
- instagram
- instagram-api
- instagram-api-alternative
- ig-api
- social-media
- social-listening
- hashtag-tracking
- x402
- ai-agent
---
# Instagram API
Instagram data on demand: profile lookup by @handle, posts, reels, stories,
tagged posts, followers and followings, hashtag and location feeds, audio/music
feeds, and post comments — one plain HTTP GET per call, paid as you go. No
login, no session cookies, no headless browser, no Graph API business
verification.
Base URL: `https://instagram.fetcher.sh`
## Quick reference
| | |
| --- | --- |
| Base URL | `https://instagram.fetcher.sh` |
| Auth | `Authorization: Bearer bby_live_...` or x402 (USDC) |
| Price | $0.004/call (flat) |
| Endpoints | 16, all `GET` |
| MCP | `https://instagram.fetcher.sh/mcp` |
| Machine-readable | `/openapi.json` · `/llms.txt` · `/skill.md` |
## Which endpoint do I need?
| I want to... | Call |
| --- | --- |
| Look up a profile by @handle | `GET /api/user/handle/{handle}` |
| Search accounts by name | `GET /api/user/search` |
| Get a user's posts, reels, or stories | `GET /api/user/{id}/posts` / `/reels` / `/stories` |
| Get a user's followers or followings | `GET /api/user/{id}/followers` / `/followings` |
| Look up a post by its share-URL shortcode | `GET /api/post/code/{code}` |
| Get a post's comments | `GET /api/post/{id}/comments` |
| Find posts under a hashtag | `GET /api/hashtag/{name}/posts` |
| Find posts tagged at a location | `GET /api/location/{id}/posts` |
Full param details for every row: [`references/endpoints.md`](references/endpoints.md).
## Authentication
Two ways to pay, same data — full mechanics in the [`fetcher`
skill](../fetcher/SKILL.md):
```bash
# 1. Prepaid credits (recommended — get a key at https://fetcher.sh/topup
# or via POST /api/credits/topup, see the fetcher skill)
export FETCHER_API_KEY="bby_live_xxxxxxxxxxxx"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/handle/nasa"
# 2. x402 pay-per-call — omit the header; a GET with no payment returns 402
# with machine-readable payment requirements (USDC on Base, Polygon,
# Arbitrum, Monad, or Solana). @x402/fetch signs and retries automatically.
```
Every response is `{ "status": number, "message": string, "data": ... }`; the
HTTP status mirrors `status`.
## Endpoints (16 — all GET, $0.004/call)
| Endpoint | What it returns |
| --- | --- |
| `/api/user/handle/{handle}` | Full profile by @handle — follower counts, bio, numeric ID |
| `/api/user/search` | Profiles matching a keyword query |
| `/api/userid/{handle}` | Just the numeric user ID for a @handle |
| `/api/user/{id}` | Profile by numeric ID |
| `/api/user/{id}/posts` | A user's posts |
| `/api/user/{id}/posts/tagged` | Posts the user is tagged in |
| `/api/user/{id}/reels` | A user's reels |
| `/api/user/{id}/stories` | A user's active stories |
| `/api/user/{id}/followers` | A user's followers |
| `/api/user/{id}/followings` | Accounts a user follows |
| `/api/post/code/{code}` | A single post by its shortcode (from the post URL) |
| `/api/post/{id}/comments` | A post's comments |
| `/api/hashtag/{name}/posts` | Posts under a hashtag |
| `/api/hashtag/{name}/reels` | Reels under a hashtag |
| `/api/location/{id}/posts` | Posts tagged at a location |
| `/api/audio/{id}/posts` | Posts using a specific audio/music track |
`{id}` / `{handle}` / `{name}` / `{code}` are path parameters. Optional
`cursor` / `page` paginate; `query` (user search) is required where it
appears.
## Scenarios
**Resolve a profile by handle — the endpoint most callers want first:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/handle/nasa"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/handle/natgeo"
```
**Search for profiles by keyword, or resolve just the numeric ID for a handle:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
--data-urlencode "query=fitness influencer" -G \
"https://instagram.fetcher.sh/api/user/search"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/userid/nasa"
```
**A profile's posts, reels, stories, and tagged posts (by numeric ID from the
handle lookup above):**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/528817151/posts"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/528817151/reels"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/528817151/stories"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/528817151/posts/tagged"
```
**Followers and followings:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/528817151/followers"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/user/528817151/followings"
```
**A single post by shortcode (the part of the URL after `/p/`), and its
comments:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/post/code/C0JD3tntcmy"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/post/3245142029192513970/comments"
```
**Posts and reels under a hashtag, posts from a location, and posts using an
audio track:**
```bash
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/hashtag/travel/posts"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/hashtag/travel/reels"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/location/213131048/posts"
curl -H "Authorization: Bearer $FETCHER_API_KEY" \
"https://instagram.fetcher.sh/api/audio/271328201351336/posts"
```
## MCP
```json
{
"mcpServers": {
"instagram": {
"url": "https://instagram.fetcher.sh/mcp",
"headers": { "Authorization": "Bearer bby_live_..." }
}
}
}
```
Free: `search_endpoints`, `describe_endpoint`, `check_balance`. Paid:
`fetch_data` (any endpoint above), `topup_credits`, plus the named shortcut
`instagram_user_handle`. Drop the `headers` block to pay per call with x402
instead — see the [`fetcher` skill](../fetcher/SKILL.md) for the full flow.
## Errors
- `400` — missing/invalid parameter (message names it)
- `401` — unknown or rotated key
- `402` — payment required (x402 challenge) or `topup_required` (credits
exhausted)
- `404` — not a priced path
- No rate limits; no refunds on upstream failures (settlement precedes
delivery)
## Reference
- Deep dives: [`references/endpoints.md`](references/endpoints.md) (every
param) · [`references/scenarios.md`](references/scenarios.md) (one `curl`
per endpoint) · [`references/faq.md`](references/faq.md) ·
[`references/comparison.md`](references/comparison.md) (vs. the official
Instagram Graph API and a browser scraper)
- Task guides: [profile lookup](../../task-guides/instagram-profile-lookup.md) ·
[hashtag and location monitoring](../../task-guides/instagram-hashtag-and-location-monitoring.md)
- Slash command: [`/instagram-profile`](../../commands/instagram-profile.md)
- Full agent setup: <https://instagram.fetcher.sh/skill.md>
- OpenAPI 3.1 contract: <https://instagram.fetcher.sh/openapi.json>
- Condensed catalog: <https://instagram.fetcher.sh/llms.txt>
- Payment, credits, and MCP deep dive: [`fetcher` skill](../fetcher/SKILL.md)
- Site: <https://instagram.fetcher.sh>