Instagram Comments Scraper - Export Post & Reel Comments avatar

Instagram Comments Scraper - Export Post & Reel Comments

Pricing

from $0.38 / 1,000 results

Go to Apify Store
Instagram Comments Scraper - Export Post & Reel Comments

Instagram Comments Scraper - Export Post & Reel Comments

Instagram comments scraper: export the comments and replies on a public post or reel. Every row has the author's username and name, the text, the time, likes, reply count and the verified flag; GIF comments come with a title and link. One run reads the top 75 to 150 rows. $0.40 per 1,000 rows.

Pricing

from $0.38 / 1,000 results

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

45

Total users

9

Monthly active users

16 hours

Issues response

2 days ago

Last modified

Categories

Security

Limited permissions

Share

Instagram comments scraper for a post or reel link, comments and replies as flat rows: who wrote each comment, by username and by name, what it says, when, how many likes it picked up, how many replies hang off it, and whether the author is verified. Every row links to its post and to the comment itself. A comment that is only a GIF comes back with the GIF's title and a link to it.

Here is the part worth knowing before you start. A run reads each thread from the top down, in Instagram's order, and stops at the number of rows you ask for, up to 2,000. By default, replies come back only where Instagram sends them alongside a comment; switch on every reply for the rest. On the free Apify plan a run reads one page of the first post, roughly 15 to 30 rows.

InputPost or reel URLs, with or without the account name in front, bare shortcodes or numeric post ids
OutputOne row per comment or reply: text, author username and name, verified and private flags, likes, reply count, time, post and comment links, GIF title and link
Ceiling2,000 rows per run
Account neededNone
Price$0.40 per 1,000 rows on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 12,500

🔍 What Instagram Comments Scraper does

You give it links, it gives you the conversation under them. Comments and replies land in the same row shape, so you can drop the lot into a sheet without branching on type. A reply carries isReply: true and a parentCommentId, which is enough to rebuild the tree or to filter replies out with one condition.

You don't need an Instagram account.

If you would rather the run read through your own Instagram account, you can put your own session in sessionCookies. It is used only for your run, and you are responsible for using it within the site's terms. Most people leave it empty and never think about it again.

📋 What data you get from each Instagram comment

What you getField
The comment's id, and the post it sits underid, mediaId
What it saystext
A GIF-only comment's title and linkhasGif, gifTitle, gifUrl
Likes and how many replies it haslikeCount, replyCount
When it was writtencreatedAt
Who wrote itownerUsername, ownerFullName, ownerId, ownerVerified
Whether it is a reply, and to which commentisReply, parentCommentId
Links to the post, the comment and, on a reply, its parentpostUrl, commentUrl, parentCommentUrl
Where it sits in Instagram's order for that postthreadPosition
Whether the author's account is privateownerIsPrivate
The author's profile picture link, only when you ask for itownerProfilePicUrl

▶️ How to scrape Instagram comments

  1. Open Instagram Comments Scraper and click Try for free.
  2. Paste your links into Post URLs, one per line.
  3. Set Max comments. Start at 15 while you look at the output shape. For the same number from every post, also fill in Max comments per post.
  4. Click Start.
  5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.

Start it with no post at all and you get five labelled sample rows, which are not charged.

💰 How much does it cost to scrape Instagram comments?

$0.40 per 1,000 comment rows on the Free plan. Paid plans pay a little less: $0.395 on Starter, $0.39 on Scale and $0.385 on Business. On the free plan, the $5 Apify gives you each month covers about 12,500 rows. On the free plan a run stops after one page and says so in a free row; a paid plan gets the full run.

You pay per row delivered. The same comment is never delivered twice in a run, so you never pay for it twice. Sample rows and diagnostic rows are not billed, and neither is a post that turns out to have nothing under it. Extra replies are rows like any other, at the same price.

📥 What you give it

