Instagram Scraper - Profiles, Posts & Reels (No Login)
Scrape Instagram profiles, posts and reels as JSON: followers, caption, likes, comments, media URLs. No login or API key. $0.45 per 1,000 items.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
usernames,startUrls,onlyPostsNewerThan(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.00045 per result = $0.45 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Result returned | Charged once per profile or post returned in the dataset. Failed or empty runs are not charged. | $0.00045 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-19, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
usernames | Instagram usernames, with or without @. Each one returns a profile row plus the media on that account's public profile grid, in the grid's own order: pinned tiles first, then newest first. | array |
startUrls | Paste Instagram URLs directly. A profile URL returns that account's public grid; a post or reel URL returns that one item, whether or not it is on the grid. | array |
onlyPostsNewerThan | Keep posts and reels published on or after this date. Pick a day in the calendar, or switch to a relative window such as 7 days or 2 weeks, which suits a scheduled run. Days are counted in UTC. Pinned tiles have to meet the date too. Leave it empty for no date limit. | string |
skipPinnedPosts | Drop the posts an account pinned to the top of its grid, up to three of them. Off by default; every media row carries isPinned either way. Reels pinned to the reels tab are a separate set and are not counted here, they come back at their own date. | boolean |
includeReelsTabOnly | Off by default, so a profile run returns what the profile grid shows. Turn it on to also get media that only the reels tab lists, such as trial reels and reels an account keeps off its grid. | boolean |
resultsLimit | Maximum rows across the run, including the profile row. The limit is applied after the grid is filtered and ordered, so pinned tiles use result slots unless Skip pinned posts is on. | integer |
notionConnector | Optional. Deliver the results to your connected Notion via Apify MCP connectors, no extra code. | string |
notionParentId | Optional Notion database/data-source id to create the pages in. | string |
sessionCookies | Optional. Runs work without an account. But Instagram serves a signed-out visitor less than a signed-in one: on some profiles a few posts are not in the signed-out grid at all, and no signed-out route reaches them. Paste your own Instagram cookie here and the run uses it from the first request, so it sees what your account sees, with a rate limit no other run shares. In Chrome: F12 -> Application -> Cookies -> https://www.instagram.com -> copy the `sessionid` value. Paste one per line. Use a throwaway account, never one you care about. | array |
What you get
A structured dataset — each result includes fields like:
typeshortCodeurlcaptionhashtagslikesCountcommentsCountvideoViewCountdisplayUrlimagesisVideoownerUsernametimestampisPinnedisPaidPartnershiplikesAndViewCountsDisabledisCommentsDisabledtaggedUserscoauthorProfilessponsorProfilesisSponsoredvideoPlayCountExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
8 ready-to-run use cases
Instagram Profile Scraper - Export Posts, Likes & Comments
Export any public Instagram profile's posts: caption, likes, comments, media URLs, owner and timestamp. Swap the username and run it. No login needed.
Instagram Competitor Analysis - Track a Rival Account
Pull a competitor's recent Instagram posts and engagement to see what they publish and how it lands. Works on any public account, no login.
Download Instagram Posts and Reels as JSON or CSV
Download a public account's Instagram posts and reels: caption, likes, comments, video and image URLs. Change the username to any public handle.
Instagram Post Scraper - Filter Posts by Date
Scrape a public Instagram account's posts from a date you choose onward. Set the cutoff and the handle, get captions, likes, comments and media URLs.
Instagram Data Export From a Profile URL
Paste an Instagram profile URL and get its recent posts: caption, likes, comments and media URLs. Any public account, no login and no API key.
Instagram Archive: Export Post History From a Date
Archive a public Instagram account's post history from a date you choose: captions, likes, comments, media URLs and timestamps, as CSV or JSON.
Compare Instagram Accounts Side by Side
Run several public Instagram accounts at once and compare their latest posts and engagement in one table. Add or remove handles as you like.
Instagram Engagement Rate Calculator for Creators
Check a creator's engagement before a brand deal: recent posts with likes and comments per post, so you can work out the rate. Any public handle.
Related tools in Social Media Scrapers
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
Tweet Scraper
Scrape X (Twitter) tweets by handle or URL, no API key. Rows carry text, likes, retweets, views and author. Search needs your X cookie.
Twitter (X) User Scraper - Profiles & Followers, No Login
Scrape X (Twitter) profiles: followers, following, post count, name, bio and verification. No API key, no login. $0.14 per 1,000 profiles.
TikTok User Scraper - Profiles, Followers & Stats (No Login)
Scrape TikTok profiles without a login. Get follower, following, likes and video counts, bio, verified flag and avatar. $0.35 per 1,000 profiles.
Reddit Scraper
Scrape Reddit posts with no login or API key. Rows carry titles, selftext, scores, authors, comment counts and permalinks. $0.50 per 1,000 rows, flat.
Reddit Posts Search Scraper
Search Reddit by keyword: title, post text, author, subreddit, permalink and dates. Add a free Reddit app for scores. $0.891 per 1,000 posts.
Reddit Video Scraper & Downloader
Download v.redd.it videos from any subreddit or Reddit user, with the audio joined back in. Get post details and dedupe. $0.03 per video record.
Where this tool sits
- Categories
- Social Media Scrapers
- Platforms
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
Any public account works, including brands and creators with a business category set. You get the profile row and then the posts on the grid, the same as for a personal account. On some business accounts postsCount and isBusinessAccount come back null; the rest of the row is filled in.
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 | A day (2026-05-01) or a window (7 days, 2 weeks, 1 month); the form gives you a calendar. Older posts are dropped before they are billed. 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. |
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, videoPlayCount | Counters as Instagram reports them at read time. On a reel the two video counters usually hold the same number, because Instagram sends one count for plays and views; the output table shows it once, as Views. |
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. isSponsored is the same flag as isPaidPartnership, kept under both names. |
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. PARTIAL means a profile's posts stopped coming part way, and postsDelivered says how many arrived. Either way the run carries on to the next item and none of these rows 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
1. Open Instagram Scraper and click Try for free. 2. Type a handle into Profile usernames, or paste links into Start URLs. 3. Set Max results. Start at 50 while you look at the output shape. 4. Click Start. 5. 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
onlyPostsNewerThan to 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.
- 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.