Instagram Scraper - Profiles, Posts, Hashtags & Comments avatar

Instagram Scraper - Profiles, Posts, Hashtags & Comments

Pricing

from $1.99 / 1,000 results

Go to Apify Store
Instagram Scraper - Profiles, Posts, Hashtags & Comments

Instagram Scraper - Profiles, Posts, Hashtags & Comments

Pricing

from $1.99 / 1,000 results

Rating

0.0

(0)

Developer

Lantern Lab

Lantern Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Categories

Security

Limited permissions

Share

Give it Instagram usernames, post or Reel URLs, or hashtags and get the public data back: profile details, and for every post its caption, hashtags, publish time, likes, comment count, views, image and video URLs and author - plus the post's comments, page after page, not just the first 15. No Instagram login, no cookies, no account of your own. $1.99 per 1,000 results plus $0.005 per run. See Pricing.

What makes it different

  • Comments past the first page. Instagram shows about 14 comments per page; this Actor keeps paging until it has the number you asked for. When Instagram stops early, the post says so (commentsComplete: false and commentsPartialReason) instead of passing a short list off as all there is.
  • Your limits are hard limits. maxPostsPerProfile, maxPostsPerHashtag and the comment limits are never exceeded, and you are never charged for more than you asked for.
  • The date filter works. newerThan keeps only posts published since that date. On a profile it stops at the first older post below the pinned ones, so an old pinned post never cuts the list short.
  • Pinned posts once. Pinned posts carry isPinned: true, are written at most once per run, and can be left out with skipPinnedPosts.
  • Hashtag results really carry the hashtag. A post is returned for #moon only if its own caption contains #moon. Posts that merely mention the word are read, dropped and not charged.
  • No duplicates. Profiles, posts and comments are deduplicated across the whole run by Instagram's own IDs; a repeat is written and charged once. A post URL whose post an earlier profile or hashtag input already wrote still gets the comments it asks for.
  • Empty, blocked and failed is free - and labelled. Every input gets a free input_status row. An input Instagram refused, or one cut short by a limit, is marked partial: true with a reason - never reported as "zero posts".

Input

{
"usernames": ["nasa"],
"postUrls": ["https://www.instagram.com/p/DX7RFLbk8B6/"],
"hashtags": ["artemis"],
"maxPostsPerProfile": 24,
"maxPostsPerHashtag": 20,
"maxCommentsPerPost": 100,
"newerThan": "30 days",
"skipPinnedPosts": true
}
FieldWhat it does
usernamesnasa, @nasa or a profile URL. Returns a profile row plus its newest posts.
postUrls/p/<code>/ or /reel/<code>/ URLs. Returns the post plus its comments.
hashtagstag or #tag. Returns public posts whose caption carries the hashtag.
maxPostsPerProfilePosts per profile, newest first. Default 12, up to 500.
maxPostsPerHashtagPosts per hashtag. Default 20, up to 100.
maxCommentsPerPostComments per post URL. Default 50, up to 5,000; 0 turns them off.
maxCommentsPerListedPostComments per profile or hashtag post. Default 0 (off).
newerThan2026-10-01, an ISO time, or 7 days / 2 weeks / 3 months. Applies to profile and hashtag posts.
skipPinnedPostsLeave pinned posts out of profile results. Default off.
maxUpstreamRequestsOptional hard ceiling on requests. By default the Actor works one out from your inputs, so a run is never unbounded.
proxyConfigurationDefault: Apify Proxy (datacenter). A refused request is retried once on a residential IP.

Output

Every row has a recordType. Dataset views: Posts, Comments, Profiles, Input status.

post

{
"recordType": "post",
"postId": "3889777825826455674",
"shortcode": "DX7RFLbk8B6",
"url": "https://www.instagram.com/p/DX7RFLbk8B6/",
"type": "Sidecar",
"productType": "carousel_container",
"caption": "Start your week with some new photos from Artemis II! ...",
"hashtags": ["nasa", "artemis", "photodump"],
"mentions": [],
"publishedAt": "2026-05-04T18:01:15.000Z",
"publishedAtEpoch": 1777917675,
"likeCount": 397148,
"commentCount": 1326,
"viewCount": null,
"displayUrl": "https://scontent-....cdninstagram.com/...",
"videoUrl": null,
"mediaUrls": ["https://scontent-...", "https://scontent-...", "https://scontent-...", "https://scontent-..."],
"ownerId": "528817151",
"ownerUsername": "nasa",
"ownerFullName": "NASA",
"ownerIsVerified": true,
"coauthors": ["nasaartemis"],
"locationName": null,
"isPinned": null,
"commentsRequested": 100,
"commentsCollected": 100,
"commentsComplete": true,
"commentsPartialReason": null,
"inputKind": "post",
"inputValue": "https://www.instagram.com/p/DX7RFLbk8B6/",
"rank": 1,
"partial": false,
"partialReason": null,
"collectedAt": "2026-10-30T12:54:08.945Z"
}

