# Instagram Comments Scraper with Replies — CSV Export, No Login (`afanasenko/instagram-comments-scraper`) Actor

Export Instagram comments from any public post or reel to CSV, JSON or Excel: comment text, author, likes, time, reply threads, @mentions and #hashtags as columns, optional comment likers, no duplicates, no login. Each post gets a summary row with how many comments Instagram served.

- **URL**: https://apify.com/afanasenko/instagram-comments-scraper.md
- **Developed by:** [Andrey Afanasenko](https://apify.com/afanasenko) (community)
- **Categories:** Lead generation, Social media, Automation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.82 / 1,000 comments

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Instagram Comments Scraper with Replies — CSV Export, No Login

[![Apify Actor](https://apify.com/actor-badge?actor=afanasenko/instagram-comments-scraper)](https://apify.com/afanasenko/instagram-comments-scraper)

> **Paste an Instagram post or reel link. Get every comment Instagram serves as a spreadsheet row: who wrote it, what they said, when, and how many likes it has.**
> Replies come as their own rows. @mentions and #hashtags get their own columns. Public posts only, no login, no cookies. Export to CSV, JSON or Excel.

> **🆓 Free to start:** 50 comments per run · 15 runs a month · replies, mentions and both views included · no card, no login.

### 🎯 What it does

**You give** links to public Instagram posts or reels, one per line — up to 50 per run on a paid plan, 3 on the free one. Leave the box empty and it reads a demo post instead.

**You get** one row per comment: text, time, likes, author. Replies are rows too, each pointing at the comment it answers. @mentions and #hashtags get their own columns. Optional: who liked each comment.

**What you won't get: every comment the counter shows.** The number on the post counts replies, hidden and deleted comments. Instagram hands over fewer — a bit under half on a typical post. Every post gets a free summary row: what arrived, and why reading stopped.

Comments by **private accounts are included** — about six in ten on a busy post. Their comment is public.

### 📦 Output sample

Every comment is one row. Here is what a row holds:

- **The comment** — Comment Text, Posted At, Likes, Replies, Is Reply, Parent Comment ID, Mentions, Hashtags.
- **Who wrote it** — Account, Full Name, Author ID, Author Is Verified, Author Is Private, Profile Picture.
- **Which post** — Source, Post URL, Post Owner, Declared Comments.
- **Coverage and notices** — Delivered Top-Level, Delivered Replies, Stop Reason, Analysis Status, Why Not Analyzed, Comment Likers.

A real row from a recent run (likers switched on):

```json
{
  "Account": "https://instagram.com/marie.dubois",
  "Source": "DccbeHGPj3T",
  "Analysis Status": "analyzed",
  "Why Not Analyzed": "N/A",
  "Post URL": "https://www.instagram.com/p/DccbeHGPj3T/",
  "Post Owner": "natgeo",
  "Declared Comments": 173,
  "Delivered Top-Level": null,
  "Delivered Replies": null,
  "Stop Reason": null,
  "Comment ID": "17912345678901234",
  "Parent Comment ID": null,
  "Is Reply": false,
  "Comment Text": "This is stunning 😍 @jules_martin you have to see this",
  "Posted At": "2026-08-29T14:22:07.000Z",
  "Likes": 34,
  "Replies": 2,
  "Full Name": "Marie Dubois",
  "Author ID": "51234567890",
  "Author Is Private": true,
  "Author Is Verified": false,
  "Profile Picture": "https://scontent.cdninstagram.com/v/...",
  "Mentions": ["jules_martin"],
  "Hashtags": [],
  "Comment Likers": []
}
```

The coverage columns are filled on the `post_summary` row, not on comment rows.

**Views** — two ways to look at the same rows, in the **Storage → Dataset** tab:

| View | What each row is | Best for |
|---|---|---|
| **Comments** (default) | One comment, plus one `post_summary` row per post with its totals | Reading the discussion, sentiment work, export |
| **Commenters** | The same rows, trimmed to the person and who they tagged; someone who commented twice appears twice — dedupe by handle | Giveaway entrant lists |

Full per-field schema: [`.actor/dataset_schema.json`](.actor/dataset_schema.json) — what AI agents see through Apify's MCP server too.

### ⚡ Quick start

1. Open the **Input** tab.
2. Paste one or more post links into **Post Links**, one per line. Reel links work too.
3. Click **Start**. Rows appear in **Storage → Dataset** as they arrive; download CSV, JSON or Excel there.

A minimal input that works on the **free plan**:

```json
{
  "postUrls": ["https://www.instagram.com/p/CA2aJYrg6cZ/"],
  "maxCommentsPerPost": 50
}
```

### 🧭 When to use it

- **Giveaway entrant lists** — every entry as a row with the friends they tagged already in `Mentions`.
- **Comment sentiment analysis** — full text, time and likes, ready to score.
- **Competitor comment research** — what people say under a rival's posts, reply threads included.
- **Reply-thread export** — every reply as a row that names the comment it answers.
- **Finding who engages** — handle, name, verified and private flags on every row.

### 🛠 Input

Two sections in the form: **🎯 Posts to export** and **▶️ Run & Storage Options**.

| Field | What it does | Default |
|---|---|---|
| **Post Links** | Post or reel links, one per line — up to 50 on a paid plan, 3 on the free one. Empty = demo run. | empty |
| **Max comments per post (cost control)** | Cost ceiling per post, in comments. A reply is a comment. `0` = no cap (paid plans). | `1000` |
| **Include reply threads** | Return each reply as its own row. | on |
| **Include who liked each comment** | Adds the accounts that liked each comment; a separate, cheaper event. | off |
| **Max likers per comment** | How deep to read each comment's liker list. | `50` |
| **Start a Fresh Run** | Uncheck to resume the previous run. | on |

An unreadable link — not a post, deleted, or inside a private account — comes back as a **free row** with the reason.

### 💰 How much will scraping Instagram comments cost?

You pay per comment, not per run. Two events, priced by your Apify plan:

| Event (per 1,000) | Free | Bronze | Silver | Gold, Platinum & Diamond |
|---|---|---|---|---|
| **Comment** (a reply is a comment) | $2.60 | $2.34 | $2.08 | $1.82 |
| **Comment liker** (optional) | $0.43 | $0.39 | $0.34 | $0.30 |

| You ask for | Plan | Approx. cost |
|---|---|---|
| 50 comments — all a free run reads | Free | $0.13 |
| 1,000 comments | Bronze | $2.34 |
| 5,000 comments | Gold | $9.10 |

- Duplicates are removed **before** charging — you pay once per comment.
- Free rows: unreadable links, comments-off posts, and every `post_summary`.

**Replies count toward the cap** — 200 top-level comments with busy threads is closer to 400 rows, so set the cap for both. **Likers add work, not rows** — one lookup per comment, off by default.

### 🆓 Free vs paid plan

| | Free plan | Paid plan |
|---|---|---|
| Comments per run | 50 | as many as you ask for |
| Runs per month | 15 | unlimited |
| Post links per run | 3 | up to 50 |
| Reply threads | ✅ | ✅ |
| Comment likers | ✅ | ✅ |
| Resume from checkpoint | ✅ | ✅ |

Nothing else is held back: every column, both views and every option work the same on either plan. Links past the third come back as free rows and cost nothing. A run **you abort** still uses up a slot.

All fifteen runs together cost $1.95 of the $5 monthly credit Apify gives a free account, so the allowance is really yours to spend.

### 🧪 Recipes

**A giveaway entrant list** — replies off (giveaway rules count top-level comments, and you pay for fewer rows), then open the **Commenters** view and dedupe by handle.

```json
{ "postUrls": ["https://www.instagram.com/p/YOUR_GIVEAWAY_POST/"],
  "includeReplies": false, "maxCommentsPerPost": 0 }
```

**A full discussion, threads and all** — sort the sheet by `Parent Comment ID` and every thread reads top to bottom.

```json
{ "postUrls": ["https://www.instagram.com/p/YOUR_POST/"],
  "includeReplies": true, "maxCommentsPerPost": 0 }
```

**Several posts, bounded spend** — posts are read in turn, so one viral post cannot starve the others.

```json
{ "postUrls": ["https://www.instagram.com/p/POST_ONE/",
               "https://www.instagram.com/reel/POST_TWO/"],
  "maxCommentsPerPost": 500 }
```

### 🔁 Resume / checkpoint

Uncheck **Start a Fresh Run** to pick up where the last run stopped.

- Posts already finished are skipped.
- A post that hit a cap or an error is read again.
- A post cut off part-way carries on from where it stopped.

A resumed run gets a fresh allowance and spends a monthly slot.

### 📡 Live status & storage records

The run's **Storage → Key-value store** tab holds a live status page and these records:

| Record | What it holds |
|---|---|
| `status.html` | Live progress and cost |
| `RUN_SUMMARY` | Everything about the run, incl. declared vs delivered per post |
| `COMMENT_COVERAGE` | The coverage record alone, for integrations |
| `USER_MESSAGE` | The one thing this run most needs to tell you |
| `UNREAD_LINKS` | Every link that could not be read, with the reason |
| `API_USAGE` | Upstream request counts |
| `FREE_LIMITS_APPLIED` | Free-plan ceilings that applied |

### 🤖 Programmatic / API use

**REST API:**

```bash
curl -X POST "https://api.apify.com/v2/acts/afanasenko~instagram-comments-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"postUrls":["https://www.instagram.com/p/CA2aJYrg6cZ/"],"maxCommentsPerPost":200}'
```

**MCP / agentic clients:** the actor is a tool on Apify's [MCP server](https://docs.apify.com/platform/integrations/mcp) at `mcp.apify.com`. Any AI assistant with your token can find it, read its schemas and run it — just ask: *"get the comments on this Instagram post, replies included, as CSV"*.

A run ends `SUCCEEDED` even with nothing to deliver; the reason is in `USER_MESSAGE` — branch on that.

### 💡 Tips & Best Practices

#### Getting maximum results

- Read a post soon after it goes up; Instagram serves less of an old thread.
- Judge coverage by **Declared** vs **Delivered** on the summary row.
- Paste several posts into one run; one viral post cannot starve the others.

#### Cost optimization

- **Max comments per post** bounds each post's bill, replies included.
- Turn replies off for giveaways; you pay for fewer rows.
- Keep likers off unless you need them; they multiply lookups, not rows.

#### Performance

- Small posts finish in under a minute; thousands of comments take several.
- Stop a long run any time; continue with **Start a Fresh Run** unchecked.
- Bound a huge post with the comment cap, not the run timeout — a cap ends cleanly.

#### Data quality

- Spot-check five rows against the post before scaling up.
- Sort by `Parent Comment ID` to rebuild threads in a sheet.
- `Author Is Private` is information, not a filter.

### ❓ FAQ

**Q: How do I get the comments on an Instagram post?**
A: Paste the post link into **Post Links** and click **Start**. Download the table from **Storage → Dataset**.

**Q: Is there a free Instagram comment scraper?**
A: Yes — 50 comments per run from up to 3 links, 15 runs a month, replies and both views included. No card needed.

**Q: Can I use the Instagram API instead?**
A: Instagram's Graph API returns comments only on your own business account's posts. This actor reads any public post or reel.

**Q: What are the best Instagram comment scraper alternatives?**
A: Check for replies as rows, duplicates removed before you pay, and declared vs delivered per post. This actor does all three.

**Q: Why did I get fewer comments than the post shows?**
A: The counter includes replies, hidden and deleted comments, and Instagram serves only some. Posts read to the very end returned 39–75% of it, median **44%** across eight posts. Totals sit on the `post_summary` row.

**Q: Does it work on private accounts?**
A: No — a post inside a private account comes back as a free row saying so. Comments *written by* private accounts are included.

**Q: Are duplicate comments possible?**
A: No. Instagram sometimes serves a comment on two pages; the actor drops the repeat by id before charging, also after a restart.

**Q: Can I sort comments by newest or most popular?**
A: No — Instagram offers no sort order for this data, so no tool can honestly promise one. Rows arrive in the order served.

**Q: What is the `post_summary` row?**
A: One free row per post with the declared count, what was delivered, and Stop Reason: `end` (list ran out) · `cap` (your limit or the free ceiling) · `error` (source stopped answering) · `disabled` (comments off).

**Q: Why do I see `null` for missing values?**
A: `null` means Instagram did not give it; only `Why Not Analyzed` uses `N/A`. Every key is present except `Comment Likers`, which appears only when likers are on.

### 🔗 Other Instagram scrapers (same author)

| You start with… | You want to find… | Use this actor |
|---|---|---|
| A post or reel link | Its comments and replies, as rows | **This actor** |
| A post or reel link | Who liked or commented, as full profiles | [Instagram Likes Scraper](https://apify.com/afanasenko/instagram-post-likers-scraper) |
| Handles, links, keywords or places | Profiles via 6 discovery modes | [Instagram Profile Scraper](https://apify.com/afanasenko/instagram-profile-scraper) |
| One known account | Its followers and following | [Instagram Followers & Following Extractor](https://apify.com/afanasenko/instagram-followers-scraper) |
| One known account | Who followed and unfollowed **over time** | [Instagram Follower Tracker](https://apify.com/afanasenko/instagram-follower-tracker) |
| 1–5 seed handles | Similar profiles via «Suggested for You» | [Instagram Related Profiles Scraper](https://apify.com/afanasenko/instagram-related-profiles-scraper) |
| A keyword or a hashtag | The accounts in that niche | [Instagram Influencer Search](https://apify.com/afanasenko/instagram-influencer-search) |
| A reel link or a creator handle | What the reels **say** — transcript, on-screen text | [Instagram Reel Script Extractor](https://apify.com/afanasenko/instagram-reel-script-extractor) |
| An AI agent | The profile scraper's modes as MCP tools | [Instagram Profile Scraper MCP Server](https://apify.com/afanasenko/instagram-profile-scraper-mcp-server) |

People behind a post as profiles → Instagram Likes Scraper. What they **said** → this one.

### 🛟 Support & feedback

- **Open an issue** on the actor's [Issues tab in Apify Console](https://console.apify.com/actors/dNo2eHsgX7nec70EF/issues) — paste the run URL.
- **Feature requests** in the same tab; we read every one.
- **Ratings & reviews** on the [Apify Store page](https://apify.com/afanasenko/instagram-comments-scraper) help other users find the actor.

### ⚖️ Is it legal to scrape Instagram comments?

Yes — the actor reads **publicly available** comments and does not log in, bypass authentication, read private accounts, or interact with content on your behalf. You are responsible for how you use the data, including GDPR, CCPA and Instagram's terms.

# Actor input Schema

## `postUrls` (type: `array`):

Instagram post or reel links, one per line — e.g. https://www.instagram.com/p/CA2aJYrg6cZ/. Reel links work too. A link that is not a post link, a deleted post, and a post inside a private account cannot be read — each one comes back as its own free row naming the link and why. Leave empty to run a small demo on a public post.

## `maxCommentsPerPost` (type: `integer`):

Hard cost ceiling per post — each comment returned is one paid event, and a reply is a comment. A post with 30,000 comments costs 30,000 events unless you cap it here. 0 = no cap, paid plans only. Free plan ceiling: 50 comments per run, from up to 3 post links. Default 1000.

## `includeReplies` (type: `boolean`):

Read the replies under each comment and return them as their own rows, marked as replies and carrying the comment they answer. Replies are billed like any other comment. Posts with reply threading switched off are detected before any reply call is made, so this costs nothing on them.

## `includeCommentLikers` (type: `boolean`):

Add the accounts that liked each comment. This is a separate, cheaper paid event and is off by default because it multiplies the work: a post with 1,000 comments means up to 1,000 extra lookups. Posts with comment likes switched off are detected first and cost nothing.

## `maxLikersPerComment` (type: `integer`):

How deep to read each comment's liker list. Instagram serves them 50 at a time. Only used when the option above is on. Default 50.

## `clearSavedData` (type: `boolean`):

Check this to clear saved data from previous runs and start clean. Uncheck to resume a previous run from where it left off.

## Actor input object example

```json
{
  "postUrls": [],
  "maxCommentsPerPost": 1000,
  "includeReplies": true,
  "includeCommentLikers": false,
  "maxLikersPerComment": 50,
  "clearSavedData": true
}
```

# Actor output Schema

## `liveStatus` (type: `string`):

No description

## `results` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

## `commentCoverage` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("afanasenko/instagram-comments-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("afanasenko/instagram-comments-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call afanasenko/instagram-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afanasenko/instagram-comments-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dNo2eHsgX7nec70EF/builds/lWPbjxZ2I7ioP1bxS/openapi.json
