Scrape public Instagram profiles, posts and reels from usernames or links, no login: followers, bio and links, and per post the caption, hashtags, likes, comments, date, image and video URLs, collaborators, tagged users, audio and first comments. Reels-only, date filter and only-new mode.
Versions follow MAJOR.MINOR.PATCH (src/version.py); Apify shows MAJOR.MINOR from .actor/actor.json.
Every run logs its version and records it in the RUN_STATS key-value record.
0.1.1 (2026-10-16)
A run that returns nothing (every input bad, private, blocked or unreachable, or an empty input) now ends
SUCCEEDED with an empty dataset and the reason as its status message and in the log, instead of FAILED. Only an
unexpected error still fails the run. RUN_STATS keeps the reason as before.
No change to output fields or price.
0.1.0 (2026-10-14)
First release.
Public Instagram profiles, posts and reels from usernames, profile links, /reels/ tabs and post or reel links, in
one run and one table (type = profile or post, every column on every row).
Profiles: name, bio, follower and following counts, verified and private flags, every bio link, picture, Threads
name. Posts in full: caption, hashtags, mentions, date, likes (null when hidden), comments count, image, video URL
and length, size, carousel items, collaborators, tagged users, location, audio, alt text, topics, the comments
Instagram shows logged-out visitors.
Posts per profile (0-2,000), Only reels, Only posts newer than (date or age), Only new posts since the last run
(memory per profile and reels filter in the user's account, written only for what reached the dataset).
Hashtag, location, search, story and tagged/follower pages are refused with the reason: Instagram shows them only
to signed-in accounts, and this actor never signs in, sends cookies of an account, or uses one.
Charged per result through Apify's apify-default-dataset-item event; failed inputs, withheld posts, filtered
posts and already-returned posts are free. "Max results per run" and the maximum cost per run stop the fetching,
not just the writing.
A visitor Instagram refuses is replaced (a new datacenter IP, then residential after six refusals in a run); a run
stops after 24 refusals. Renamed queries are read again from Instagram's own pages.
Source and terms (ACTOR-CHECKLIST sections 0 and 6), read 2026-10-14
Source: Instagram's logged-out web app: instagram.com's home page (cookies and its page token), then the three
persisted GraphQL queries its logged-out profile and post pages run (PolarisLoggedOutDesktopWWW...). Not a
published API: Meta's documented Instagram APIs (Graph API, Business Discovery) need an app, a business account
and the account owner's consent, which a scraper of public data can't use.
robots.txt:www.instagram.com disallows every crawler (User-agent: * / Disallow: /). Built under Michael's
platform exception of 2026-10-14 (PLAN.md "Exclusions lifted", ACTOR-CHECKLIST 2b: robots_exempt_hosts, browser
User-Agent for www.instagram.com only), logged-out only, one query at a time per visitor at most one a second.
Terms: Instagram's Terms of Use (https://help.instagram.com/581066165581870 ; the page needs JavaScript, so the
clause was confirmed through search results and a 2019 court filing of the same text) bar accessing or collecting
information in unauthorized ways, including "collecting information in an automated way without our express
permission". Meta also has Automated Data Collection Terms (reported effective 2024-10-07; Meta's page not read).
They bind people who accept them by using an account; this actor never signs in. In Meta Platforms v. Bright Data (N.D. Cal., January 2024) the court
held Meta's terms didn't bar logged-off scraping of public data. The README says the robots.txt and terms position
plainly, and that the data includes personal data (public usernames, comments) the user is responsible for.