How to Scrape Instagram Data in 2026: Profiles, Posts, Reels, Comments
Get public Instagram profiles, posts, reels, comments, hashtags, highlights and transcripts as clean JSON with one REST API: no login, no scraper, no app review.
The simplest way to get public Instagram data in 2026 is a hosted scraping API: one HTTPS call returns a profile, its posts and reels, the comments on a post, a hashtag feed or a reel transcript as JSON. With crawlfeed, every Instagram call costs 1 credit, needs only an API key, and returns the same shape as TikTok, YouTube and X data.
Instagram holds a huge share of the visual web: brand campaigns, creator portfolios, product launches and the comment threads under them. It is also one of the harder platforms to get data out of. This guide shows how to pull public Instagram data (profiles, posts, reels, comments, hashtags, story highlights and transcripts) with plain HTTPS calls, with working code in cURL, JavaScript and Python.
Why is Instagram data hard to get?
Three things get in the way:
- The official API covers your own accounts. Meta’s Instagram APIs are designed for professional accounts you manage. Business Discovery gives you basic fields for other business and creator accounts, but not arbitrary public profiles, comment threads or hashtag feeds for a product.
- Logged-out browsing is locked down. Instagram shows a login wall after a few pages, rate-limits anonymous traffic hard, and the internal endpoints the web app uses change without notice.
- The data is spread out. A reel, a carousel and a photo are shaped differently, and counts, captions and audio sit in different places depending on which endpoint returned them.
Here is how the usual options compare:
| Approach | Public profiles you do not manage | Comments and hashtags | Maintenance |
|---|---|---|---|
| Instagram Graph API | Limited (Business Discovery) | Your own media only | Low, but needs app review |
| Your own scraper | Yes | Yes | High: logins, proxies, broken parsers |
| Scraping API (crawlfeed) | Yes | Yes | None on your side |
The rest of this guide takes the last route.
What Instagram data can you get?
Every call below is live on crawlfeed today. The table is generated from the API’s own catalogue, so the endpoints and prices are exactly what you will be charged:
| Operation | Endpoint | Needs | Credits |
|---|---|---|---|
| Profile | /v1/instagram/profile | handle | 1 |
| Posts | /v1/instagram/posts | handle | 1 |
| Post | /v1/instagram/post | id | 1 |
| Comments | /v1/instagram/comments | post_id | 1 |
| Search | /v1/instagram/search | q | 1 |
| Linked profiles | /v1/instagram/linked-profiles | handle | 10 |
| Reels and shorts | /v1/instagram/reels | handle | 1 |
| Tagged posts | /v1/instagram/tagged | handle | 1 |
| Hashtag | /v1/instagram/hashtag | tag | 1 |
| Trending | /v1/instagram/trending | — | 1 |
| Transcript | /v1/instagram/transcript | id | 1 |
| Summary | /v1/instagram/summary | id | 4 |
| Replies | /v1/instagram/replies | post_id, comment_id | 1 |
| Search posts | /v1/instagram/search/posts | q | 1 |
| Search profiles | /v1/instagram/search/profiles | q | 1 |
| Topic | /v1/instagram/topic | q | 1 |
| Collections | /v1/instagram/collections | handle | 1 |
| Collection posts | /v1/instagram/collection/posts | id | 1 |
| Posts using a sound | /v1/instagram/track/posts | id | 1 |
Everything comes back in crawlfeed’s unified types (Profile, Post, Comment and friends), which are the same across all 26 platforms.
Get an Instagram profile
You need an API key (new accounts get 100 free credits) and a handle, without the @:
curl -G https://api.crawlfeed.dev/v1/instagram/profile \
-H "Authorization: Bearer $CRAWLFEED_KEY" \
--data-urlencode "handle=natgeo"The response is a Profile wrapped in the standard envelope. Trimmed, and with illustrative numbers, it looks like this:
{
"data": {
"platform": "instagram",
"handle": "natgeo",
"display_name": "National Geographic",
"verified": true,
"followers": 1234567,
"following": 123,
"posts_count": 12345,
"bio": "…",
"links": ["…"]
},
"meta": { "credits_used": 1, "credits_remaining": 99, "cache": "MISS", "data_age_s": 0 }
}A profile costs 1 credit. Counts are always numbers, and a field Instagram does not expose comes back as null rather than disappearing, so your code does not need a special case per account.
Get posts from an Instagram account
/v1/instagram/posts returns an account’s recent posts, newest first, one page per call:
curl -G https://api.crawlfeed.dev/v1/instagram/posts \
-H "Authorization: Bearer $CRAWLFEED_KEY" \
--data-urlencode "handle=natgeo"Each item is a Post with text (the caption), created_at, media (one entry per photo or video, with type, url, thumbnail_url and duration_s), engagement (likes, comments, views and friends), hashtags, mentions and is_ad. Carousels simply have more than one entry in media.
To get the next page, pass meta.next_cursor back as cursor. When next_cursor is missing, you have reached the last page. Every page is billed, so stop once you have enough:
import os, requests
posts, cursor = [], None
while True:
params = {"handle": "natgeo", **({"cursor": cursor} if cursor else {})}
res = requests.get(
"https://api.crawlfeed.dev/v1/instagram/posts",
params=params,
headers={"Authorization": f"Bearer {os.environ['CRAWLFEED_KEY']}"},
)
body = res.json()
posts.extend(body["data"])
cursor = body["meta"].get("next_cursor")
if not cursor or len(posts) >= 100:
breakIf you already know a post’s id, /v1/instagram/post?id=… returns just that one.
Get comments and replies on a post
Pass the post id as post_id:
curl -G https://api.crawlfeed.dev/v1/instagram/comments \
-H "Authorization: Bearer $CRAWLFEED_KEY" \
--data-urlencode "post_id=<post_id>"Each Comment has the text, the author, likes, created_at and reply_to_id. Comments page the same way as posts. For the replies under one comment, call /v1/instagram/replies with both the post_id and the comment_id.
Reels, highlights, tagged posts and audio
Beyond the main grid, Instagram has a few surfaces of its own, and each has its own call:
- Reels:
/v1/instagram/reels?handle=…lists an account’s reels only, which is usually what you want for video analytics. - Story highlights:
/v1/instagram/collections?handle=…lists an account’s highlights, and/v1/instagram/collection/posts?id=…returns the items inside one. - Tagged posts:
/v1/instagram/tagged?handle=…returns public posts other accounts have tagged a profile in, handy for tracking brand mentions and user-generated content. - Audio:
/v1/instagram/track/posts?id=…lists reels that use a given audio track.
curl -G https://api.crawlfeed.dev/v1/instagram/reels \
-H "Authorization: Bearer $CRAWLFEED_KEY" \
--data-urlencode "handle=natgeo"Search, hashtags and trending
To discover content rather than read a known account:
- Keyword search:
/v1/instagram/search/posts?q=…for posts,/v1/instagram/search/profiles?q=…for accounts, or/v1/instagram/search?q=…for the platform’s general search. - Hashtags:
/v1/instagram/hashtag?tag=…returns posts using a hashtag. Pass the tag without the#. - Trending:
/v1/instagram/trendingreturns what is trending right now, with an optionalcountry.
curl -G https://api.crawlfeed.dev/v1/instagram/hashtag \
-H "Authorization: Bearer $CRAWLFEED_KEY" \
--data-urlencode "tag=coffee"Get a reel transcript
For research, summaries or feeding reels to an LLM, the spoken words are often more useful than the caption:
curl -G https://api.crawlfeed.dev/v1/instagram/transcript \
-H "Authorization: Bearer $CRAWLFEED_KEY" \
--data-urlencode "id=<id>"A transcript costs 1 credit, and includes timings when they are available.
Handle errors and rate limits
Errors are RFC 9457 problem details with a stable code, so branch on the code, not the message:
| Code | What it means | What to do |
|---|---|---|
not_found | The handle or post does not exist, or is private | Check the id; do not retry |
invalid_request | A required parameter is missing or malformed | Fix the request |
rate_limited | You sent requests faster than your limit | Wait retry_after seconds |
insufficient_credits | Your balance is lower than the call’s price | Top up; nothing was charged |
platform_unavailable | Instagram or the upstream failed | Retry later; the call was refunded |
A call that fails is refunded automatically, so retrying never charges you twice.
Add Arabic sentiment and dialect
If your audience writes in Arabic, add enrich=arabic to a profile, post or comments call. Each item gains an enrichment field with the dialect, sentiment, entities and topics, for 3 extra credits per call. It is most useful on comment threads, where it turns thousands of replies into a sentiment breakdown.
Use Instagram data from Claude or Cursor
If you would rather ask than code, connect the crawlfeed MCP server and your assistant gets the same calls as tools:
claude mcp add --transport http crawlfeed https://mcp.crawlfeed.dev/mcp \
--header "Authorization: Bearer $CRAWLFEED_KEY"Then ask something like “which of @natgeo’s last 20 reels got the most comments, and what were people saying?”. The setup for every client is in our guide to MCP.
Wrapping up
For public Instagram data, a scraping API saves you from logins, proxies and parsers that break whenever the web app changes. With crawlfeed, every Instagram call costs one credit, and the same code works for TikTok, YouTube, X and LinkedIn. The full reference is at /docs/platforms/instagram.
Questions
Is it legal to scrape Instagram data?
Collecting publicly available data is generally lawful in many jurisdictions, but it depends on where you are, what you collect and what you do with it. crawlfeed only returns public data and never logs in to accounts. If you store personal data, you are responsible for having a lawful basis under laws such as the GDPR, and for honouring deletion requests.
Does Instagram have an official API for this?
Meta’s Instagram APIs are built for professional accounts you manage. Business Discovery can read basic public information about other business and creator accounts, but there is no official endpoint for reading any public profile, its comments or a hashtag feed at scale, which is why most teams use a scraping API for public data.
How much does it cost to get Instagram data with crawlfeed?
Every Instagram call costs 1 credit: a profile, a page of posts or reels, a page of comments, a hashtag page, a search or a transcript. New accounts get free credits, and failed calls are refunded.
How fresh is the data?
Responses are cached briefly to keep repeat calls fast and cheap. meta.cache and meta.data_age_s tell you how old a response is; add fresh=true to fetch it live for double the price.
Can I get data from private Instagram accounts?
No. crawlfeed only returns what anyone can see without logging in. Content from a private account is not available: those calls fail with not_found, and failed calls are refunded.
Try it on your own data
Every example above runs as written. New accounts get 100 free credits, no card needed.
Get an API key