type is Image, Video or Sidecar (a carousel); productType: "clips" is a Reel. publishedAt is Instagram's publish time; collectedAt is when this run read it. isPinned is true/false on profile posts and null where Instagram does not say. viewCount is filled where Instagram shows it to logged-out visitors (profile Reels and videos) and is null elsewhere - it is never estimated.

comment - commentId, postId (the parent post), postShortcode, postUrl, parentCommentId (the comment it replies to; null on a top-level comment), text, publishedAt, likeCount, ownerUsername (the commenter's public username only), ownerIsVerified, rank, collectedAt.

profile - userId, username, fullName, biography, externalUrl, followersCount, followsCount, postsCount, isVerified, isPrivate, isBusinessAccount, category, profilePicUrl, profileUrl, collectedAt. No e-mail addresses or phone numbers are collected.

input_status (free) - one per input: postsReturned, commentsReturned, rowsCharged, duplicatesSkipped, pinnedSkipped, olderSkipped, unrelatedSkipped, partial, partialReason and a plain-English statusText.

RUN_SUMMARY (free) - the last row, and the same object in the key-value store: totals, partial inputs by reason, requests sent, and why the run stopped if it stopped early.

Partial reasons

partialReasonMeaning
comments_not_publicInstagram stopped paging comments before its own count. The count includes replies and comments it does not show to logged-out visitors.
search_results_exhaustedA hashtag's public search results ran out before maxPostsPerHashtag.
candidate_limitA hashtag read 3 search results per post asked for without filling the limit (most did not carry the hashtag or were filtered out).
private_accountThe profile is private; its profile row is returned, its posts are not public.
not_foundNo public profile or post by that name (deleted, renamed, restricted or never existed).
gatedInstagram withholds the post from logged-out visitors (age or region restriction).
blockedInstagram refused the requests, also on a fresh residential IP. Not an empty result.
upstream_error / unexpected_shapeA request failed, or the answer was not in a shape the Actor knows. Not an empty result.
upstream_request_capThe run reached maxUpstreamRequests.
charge_limit_reachedThe maximum charge you set for the run was reached.
not_collectedThe run stopped before reaching this input.

Limits, stated up front

  • Public content only, no login. Private accounts, Stories, highlights, and anything that needs an Instagram account are out of scope.
  • Hashtags come from public web search. Instagram's own hashtag feed requires a login. This Actor finds hashtag posts through public search results, then checks each post's caption. You get real, matching posts - but not Instagram's complete or newest-first hashtag feed, and popular accounts are over-represented. When the search results run out the hashtag is marked search_results_exhausted.
  • Replies are not shown to logged-out visitors. Comments are top-level comments; parentCommentId is filled only when Instagram provides it. Instagram's commentCount includes replies, which is why a post can have fewer collectable comments than its count.
  • Views. Instagram shows a view count logged-out only for some videos; elsewhere viewCount is null.
  • Transcripts of Reels are not part of this Actor.

Pricing

Pay per result: $1.99 per 1,000 results, plus $0.005 per run (start fee). A result is one profile, post or comment row. input_status rows, the run summary, duplicates, filtered posts and anything an input could not return are free, so a blocked or empty input costs nothing beyond the start fee. Example: one profile with 50 posts and 20 comments each = 1 + 50 + 1,000 = 1,051 results ≈ $2.10.

How it works

Plain HTTP requests to the same public endpoints Instagram's own logged-out web page uses, through Apify Proxy (datacenter by default, residential only as a fallback). Profiles come from Instagram's public profile endpoint (newest 12 posts in one request, then the profile grid's own pages); posts and comments from the logged-out post page and its comment pages. No browser, no login, no cookies of your own.