{
"postUrls": ["https://www.instagram.com/p/Db9IVmrDvQ4/"],
"maxComments": 100
}
FieldDefaultWhat it is
postUrlsnonePost, reel or IGTV links. /p/, /reel/, /reels/ and /tv/ all work, with or without the account name in front. As many as you like, one per line.
shortcodesnoneOr the bare code after /p/ or /reel/, or the post's numeric id. You can mix the two fields.
maxComments100Rows for the whole run, split evenly across the links you gave. 1 to 2,000. Replies count towards it.
maxCommentsPerPostnoneRows from every post instead of an even split, replies included. maxComments still caps the run, so raise it too: 10 posts at 100 each need 1,000.
includeRepliestrueTurn it off for top-level comments only.
includeAllRepliesfalseEvery reply, not only the ones Instagram shows beside a comment. The run writes a page of comments, then the replies under each one that has at least three more, in order. Each reply is a row at the comment price and counts towards maxComments. Needs includeReplies on; not used with your own cookies.
maxRepliesPerCommentnoneWith every reply on: at most this many replies under each comment, the ones Instagram shows included.
includeProfilePicUrlfalseAdds ownerProfilePicUrl, a link to the commenter's profile picture. The run never downloads or keeps the picture.
sessionCookiesnoneOptional: your own session, if you would rather the run read through your account. It is used only for your run, and you are responsible for using it within the site's terms.
proxyConfigurationnoneLeave it alone unless you have servers of your own you want used.
notionConnector, notionParentIdnoneOptional. Write each comment into a Notion data source as well as the dataset.
notionMaxRowsnoneSend only the first this many rows to Notion. The dataset still gets them all.

A link that is not a post, or a shortcode that cannot exist, gets a labelled row and no lookup.

📤 What you get back

A real row read on 25 October 2026, a brand account commenting on a football post. Its closing emoji is cut from this block:

{
"ok": true,
"type": "comment",
"id": "18107041583611449",
"mediaId": "3993517018170036322",
"text": "THE GOAT",
"hasGif": false,
"gifTitle": null,
"gifUrl": null,
"likeCount": 28569,
"replyCount": 132,
"createdAt": "2026-09-24T21:18:00.000Z",
"ownerUsername": "luxury",
"ownerFullName": "Luxury",
"ownerId": "1122059043",
"ownerVerified": true,
"isReply": false,
"parentCommentId": null,
"postUrl": "https://www.instagram.com/p/Ddr0pHIgJBi/",
"commentUrl": "https://www.instagram.com/p/Ddr0pHIgJBi/c/18107041583611449/",
"parentCommentUrl": null,
"threadPosition": 2,
"ownerIsPrivate": false,
"ownerProfilePicUrl": null
}

A GIF-only comment from an earlier run, link shortened:

{
"text": "",
"hasGif": true,
"gifTitle": "The Boys Messi GIF",
"gifUrl": "https://cdn.fbsbx.com/v/t59.2708-21/822297128_..._n.gif?..."
}
FieldHow to read it
idUnique per comment. Use it as your dedupe key across runs.
mediaId, postUrlThe post the comment sits under, as Instagram's id and as a link.
commentUrl, parentCommentUrlBuilt from the post and the ids on the row. They open the comment for someone signed in to Instagram; signed out, Instagram may show its home page. parentCommentUrl is null on a top-level comment.
isReply, parentCommentIdfalse and null on a top-level comment. On a reply, true and the id of its parent.
replyCountHow many replies Instagram says the comment has, which is often more than the number that came back.
threadPosition1 for the top comment of that post, in the order this run read it. A reply carries its parent's number. The order moves between runs.
ownerFullNameThe name on the commenter's profile. null when they have not set one.
ownerIsPrivatetrue when the commenter's account is private.
ownerProfilePicUrlnull unless you turned on includeProfilePicUrl. The link expires after a while.
hasGif, gifTitle, gifUrlA comment that is only a GIF has an empty text. Then hasGif is true and the other two describe the GIF. Otherwise false, null, null.
createdAtISO timestamp, or null when Instagram did not supply one. Nothing is guessed.

🧾 Reading the output

Three kinds of row can land in your dataset, and only the first kind is billed.

RowHow to spot itBilled
A comment or replyok: true and type: "comment"yes
A sample rowsampleData: true, charged: falseno
A diagnosticok: false and an errorCodeno

Filter on ok == true and you have your thread. Sample rows appear only when you start a run without naming a post, so a run that names a real post never answers with invented data.

