Scrape Instagram Profiles, Scrape Instagram Posts - Reels API
Pricing
from $1.05 / 1,000 profiles
Scrape Instagram Profiles, Scrape Instagram Posts - Reels API
Extract Instagram posts, reels, profiles, places and hashtags, no login. Get data from Instagram using Instagram URLs or usernames: content, metrics, metadata - followers, bio, links, reel plays, likes and comment counts. Newest 12-20 posts per account, run via API, schedule and monitor runs.
Pricing
from $1.05 / 1,000 profiles
Rating
0.0
(0)
Developer
Snow Leo Data
Maintained by CommunityActor stats
0
Bookmarked
70
Total users
29
Monthly active users
13 days ago
Last modified
Categories
Security
Limited permissionsShare
Instagram Scraper — profiles, posts, reels, hashtags and places
Public Instagram data without a login, without cookies and without a browser. One table holds all four kinds of row: profiles, posts and reels, hashtags and places.
Did this save you time? A short review on this Actor's page, or Save, helps other people find it.
Post depth, stated plainly (checked 2026-10-27). Instagram now asks for a
login on the full post feed. Without a login this actor returns, per account,
the newest 12–20 posts shown on the public profile page (photos, videos,
carousels, captions, hashtags, comments count; likes and exact dates are
missing on some of them) and, with Add play counts for recent reels, up to 12
reels with play counts. It does not return a full history of 200 or
more posts per account. If Instagram opens the feed again, the actor walks it
automatically (50 posts per request, up to your postsPerProfile), and the run
log says which of the two paths was used.
What it is good at: profile data (followers, following, post count, bio, every bio link, verified and private flags), the latest posts and reels of an account, reel play counts, hashtag and place pages, and watch mode that charges only for what changed. No login, no cookies, no browser, and an empty run always says why.
What you get
Profile — username, user id, full name, biography, followers, following, post count, verified, private, memorialised, profile picture, every bio link with its title, external URL, pronouns, account badges, Threads username, highlight count, whether the account has reels.
Post / reel (the newest 12–20 per account today; some fields, such as likes and exact date, are absent on posts read from the profile page) — shortcode, post id, type (photo, video, carousel, reel), product type, date, likes, comments, plays, caption, hashtags, mentions, owner username, owner id, owner full name, owner verified, image URL, video URL, width, height, carousel item count and every carousel image, tagged users, co-authors, paid-partnership flag, comments-disabled flag, alt text, reel music title and artist, Instagram's topic pills, place name and coordinates.
Hashtag — the tag, its volume when Instagram states it, Instagram's own description of the tag, related keywords, plus the 12 posts of that page.
Place — id, name, latitude, longitude, plus the 18 posts of that page, each with likes, comments and dates.
What Instagram does not give a logged-out visitor
Written plainly, because you will hit these and should know beforehand:
- Comments. No comment text is served without a login.
- Followers and following lists. Only the counts.
- Business category, contact e-mail and phone. Not in the logged-out page.
- Stories and highlights content. Only the highlight count.
- Hashtag coverage is partial. Instagram serves its logged-out hashtag
page for some tags and the login wall for others: of 5 tags tried on
2026-09-17, 2 (
travel,nature) returned 12 posts each and 3 (nasa,food,photography) returned the login wall. Closed tags are named in the run report; they do not fail the run. Tag pages also cannot be paged: the pagination query answers with null to a logged-out caller. - Hashtag volume is often missing.
travelreports 3.9B,naturereports nothing at all. An absent number isnull, never a guess. - Place pages stop at 18 posts. Their pagination query answers 401.
- Play counts exist only for reels on the account's reels tab (up to 12 per account, switch on Add play counts for recent reels). Feed posts and post pages carry no view count at all.
- Private and withheld accounts. Instagram answers with an error shell; the run report names the account and the reason instead of guessing.
How much of it costs what
| Row kind | How it is fetched | Wire traffic |
|---|---|---|
| Profile | one page | 136–164 KB (141 KB typical) |
| Post / reel from an account | profile page (about 12–20 newest) + reels tab; the full feed, 50 per call, only when Instagram allows it | included in the profile page; 4.6 KB per post on the feed |
| Hashtag + its 12 posts | one page | 157 KB |
| Place + its 18 posts | one page | 333 KB |
| Post opened for place, music, photo tags | one page per post | 149 KB |
Pages are requested with gzip, which is why a profile page costs 141 KB instead of the 702 KB it weighs unpacked.
Watch mode
onlyNew remembers what earlier runs delivered and returns only what is new
or changed, each row marked NEW or UPDATED in change_type. Signed CDN
URLs change on every view, so they are deliberately left out of the change
fingerprint — otherwise every post would look updated every morning and you
would pay for the whole table again. A run that finds nothing new returns an
empty dataset and says nothing-changed in the report.
Filters
minLikes, minComments, minFollowers, postedAfter, postedBefore,
captionContains, postTypes. Two rules worth knowing:
- Filters run before billing, so rows they remove are not charged.
- A post whose owner hides like counts arrives with
likes: nulland is kept byminLikes— missing data is not a mismatch. The single exception iscaptionContains: a post with no caption cannot contain your phrase, so it is dropped. postedAfteralso stops the crawl when the feed is walked, because it runs newest first. On the profile-page path there is nothing to stop: it is a single page.
maxItems caps the rows written to the dataset and never the crawl: with
filters on, the crawl goes as deep as the source allows so that a filtered run
does not hand you an empty table. With only 12–20 posts per account available,
a strict filter can legitimately leave few rows.
An empty dataset always says why
no-input, nothing-requested, date-range-inverted,
follower-filter-without-profiles, charge-limit-reached, nothing-changed,
filtered-out, targets-not-available, nothing-collected,
source-returned-nothing — one of these lands in empty_reason in the run
report, and in the log as a warning. The first four are decided by your input
alone and stop the run before a single request is made.
Proxy
Instagram blocks Apify's cloud addresses by name: measured 2026-09-17, a direct profile request from the cloud returns 200 and a 499 KB page with not one field in it, while the same page through a residential address returns the real data. The proxy input is therefore preset to residential, and you can change it like in any Apify actor. The run report tells you how many requests were made and how many bytes they cost.
Output
One flat table with a result_type column (profile, post, hashtag,
location). compactOutput trims it to 18 columns for AI agents and
spreadsheets; excludeEmptyFields drops nulls, empty lists and false values.
The run report (REPORT in the key-value store) carries rows per kind, what
each filter removed, which targets Instagram refused, the traffic bought and
empty_reason.
What buyers of the big Instagram actors are asking for
Read on 2026-09-17 off the public issue boards of the seven largest Instagram actors on Apify — 156 open and closed tickets from people who already pay. Below is what they ask for and where this actor stands. Nothing here is a promise about their software; it is what their own buyers wrote.
| What the tickets say | Here |
|---|---|
| "Post count came as empty for some accounts which actually do have posts", "Not retrieving count of posts for some instagram pages" — 2 tickets | posts_count is read out of the og:description line, because the page JSON carries all_media_count: null on every account measured |
| "Number of posts downloaded exceeds 12", "Returns only a few posts", "Detailed mode — not all posts returned", "Not retrieving all posts from date" — 4 tickets | Not closed today. On 2026-09-17 the full feed gave 200 posts over 4 requests; on 2026-10-27 Instagram asks for a login on it, so you get the newest 12–20 posts per account. If the feed opens again the actor uses it automatically |
| "videoPlayCount is null", "No views returned", "I do not see any Number of Views data", "Add videoPlayCount to the latest posts output" and nine more — 15 tickets | plays comes from the reels tab, the one logged-out surface that carries play_count. Switch: Add play counts for recent reels. Honest limit: Instagram lists about 12 reels there per account, and feed posts carry no view count at all |
| "Run marked as Succeeded but returns empty latestPosts", "empty successful datasets", "Common transient no items" — 7 tickets | an empty dataset always carries one of 10 named reasons in empty_reason; four of them stop the run before the first request |
| "restricted_page conflates three different situations — two of them carry no distinguishing field" | every target Instagram refused is listed in the run report by name and reason, and does not fail the run |
"Usernames containing .com resolve to a different account's profile (greedy .com stripping)" | nike.com stays nike.com; only @, slashes and the query string are stripped |
| "Duplicated rows! The account has 68k followers, you extracted 118k" | rows are de-duplicated by shortcode, so one post is never delivered twice in a run |
| "Expose coauthor_producers so Instagram collaboration posts are detectable" | coauthors ships on every post row |
| "paidPartnership is not returned" | is_paid_partnership ships on every post row |
| "Add profile picture (favicon/avatar) to the response" | profile_pic_url ships on every profile row |
| "Date filtered results unexpected", "Not retrieving all posts from date" — 3 tickets | postedAfter and postedBefore filter before billing. Posts older than the newest 12–20 are not reachable without a login today |
| "Add maxRequestRetries / per-profile timeout — one blocked profile gates the whole run" | a profile that fails is reported and skipped; the run continues. The per-request retry count is fixed at 3 and is not an input yet |
| "Business address not returned for business accounts that display address on profile", "Not showing mobile number and email" — 3 tickets | not closed, and not promised: the logged-out business profile page carries no address, phone or e-mail (checked on @gopro) |
| "Mentions limited to 21 results", "Prefiltering Comments", "Instagram Search Scraper blocked" | not closed: mentions, comment text and keyword search are all behind the login wall |
Defaults
Running with the preset input returns the @nasa profile row and its newest
posts. maxItems defaults to 50 so a trial run stays cheap; postsPerProfile
defaults to 12 and goes up to 5000, which only has an effect when Instagram
serves its full feed (see the top of this page).