Instagram Scraper - Profiles, Posts and Reels
Pricing
from $0.44 / 1,000 results
Instagram Scraper - Profiles, Posts and Reels
Scrape Instagram profiles, posts and reels. A username gives the profile row plus the posts on its grid; a post or reel link gives that one item. Rows have the caption, likes, comments, views, media links, tagged users and timestamp. $0.45 per 1,000 rows.
Pricing
from $0.44 / 1,000 results
Rating
5.0
(2)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
89
Total users
30
Monthly active users
23 hours
Issues response
a day ago
Last modified
Categories
Share
Give it an Instagram username or a post link and get flat rows back: the account's profile row plus the posts and reels on its public grid, or the one post or reel you linked, with caption, likes, comments, views, media links and tagged people. One row per thing, ready for a sheet.
The part worth knowing up front: a signed-out run sees the grid Instagram serves a visitor. On most accounts that is the whole grid. On a few it is smaller than what you see while logged in. One profile's walk also stops after 60 pages of 12 posts, about 720, so a very large account does not come back complete in one run.
| Input | Usernames, or profile, post and reel links |
| Output | One row per profile, post or reel: caption, likes, comments, views, media links, owner, tagged users, timestamp |
| Ceiling | 5,000 rows per run |
| Account needed | None |
| Price | $0.45 per 1,000 rows on the free plan, down to $0.435 on Business. The free plan's $5 a month covers about 11,000 |
π What Instagram Scraper does
Public accounts are supported, including brands and creators with a business category set. On some
business accounts postsCount and isBusinessAccount come back null; the rest of the row is
filled in.
A username returns that account's profile row, then its grid in the grid's own order: pinned tiles
first, then newest first. Every media row carries isPinned, and skipPinnedPosts drops the pinned
ones if you want plain publication order. Reels an account keeps off its grid are a separate set,
and includeReelsTabOnly adds them on top of the grid.
A post or reel link returns that one item, whether or not it is still on the grid. You can mix usernames and links in one run.
Hashtags and mentions are parsed out of the caption for you. Tagged users, collaborators and sponsors come back as their own arrays with ids, names and links. Rows are deduplicated inside a run, so nothing is returned or billed twice.
π What data you get from each Instagram profile and post
| What you get | Field |
|---|---|
| What the row is: a profile, a photo, a video or a carousel | type |
| Profile: handle, display name, numeric id, link | username, fullName, id, url |
| Profile: bio, bio link and picture | biography, externalUrl, profilePicUrl |
| Profile: follower, following and post counts | followersCount, followsCount, postsCount |
| Profile: verified, business and private flags | verified, isBusinessAccount, private |
| Post: link and shortcode | url, shortCode |
| Post: caption, and the hashtags and handles in it | caption, hashtags, mentions |
| Post: likes, comments and video views | likesCount, commentsCount, videoViewCount, videoPlayCount |
| Post: cover image, video file and every carousel frame | displayUrl, videoUrl, images, dimensions, isVideo |
| Post: who posted it and when | ownerUsername, ownerId, timestamp |
| Post: tagged people, co-authors and sponsors | taggedUsers, coauthorProfiles, coauthorUsernames, sponsorProfiles |
| Post: paid partnership, hidden likes, comments off, pinned | isPaidPartnership, isSponsored, likesAndViewCountsDisabled, isCommentsDisabled, isPinned |
| Post: Instagram's alt text for the image | accessibilityCaption |
βΆοΈ How to scrape Instagram posts
- Open Instagram Scraper and click Try for free.
- Type a handle into Profile usernames, or paste links into Start URLs (profiles or posts).
- Set Max results. Start at 50 while you look at the output shape.
- Click Start.
- Download the dataset as JSON, CSV or Excel, or pull it from the Apify API.
Start it with both lists empty and you get one labelled sample row, which is not charged.
π° How much does it cost to scrape Instagram posts?
$0.45 per 1,000 rows. That is the free plan's price; paid plans pay a little less: $0.445 on Starter, $0.44 on Scale and $0.435 on Business. On the free plan, the $5 Apify gives you each month covers about 11,000 rows.
A profile row and a post row cost the same. You pay for rows that carry data, so the sample row,
diagnostic rows, posts dropped by your date filter and duplicates inside a run are not charged.
resultsLimit is the ceiling on both the rows and the spend.
π₯ What you give it
{"usernames": ["nasa"],"onlyPostsNewerThan": "2 weeks","resultsLimit": 50}
| Field | Default | What it is |
|---|---|---|
usernames | none | Handles with or without @. Each returns its profile row plus its grid. |
startUrls | none | Paste links instead. A profile link reads that grid; a /p/, /reel/ or /tv/ link reads that one item. |
resultsLimit | 50 | Rows across the whole run, profiles and posts together. 1 to 5,000. This is also your spend cap. |
onlyPostsNewerThan | none | A day (2026-05-01) or a window (7 days, 2 weeks, 1 month); the form gives you a calendar. Days count in UTC, and pinned tiles have to meet the date too. A value that is not a date stops the run with a BAD_INPUT row before anything is read. |
skipPinnedPosts | off | Drop the tiles pinned to the top of the grid, up to three of them. |
includeReelsTabOnly | off | Also return reels the account keeps off its grid, such as trial reels. It adds them; it does not limit the run to reels. |
sessionCookies | none | Optional. Your own Instagram cookie, used from the first request so the run sees what your account sees. Treat the value like a password. |
proxyConfiguration | none | Leave it alone unless you have your own servers to use. |
notionConnector, notionParentId | none | Optional. Write each row into a Notion database as well as the dataset. |
π€ What you get back
A real post row from a run on 30 September 2026, with the image links cut short:
{"ok": true,"type": "image","shortCode": "Dd4OWyWjFsh","url": "https://www.instagram.com/p/Dd4OWyWjFsh/","caption": "I spy with my X-ray eyes π\n\nUsing @NASAChandraXray, astronomers discovered a new class of \"hypersoft\" objects that give off very low-energy, difficult to detect X-rays. These objects exist in multiple galaxies, including this one, the Pinwheel Galaxy.\n\n#NASA #Space #Galaxy","hashtags": ["NASA", "Space", "Galaxy"],"mentions": ["NASAChandraXray"],"likesCount": 240993,"commentsCount": 664,"videoPlayCount": null,"videoViewCount": null,"displayUrl": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-15/...","videoUrl": null,"images": ["https://scontent-iad6-1.cdninstagram.com/v/t51.82787-15/..."],"isVideo": false,"dimensions": {"height": 1441, "width": 1439},"ownerUsername": "nasa","ownerId": "528817151","timestamp": "2026-09-29T16:48:08.000Z","accessibilityCaption": null,"taggedUsers": [],"sponsorProfiles": [],"coauthorProfiles": [],"coauthorUsernames": [],"isPaidPartnership": false,"isSponsored": false,"likesAndViewCountsDisabled": false,"isCommentsDisabled": false,"isPinned": false}
| Field | How to read it |
|---|---|
shortCode | Unique per post. Use it as your dedupe key across runs. |
ownerUsername | On a collaboration post this can be the other account, with the one you asked for in coauthorUsernames. |
videoViewCount, videoPlayCount | null on photos. On a reel the two usually hold the same number, because Instagram sends one count for plays and views. |
isSponsored | The same flag as isPaidPartnership, kept under both names. |
displayUrl, videoUrl, images | Signed and time limited. Download anything you want to keep. |
postsCount, isBusinessAccount | On the profile row, null on some business accounts. The rest of the profile row is still there. |
π§Ύ Reading the output
Three kinds of row can land in your dataset.
| Row | How to spot it | Billed |
|---|---|---|
| A profile, post or reel | ok: true and a type | yes |
| The sample row | _sample: true, charged: false | no |
| A diagnostic | ok: false and an errorCode | no |
Filter on ok == true and you have your data. Diagnostic rows carry one of these codes:
| Code | What it means |
|---|---|
NOT_FOUND | Instagram showed the item or account as gone, private or suspended. |
NOT_SERVED | This request was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED. |
RATE_LIMITED, SERVER_ERROR, NETWORK | Instagram was busy or unreachable for that item. Try again in a few minutes. |
PARTIAL | A profile's posts stopped coming part way. postsDelivered says how many arrived, and only those were charged. A new run starts from the top. |
BAD_INPUT | onlyPostsNewerThan was not a date. Nothing was read. |
NO_RESULTS | The run finished with nothing to return for your input. |
TIME_LIMIT | The run got close to its time limit and stopped on its own. The results delivered before that are complete and charged. Give the run more time, or ask for fewer results, to get the rest. |
After any of these except TIME_LIMIT, which ends the run, the run carries on to the next item. None of these rows is billed, and only one case fails the run: when the time limit stopped it before any result came back, the run ends as failed, with a TIME_LIMIT row saying so.
One quirk of the Overview table: it shows post columns, so a profile row reads as an almost empty line there. Open the row itself or download the JSON and it is all present.
π‘ What people use it for
- Pulling a competitor's recent posts every Monday and diffing the like and comment counts.
- Checking one post or reel at a time from links a team drops into a channel.
- Measuring posting cadence:
timestampacross a grid tells you how often an account actually posts.
From a grid to what the comments say, in three steps:
- Run this on a username with
onlyPostsNewerThanset to30 days. - Sort the rows on
commentsCountand copy theurlof the posts at the top. - Paste those links into Instagram Comments Scraper and read what people actually said.
π§ What it does not do
- No comments or stories. Those are separate actors, linked below.
- A private account returns the profile shell only. Bio, counts and
private: truecome through. There is nothing public behind it to read. - Recent posts, not the full archive. About 720 posts per profile at most, so on a very large
account use
onlyPostsNewerThanto make the walk purposeful. - A signed-out run can see a smaller grid. If a profile shows more in your browser than the run returned, that is the difference.
- Media links expire. They are signed, short-lived links. Fetch anything you want to keep.
- Counts are a snapshot at read time, not at publish time.
- It is not an official Instagram tool. Dami's Studio is independent and is not affiliated with or endorsed by Instagram or Meta, or by any other company named on this page.
π§ Which Instagram scraper do you need?
| If you want | Use |
|---|---|
| A profile plus the posts on its grid | This one |
| One row per account, with engagement | Instagram Profile Scraper |
| Posts and reels from links you already have | Instagram Post Scraper |
| The reels on a profile's reels tab, with play counts and MP4 links | Instagram Reel Scraper |
| Posts under a hashtag | Instagram Hashtag Scraper |
| Comments under a post or reel | Instagram Comments Scraper |
| Stories a profile has up right now | Instagram Stories Scraper |
β Questions people ask
Do I need an Instagram account to scrape posts?
No. Everything above works signed out. The cookie field is optional.
Is resultsLimit per username or per run?
Per run, and the profile row counts towards it. Ask for 100 across three handles and you get 100 rows in total, not 300.
Why did I get fewer posts than I asked for?
The account has fewer, your date filter dropped them, or the walk reached its 720-post ceiling. If
the posts stopped for any other reason, a free PARTIAL row says so.
Why do the numbers differ from what I see in the app?
Counts keep moving, and the row holds them as they were when it was read. If posts are missing, open the profile in a private browser window: what a logged-out visitor sees there is what this actor can read.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has ready-made code
for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/instagram-scraper. Either way the run
happens on your Apify account at the same price.
Is scraping Instagram legal?
This reads public profiles and public posts only, never private accounts or messages. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
π If something breaks
Open the Issues tab on the actor page. Include the username or link you used and the run ID, and the log is enough for us to see what happened.