CodeWhat it means
BAD_INPUTThat link is not a post or reel link, or that shortcode cannot exist. Nothing was looked up.
NOT_FOUNDThe post is deleted, private, or the link is wrong.
COMMENTS_DISABLEDThe owner switched comments off on that post.
NO_RESULTSInstagram returned no comments for that post: it has none yet, comments are switched off, or it is no longer public.
FREE_PLAN_LIMITYou are on the free Apify plan, so the run read only part of your input. postsNotRead lists what it skipped. A paid plan gets the full run.
PARTIALThe run stopped before it had all you asked for: it read as many pages as one run may, or reached its maximum cost. With every reply on, it can also say how many comments came back without all of their replies (commentsWithoutAllReplies). What arrived is complete and correct.
TIME_LIMITThe run reached its time limit and stopped on its own. The comments delivered before that are complete and charged. If none had come back yet, the run still ends as succeeded, with an amber status message. Give it more time, or ask for fewer comments.
RATE_LIMITEDToo much traffic on that post just now. Try again shortly.
LOGIN_REQUIREDThe thread could not be opened this time. If you supplied a cookie, check it is still valid.
NOT_SERVEDThis request was not served this run. Re-run it later. A post from a private account always gets it. Runs before 13 October 2026 wrote BLOCKED here.
SERVER_ERRORInstagram answered badly. Re-run it.
UNEXPECTED_ERRORThe run stopped early on an unexpected error. The results before this row are kept.

A run that could not read what it was asked for ends as failed, with a labelled row telling you why, because a green tick over an empty dataset is the worst answer a scraper can give. These cases succeed instead, each with its own row: a post with no comments (NO_RESULTS), comments switched off (COMMENTS_DISABLED), a link that is not a post (BAD_INPUT), a post that no longer exists (NOT_FOUND) and a post that was not served (NOT_SERVED). If at least one link produced comments, the run succeeds and the rest get their own rows. No diagnostic row is billed as a comment.

💡 What people use it for

  • Reading what people actually said under a launch post, rather than counting the likes.
  • Going through the entries on a giveaway or a competition post by hand.
  • Collecting a few hundred comments across a set of posts to see which complaint keeps coming up.
  • Checking whether a creator's engagement looks like a conversation or like the same ten accounts.

🚧 What it does not do

  • No more than 2,000 rows a run. A post with 60,000 comments comes back as its top 2,000, in Instagram's order.
  • Every reply only when you ask. Otherwise replies come only where Instagram shows them, and a comment with just one or two more keeps the ones shown.
  • Order is Instagram's ranking, not newest first, and you cannot change it.
  • No private accounts. Public posts and reels only.
  • No comment likers, no editing, no posting, no deleting. This reads.
  • It is not an official Instagram tool. Dami's Studio is independent and is not affiliated with or endorsed by Instagram or Meta, or by any other company named on this page.

🧭 Which Instagram scraper do you need?

If you wantUse
Comments under a post or reelThis one
The post itself, caption and countsInstagram Post Scraper
Everything one account has postedInstagram Scraper
Posts under a hashtagInstagram Hashtag Scraper
Reels, with plays and audioInstagram Reel Scraper
Posts that tag or mention an accountInstagram Mentions Scraper
Comments under a Facebook post or reelFacebook Comments Scraper
Comments under a TikTok videoTikTok Comments Scraper

❓ Questions people ask

Do I need an Instagram account to scrape comments?

No. Leave sessionCookies empty and it works. The field is there for people who would rather the run read through their own account.

Can I get every comment on a huge post?

Not on a big one. A run reads up to 2,000 rows from the top of the thread, so a post with 60,000 comments comes back as its top 2,000.

Why did I get fewer rows than I asked for?

Either the thread ran out, or the run stopped early: it read as many pages as one run may, or it reached its maximum cost. The NO_RESULTS or PARTIAL row in your dataset says which.

Why is the order different from what I see in the app?

Instagram ranks comments rather than listing them newest first, so the app and a run can put them in a different order. Rows come back in Instagram's order, top first. Like and reply counts are a snapshot at read time.

Can I call it from code or connect it to an AI assistant?

The API tab has code for Python, JavaScript and the CLI. MCP clients like Claude and ChatGPT use https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/instagram-comments-scraper; coding assistants can load our skill file. All three bill your Apify account at the same price.

This reads public posts only, never private accounts or messages. Comments still contain personal data, which GDPR and similar laws cover, so have a reason for collecting them. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Send the post link you used and the run ID. The code on the diagnostic row usually explains it on its own.