Instagram Scraper - Profiles, Posts and Reels, No Login
Pricing
from $0.45 / 1,000 result returneds
Instagram Scraper - Profiles, Posts and Reels, No Login
Scrape Instagram profiles, posts and reels. Send a username to get the profile and its recent posts. Send a post or reel URL to get that one item. Instagram's profile lookup fails on business accounts, so it tries other routes until one answers. $0.45 per 1,000 items.
Pricing
from $0.45 / 1,000 result returneds
Rating
5.0
(1)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
58
Total users
20
Monthly active users
16 hours
Issues response
a day ago
Last modified
Categories
Share
Instagram Scraper: profiles, posts and reels from a username or a link
Give it a username and you get that account's profile row plus the media on its public grid. Give it a post or reel link and you get that one item, whether or not it is still on the grid. Everything comes back flat, one row per thing, ready for a sheet or a database.
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, and no signed-out route reaches the difference. Paging also stops at 60 pages, so a very large account will not come back complete in one run.
| Input | Usernames, or profile, post and reel links |
| Output | One row per profile, post or reel |
| Ceiling | 5,000 rows per run |
| Account needed | None from you |
| Price | $0.45 per 1,000 rows, flat on every plan |
๐ What Instagram Scraper does
Instagram serves a signed-out client through the same endpoints its own site calls, and those endpoints move. The profile lookup currently errors out on accounts with a business category set, which is most brands and most creators. So the run tries the routes in turn until one answers, and builds the row from whatever came back.
A username returns the 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.
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 you give it
{"usernames": ["nasa"],"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 scrapes that grid, a /p/, /reel/ or /tv/ link scrapes 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 | YYYY-MM-DD. Older posts are dropped before they are billed. Anything it cannot read as a date turns the filter off without warning, so check the format. |
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. |
sessionCookies | none | Optional. Your own Instagram cookie, so the run sees what your account sees. Use a throwaway account: the value sits in the run input, which anyone who can open the run can read. |
proxyConfiguration | Apify default | Leave it alone unless you have your own servers to use. Picking a country here can come back with no rows at all. |
notionConnector, notionParentId | none | Optional. Write each row into a Notion database as well as the dataset. |
Run it with nothing at all and you get one labelled sample row, free, so you can see the shape first.
๐ค What you get back
A real profile row from a real run, with the picture link and the bio cut short:
{"ok": true,"type": "profile","username": "nasa","id": "528817151","fullName": "NASA","biography": "Making the seemingly impossible, possible. ...","externalUrl": "https://www.nasa.gov/","followersCount": 104352628,"followsCount": 91,"postsCount": 4928,"verified": true,"isBusinessAccount": true,"private": false,"profilePicUrl": "https://scontent-lga3-1.cdninstagram.com/v/t51.2885-19/...","url": "https://www.instagram.com/nasa/"}
Post and reel rows come back with type set to image, video or carousel, and carry:
| Field | What it is |
|---|---|
shortCode, url | Unique per post, and the canonical /p/<code>/ link. Use shortCode as your dedupe key across runs. |
caption, hashtags, mentions | The caption, and the tags and handles parsed out of it without the # or @. |
likesCount, commentsCount, videoViewCount | Counters as Instagram reports them at read time. |
displayUrl, videoUrl, images | Direct links to the cover, the video file and every carousel frame. Signed and time limited. |
dimensions, isVideo, isPinned | Shape of the media, and whether it is pinned to the top of the grid. |
ownerUsername, ownerId, timestamp | Who posted it and when, as an ISO timestamp that never moves. |
taggedUsers, coauthorProfiles, sponsorProfiles | Profile objects with id, username, full name, link and picture. |
isPaidPartnership, isSponsored, likesAndViewCountsDisabled, isCommentsDisabled | What the account turned on or off for that post. |
Fields Instagram leaves out stay null rather than being guessed. postsCount and
isBusinessAccount are the two that go null when the run had to fall back to the rendered page.
๐งพ 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 | no |
| A diagnostic | ok: false and an errorCode | no |
Filter on ok == true and you have your data. NOT_FOUND means Instagram showed the item as gone.
BLOCKED means the route refused that item this run, which re-running usually clears. Either way
the run carries on to the next item and neither row is billed.
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.
โถ๏ธ How to run it
- Open Instagram Scraper and click Try for free.
- Type a handle into Profile usernames, or paste links into Start URLs.
- 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.
๐ฐ How much does it cost?
$0.45 per 1,000 rows. Flat on every Apify plan, no volume tiers.
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 people use it for
- Pulling a competitor's recent posts every Monday and diffing the like and comment counts.
- Building a content archive for a handful of accounts, captions and media links included.
- 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 ships.
๐ง What it does not do
- No comments, follower lists or stories. Those are separate actors, two of them 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. Paging stops at 60 pages, so a very large account needs
onlyPostsNewerThanto make the walk purposeful. postsCountandisBusinessAccountcan benullwhen the run fell back to the rendered page. The rest of the profile row is still there.- A signed-out run can see a smaller grid. If a profile shows more in your browser than the run returned, that is what you are looking at, and your own cookie is the fix.
- A bad date turns the filter off instead of failing, so write
onlyPostsNewerThanasYYYY-MM-DD. - 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.
๐งญ 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 contact details and engagement | Instagram Profile Scraper |
| One post or reel you already have the link for | Instagram Post Scraper |
| Posts under a hashtag | Instagram Hashtag Scraper |
| Reels found by keyword | Instagram Reels Search |
โ Questions people ask
Do I need an Instagram account? No. Everything above works signed out. The cookie field is only for the accounts where a signed-out reader sees less.
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? Either the account has fewer, your date filter dropped them, or the walk hit its paging ceiling on a very large grid.
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.
Can I run it on a schedule? Yes. Apify's scheduler, or start it from the API and read the dataset when it finishes.
๐ 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.
