Instagram Posts Scraper: Profiles, Reels, No Login
Pricing
from $0.29 / 1,000 posts
Instagram Posts Scraper: Profiles, Reels, No Login
Instagram posts scraper for public profiles, no login: each profile's newest posts and reels back to its first post, or single posts by URL. Rows carry caption, hashtags, likes, comments, reel plays, carousels, location, tagged users and collab flags. Excel, CSV or API, scheduled; pay per post.
Pricing
from $0.29 / 1,000 posts
Rating
0.0
(0)
Developer
Automation Craft
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
Instagram Posts Scraper: Profiles, Reels, No Login
Instagram posts scraper for public profiles, with no login, no cookies and no Instagram account: give usernames or profile URLs and get each profile's newest posts and reels in the order of its grid, as many as you ask for, back to the profile's first post, with reel play counts. Give post or reel URLs and get each post with its first comments. Pay per post, from $0.29 per 1,000.
Built for brand and competitor tracking, influencer and creator research, content and hashtag analysis, social media reporting and AI data sets. Name a memory and schedule the run: each run then delivers and bills only the posts it has not delivered before. Rows carry what Instagram shows a visitor who is not logged in; use them under the rules that apply to you.
At a glance
- Deep walks. Measured on 2026-10-11: one profile walked to its first post (442 posts, back to 2010-10-28) in 54 seconds, and 1,000 posts of a bakery's profile in one run in 140 seconds.
- Both date ends. Keep posts from a start date, up to an end date, or both, to the minute (UTC), or "7 days", "6 hours". An old window is reached in one or two calls: the walk jumps to the end date instead of paging through every newer post.
- Reel play counts joined from the profile's reels tab at no extra charge, with a status that says why a reel has none.
- Collab and pinned posts flagged.
isCollabandownerUsernamename a post another account owns that the profile accepted onto its grid;isPinnedmarks pinned posts. A switch leaves out either kind. - Each post billed once per run, and once per memory name across runs. A username or post that does not exist is a free status row; filtered, repeated and already known posts are free.
- A coverage row per profile says how many posts were read, delivered, charged and filtered, and why the walk stopped.
Quick start
- Open the Actor and paste usernames (
natgeo,@nasa) or profile URLs (https://www.instagram.com/nike/) into Instagram usernames or profile URLs, up to 500 a run. For single posts, paste post or reel URLs (/p/,/reel/,/reels/,/tv/) or the post code alone into Post or reel URLs, up to 500 a run. - Set Newest posts per profile: 12 by default, up to 10,000, or 0 for profile rows only. Add a date range, post types or minimum likes, comments or plays if you like.
- Run, then download the rows from the Output tab (views Posts and Profiles) as JSON, CSV or Excel, or read them through the API.
- For a monitor: give a Memory name and schedule the run (see "Monitor profiles for new posts" below).
An empty input ({}) runs a sample: @natgeo's 12 newest posts. It is a paid run like any other (USD 0.01538 on the Free plan).
What you get
One post row per Instagram post or reel (type: "post"). Fill rates measured on 1,792 distinct grid posts from platform runs of 2026-10-11 over five public profiles (natgeo, nasa, nike, zuck, tartinebakery): 705 photos, 588 reels, 450 carousels and 49 other videos.
| Field | What it is | Filled |
|---|---|---|
code, id, url | the post code (the part after /p/ or /reel/), the media id (as text) and the post link | 100% |
mediaType, productType | photo, video, reel or carousel; Instagram's own product type (feed, clips, carousel_container, igtv) | 100% |
takenAt, takenAtUnix | the time of posting, UTC, as ISO text and as Unix seconds | 100% |
caption, captionEdited | the caption as written (empty text when there is none) and whether it was edited | caption 99.7% |
hashtags, mentions | the words after # and @ in the caption, in order, without repeats | 48.7%, 51.8% |
likeCount, likeCountHidden | likes; null (never 0) when the owner hides them, and likeCountHidden is then true | 99.9% (2 hidden) |
commentCount, commentsDisabled | the comment count; commentsDisabled is true when comments are off, else null | 100% |
playCount, playCountStatus | reel plays, joined by code from the profile's reels tab; the status is ok, or says why not: not_in_newest_reels, lookup_failed, hidden_by_owner, not_available (a video that is not a reel), not_requested | 99.3% of reels (584 of 588); 481 of 485 on the final build |
viewCount | a video's view count, where the grid gives one | when given |
videoUrl, videoDuration, hasAudio | the video file link (largest size), its length in seconds and whether it has sound | videoUrl 100% of reels; videoDuration 482 of 485 reels (the final build's matrix runs of 2026-10-11) |
displayUrl, width, height | the image (the cover of a video) in its largest size, and the size | 100% |
carouselCount, carousel | a carousel's items: id, type, displayUrl, videoUrl, width, height, taggedUsers, accessibilityCaption | 450 of 450 carousels |
location | id, name, lat, lng and the location page url | 54.7% |
taggedUsers | the usernames tagged in the media | 56.6% |
coauthors | the coauthors of a collab post | 18.1% |
audio | type (music or original), title, artist, audioId | 71.3% of reels |
accessibilityCaption | Instagram's image description | 2.0% |
isPaidPartnership, sponsors | the paid partnership label and the sponsor usernames | 3 of 1,792 marked paid |
isPinned | pinned to the top of the profile's grid | 7 of 1,792 |
isCollab, ownerUsername, ownerId, ownerFullName, ownerIsVerified | a post another account owns on this profile's grid, and its owner | ownerUsername 100%; 87 of 1,792 collab |
profileUsername, source, subjectKey, scrapedAt | the profile whose grid the post came from, profile or url, the input it answers, the time of reading | always |
A post read by URL (source: "url") adds firstComments (up to 15, each with id, text, createdAt, username, userId, isVerified, likeCount, replyCount; 3 of 3 posts in the platform run) and moreCommentsAvailable. Its isPinned, isCollab and profileUsername are null: they describe a profile's grid.
The profile row
One profile row per username found: username, userId, fullName, biography, bioLinks (each url and title), externalUrl, followerCount, followingCount, isVerified, isPrivate, isMemorialized, hasReels, pronouns, highlightTitles, threadsUsername (the linked Threads handle), profilePicUrl, profileUrl. On a run of 19 large public profiles on 2026-10-11: followers, following and bio links 19 of 19, bio 17 of 19, highlight titles 12 of 19, Threads handle 11 of 19.
Coverage, status and summary rows (free)
- A
coveragerow per profile:stopReason(end_of_grid,max_posts_per_profile,posted_after_reached,max_posts,charge_limit,work_allowance,private,not_foundand more),complete,reachedEndOfGrid,jumpedToEndDate,pagesRead,postsRead,postsDelivered,postsCharged,repeated,known,filtered,filteredBy(per reason),postsSkippedNewer,pinnedSkipped,reelsCalls,playCountsJoined,playCountsNotFound. A post URL gets one too (delivered,charged,known,repeated,commentsDelivered). - A
statusrow for each value that could not be used:username_not_found,profile_private,post_not_found,lookup_failed,invalid,skipped(inputs a stopped run did not start),memory_free,proxy_mapped. - One
summaryrow last, with every counter, the reason the run stopped and what the platform confirmed as charged per event.
Example post row
A reel of nasa's grid from a run of 2026-10-11 on this Actor's current code (test actor run of the matrix, build 0.1.4), trimmed: media links shortened.
{"type": "post","code": "DeTUk4sDSp-","id": "4004634989362489982","url": "https://www.instagram.com/reel/DeTUk4sDSp-/","mediaType": "reel","productType": "clips","takenAt": "2026-10-10T15:15:02.000Z","caption": "POV: you're watching the Earth set\n\nWe just released hundreds of new images and hours of new audio from our Artemis II mission around the Moon this spring. Check out our link in bio for the Artemis II Preliminary Lunar Science Report.\n\n#NASA #ArtemisII #Artemis","hashtags": ["NASA","ArtemisII","Artemis"],"mentions": [],"likeCount": 524004,"likeCountHidden": false,"commentCount": 4921,"playCount": 7411139,"playCountStatus": "ok","videoDuration": 43.767,"displayUrl": "https://scontent-lga3-3.cdninstagram.com/v/t51.82787-15/84219...","videoUrl": "https://scontent-lga3-2.cdninstagram.com/o1/v/t2/f2/m86/AQNUv...","hasAudio": true,"width": 1074,"height": 1908,"location": null,"taggedUsers": ["nasaartemis"],"coauthors": [],"audio": {"type": "original","title": "Original audio","artist": "nasa","audioId": "28589819277311219"},"isPaidPartnership": false,"isPinned": false,"isCollab": false,"ownerUsername": "nasa","ownerFullName": "NASA","ownerIsVerified": true,"profileUsername": "nasa","source": "profile","scrapedAt": "2026-10-11T15:51:19.011Z"}
How deep it goes
The grid is read up to 33 posts a call, pinned posts first, then newest to oldest, until the profile's first post, your number, your start date or your run cap. Measured on 2026-10-11: zuck's grid to its end, 442 posts back to 2010-10-28 (Instagram counted 444 on 2026-10-08; two or three are not served to a visitor who is not logged in); 1,000 posts of tartinebakery back to 2021-05-20 in 140 seconds; 300 posts of nike in 67 seconds. Pinned posts are often old (natgeo's pinned reels were from July and September), so isPinned and Skip pinned posts matter for dated work. Collab posts are common on brand grids: 15 of nasa's newest 24 grid posts were owned by other accounts (2026-10-11).
How much does it cost to scrape Instagram posts?
Pay per event. Prices per 1,000 events (USD):
| Event | Charged for | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|---|
Post (post) | one post or reel row | 0.49 | 0.45 | 0.39 | 0.29 |
Profile (profile) | once per profile per run, with the profile's first charged post; or per profile row when Newest posts per profile is 0 | 2.00 | 1.90 | 1.70 | 1.50 |
Post details (post-details) | a post read by URL (full details and first comments), on top of its Post event | 0.60 | 0.55 | 0.50 | 0.45 |
Actor start (apify-actor-start) | once per run, per GB of memory (runs use 256 MB, so one) | 0.0075 per run | 0.0075 per run | 0.0075 per run | 0.0075 per run |
Platinum and Diamond plans pay the Gold price. There is no discount on the Actor start event. Reel play counts are included in the Post price.
The Store pricing card shows prices per 1,000 events: "$0.29 / 1,000" on the Post row means one post costs USD 0.00029 at Gold. In the same way "$1.50 / 1,000" on the Profile row means one profile costs USD 0.0015, and "$0.45 / 1,000" on the Post details row means USD 0.00045 per post read by URL, both at Gold.
Worked examples:
- A monitor run of one profile that finds 12 new posts: on the Free plan 0.0075 + 12 x 0.00049 + 0.002 = USD 0.01538; at Gold 0.0075 + 0.00348 + 0.0015 = USD 0.01248.
- A monitor run that finds nothing new: USD 0.0075 (the Actor start only).
- 1,000 posts of one profile: USD 0.4995 on the Free plan, 0.0075 + 0.29 + 0.0015 = USD 0.299 at Gold.
- 10 posts by URL on the Free plan: 0.0075 + 10 x (0.00049 + 0.0006) = USD 0.0184.
- 100 profile rows only (Newest posts per profile 0) on the Free plan: 0.0075 + 100 x 0.002 = USD 0.2075.
Free: a username or post that does not exist, a private profile in a posts run (its profile row and status row are free; none of its posts can be read), posts left out by a filter, posts repeated in the run, posts the named memory knows, the profile row of a posts run, and every coverage, status and summary row. Your run's charge limit is respected: the run stops when the next event would pass it, and the inputs it did not start get a free skipped row.
The work allowance
Work that may end without a charge (usernames that do not exist, private profiles, posts all filtered out or all known to the memory, newer posts skipped before an end date) is bounded per run: 45 seconds of unpaid work, plus 2 seconds for each charged post, 6 for each charged profile and 4 for each charged post details event. When it is spent the run stops, says so (stoppedBy: "work_allowance") and lists the inputs it did not start in a free status row. Calls that deliver charged rows never use it up.
Input
| Field | Default | What it does |
|---|---|---|
usernames | none (the Console fills in natgeo) | Usernames (natgeo, @natgeo) or profile URLs, up to 500 a run. Capitals do not matter. |
postUrls | none | Post or reel URLs (/p/, /reel/, /reels/, /tv/) or post codes, up to 500 a run. Filters and dates never apply to these: you named the post. |
maxPostsPerProfile | 12 | How many of each profile's newest posts are read, in grid order (pinned posts first, then newest to oldest), up to 10,000. Every post read counts, whether delivered, filtered or already known to the memory. Posts newer than the end date do not count. 0 = profile rows only. |
maxPosts | no cap | A cap of post rows for the whole run (profile rows are not counted). |
postedAfter | none | Keep posts from this moment on (UTC): YYYY-MM-DD, YYYY-MM-DDTHH:MM, today, yesterday, 7 days, 2 weeks, 3 months, 6 hours, counted back from the run. A walk stops at the first older post (pinned posts aside), so a start date makes a run shorter. |
postedBefore | none | Keep posts up to this moment, in the same forms (YYYY-MM-DD means the end of that day). Newer posts are skipped free and do not count toward maxPostsPerProfile. After the profile's first page (which holds its pinned posts) the walk jumps straight to the end date, so an old window is reached in one or two calls (jumpedToEndDate in the coverage row). |
mediaTypes | all | Keep only photo, video (not reels), reel or carousel. Posts of other kinds still count toward maxPostsPerProfile and are not charged. |
minLikes, minComments | 0 | Keep posts with at least this many likes or comments (a post with hidden likes does not pass minLikes). |
minViews | 0 | Keep reels and videos with at least this many plays (playCount, or viewCount where the grid gives one). Rows without a play count do not pass. |
includeCollabPosts | true | Off: collab posts (owned by another account) are left out and not charged. |
skipPinnedPosts | false | On: pinned posts are left out and do not count toward maxPostsPerProfile. |
includeReelPlayCounts | true | Join each reel's play count from the profile's reels tab (about one extra call per 12 reels, no extra charge). |
memoryName, resetMemory | none, false | A named memory: later runs with the same name deliver and charge only posts not delivered before. resetMemory forgets every post it holds first. |
proxyConfiguration | Apify datacenter proxy | A residential or other Apify proxy group is replaced by the datacenter pool and a free proxy_mapped row says so; your own proxy URLs are used as given. |
Through the API, directUrls (also urls or startUrls) takes a mixed list of profile and post URLs, and these key names are read too: resultsLimit for maxPostsPerProfile, maxItems for maxPosts, onlyPostsNewerThan for postedAfter, onlyPostsOlderThan for postedBefore. Two keys of one meaning sent together refuse the input with a free invalid row.
Monitor profiles for new posts
Give a Memory name and schedule the run (daily, hourly). Each run reads the newest posts of every profile again, skips the ones the memory already holds for free, and delivers and charges only the posts it has not delivered before under that name. A scheduled run of the 12 newest posts therefore bills only what is new, and a run that finds nothing new costs the Actor start alone. The profile row comes with every run, so followerCount is fresh each time (free in a posts run).
- Known posts count toward Newest posts per profile: set it above the number of posts a profile can publish between two runs.
- The memory is a named storage this Actor creates in your account; it belongs to this Actor. Reset the memory forgets it.
- Two runs on one memory name at the same time: the second runs free and remembers nothing. A memory that cannot be opened, read or saved makes the run free too, and a
memory_freerow says so.
What this Actor does NOT do
- It does not log in, use cookies or use Instagram accounts. It reads only what Instagram shows a visitor who is not logged in.
- It does not read comments beyond the first 15 of a post read by URL, and gives no comments on grid posts (the grid answer carries none): read the post by its URL for them.
- It does not read follower or following lists.
- It does not read stories or the contents of highlights (the profile row lists the highlight titles).
- It does not search by hashtag, keyword or place, and does not read the tagged tab of a profile.
- It does not give shares or saves counts.
- It does not transcribe videos or download video files: the row carries the video URL.
- It does not give the exact post count of a profile.
- It does not read the posts of a private profile: the profile row only.
- It cannot read posts Instagram does not show to logged out visitors (age or region restricted): those get a free
post_not_foundrow that says so. - It gives play counts for reels only (from the reels tab), not for other videos.
- It does not tell trial reels (reels shown first to people who do not follow the account) from other reels: the answers it reads carry no such mark.
API examples
curl -X POST "https://api.apify.com/v2/acts/automation_craft~instagram-posts-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \-H "Content-Type: application/json" \-d '{"usernames": ["natgeo", "nasa"], "maxPostsPerProfile": 50, "postedAfter": "30 days"}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });const run = await client.actor('automation_craft/instagram-posts-scraper').call({usernames: ['nike'],maxPostsPerProfile: 100,mediaTypes: ['reel'],minViews: 100000,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const p of items.filter((x) => x.type === 'post')) console.log(p.url, p.playCount, p.likeCount);
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("automation_craft/instagram-posts-scraper").call(run_input={"usernames": ["tartinebakery"],"maxPostsPerProfile": 12,"memoryName": "bakery watch",})for item in client.dataset(run["defaultDatasetId"]).iterate_items():if item["type"] == "post":print(item["takenAt"], item["url"], item["likeCount"], item["commentCount"])
FAQ
Can I scrape more than 12 posts from a public Instagram account?
Yes. Set Newest posts per profile (maxPostsPerProfile) up to 10,000: the grid is read up to 33 posts a call, newest first, until the profile's first post. On 2026-10-11 a run read 442 posts of one profile back to 2010, and another read 1,000 posts of one profile in 140 seconds.
How do I track a competitor's Instagram posts?
Put the competitor's username in usernames, give a memoryName and schedule the run. Each run delivers and charges only the posts not delivered before under that name, and a run with nothing new costs USD 0.0075.
Can I run an Instagram profile scraper on a schedule without it breaking?
Schedule the Actor with a memory name: every run returns the profile row (followers, following, bio, links, verified) and only the new posts. It needs no login, cookies or Instagram account, and each profile's coverage row says why its walk stopped. It gives no exact post count of a profile.
Can I filter Instagram reels by minimum views?
Yes: set minViews (with mediaTypes: ["reel"] for reels only). Play counts come from the profile's reels tab at no extra charge, a row without a play count does not pass, and posts a filter leaves out are free.
Can I scrape Instagram stories or follower names without a login?
No. This Actor reads only what Instagram shows a visitor who is not logged in, and that includes neither stories nor follower or following lists. It gives each profile's follower and following counts.
Why does this Actor run with limited permissions?
Least privilege: it only needs its own storages and the named memory store it creates itself, so it asks for nothing else in your account.
More data tools by Automation Craft
- Threads Scraper: Posts, Search, Tags, Replies
- Threads Profile Scraper: Followers, Bio, Posts
- Instagram Ads Library Scraper - Creatives, Video
- Meta Ads Library Scraper - Ad Library, All Filters
- TikTok Profile Scraper: Exact Stats, No Login
- TikTok Video Scraper: Post Stats, Transcripts
- Telegram Channel Scraper: Posts, Views, Dates
Changelog
- 0.1 (2026-10-11): first release. Profile rows and the newest posts and reels of public profiles, back to the first post on request, with reel play counts; posts by URL with their first comments; date range, post type, likes, comments and plays filters; collab and pinned flags and switches; a cross run memory; free rows for misses. No login.