# Instagram Comments Scraper: Authors, Likes & Monitoring (`automatic/instagram-comments-scraper`) Actor

Collect public top-level Instagram comments from posts and reels: text, author, likes, timestamps and direct links. Filter by date and get only new comments across scheduled runs. Empty input runs a sample of up to 20 comments. $1 per 1,000 comments plus $0.30 per 1,000 pages read.

- **URL**: https://apify.com/automatic/instagram-comments-scraper.md
- **Developed by:** [Philip Kirkbride](https://apify.com/automatic) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 delivered comments

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Comments Scraper

Collect public top-level comments from Instagram posts and reels. Each comment
becomes one row with its text, author, time, likes and direct link. GIF-only
comments are preserved, including their GIF link. No Instagram account is needed.

Filter comments by date, or remember delivered comments across scheduled runs.
Replies are not collected in this version. Instagram may show fewer comments to
signed-out visitors than the total displayed on a post.

### Use cases

- **Comment mining and UGC research.** Collect what people write under a
  campaign, a creator's post or a competitor's reel; `likesCount` ranks the
  comments that resonated and `commentUrl` opens each one.
- **Brand and trend monitoring.** Schedule a run with `monitoringKey`; later
  runs deliver only comments you have not received before, so a daily schedule
  becomes a clean feed of what is new.
- **Campaign reporting.** Run over the posts of a campaign and read
  `OUTPUT.postResults` for comments per post, pages checked and why collection
  stopped.
- **Moderation triage.** `ownerIsVerified` and `likesCount` help sort a large
  thread; GIF-only comments are kept with their `gifUrl` and an empty `text`.
- **Sentiment or topic analysis input.** The Actor does not infer sentiment; it
  preserves text, author, time and counts for your own model or spreadsheet.

To get the post links for a creator or a brand, use the
[Instagram Profile Scraper](https://apify.com/automatic/instagram-profile-scraper)
and pass its `latestPosts[].url` values here.

### Pricing

| Charge | Price |
| --- | ---: |
| Delivered comments | $1 per 1,000 ($0.001 each) |
| Run start | $0.003 per run |
| Comment page checked | $0.0003 per page |

These prices are the same on every Apify plan. A page fee applies once a comment
page has been successfully read, including the initial page, empty pages and
pages containing only old or already-delivered comments. Failed requests and
automatic retries do not add page fees. The page fee
can apply even when date filtering or monitoring delivers zero comments.

For example, 1,000 delivered comments across 47 pages cost $1.0171 in total.
A monitoring run that checks five pages and finds nothing new costs $0.0045.
The run-start fee also applies to runs with errors or no results. Memory is
limited to 512 MB–1 GB so the automatic start fee remains $0.003 per run.
Your maximum run cost stops further collection and delivery when a required
page or result charge no longer fits. The run summary reports pages checked and
why collection stopped.

For comparison, the platform's own Instagram Comments Scraper lists at $2.60
per 1,000 comments ($2.30 on Starter; its Store price starts at $1.90 with
plan discounts). This one is $1 per 1,000 comments plus $0.30 per 1,000 comment
pages checked — about $1.02 per 1,000 at 47 pages.

### Worked costs

| Run | What you pay |
| --- | ---: |
| First-run sample (20 comments, two pages) | about $0.024 |
| 100 comments (two pages) | about $0.104 |
| 1,000 comments across 47 pages | $1.0171 |
| 5,000 comments across about 100 pages | about $5.03 |
| Daily monitor, five pages checked, nothing new | $0.0045 |
| That monitor every day for a month | about $0.135 |

A full comment page carries up to 50 comments; Instagram sometimes returns
fewer, which is why the page fee is small but not zero. Comments skipped by a
date filter or a monitor do not cost a comment fee, but the page they were on
does.

### Quick start

```json
{
  "postUrls": ["https://www.instagram.com/p/DeTUk4sDSp-/"],
  "maxCommentsPerPost": 100,
  "maxItems": 1000
}
```

Use public `/p/` or `/reel/` links, or post shortcodes. Repeated links to the same
post are collected once. Profile links are not supported; supply the individual
post links you want to collect.

An empty run returns a small sample of 20 comments from the prefilled post, and
reports `usedExample: true` in the run summary.

### Your first run

Press Start without touching the form: the Actor collects a sample of up to 20
comments from the prefilled post, reports `usedExample: true` and says in the run
status that it was the example run. That costs about $0.024 — one run start,
two comment pages and 20 delivered comments.

Then paste your own links. In the Console, click **Bulk edit** in the `postUrls`
field and add one public `/p/` or `/reel/` link (or shortcode) per line, up to
1,000 per run; repeated links to the same post are collected once. Use
`maxCommentsPerPost` for how deep to go in each thread and `maxItems` for the
run total, and `maxPagesPerPost` when a thread is old and you only want the
newest pages.

### Inputs

| Input | Default | Meaning |
| --- | --- | --- |
| `postUrls` | the sample post | Up to 1,000 public post/reel links or shortcodes; paste one per line with Bulk edit. If you leave it out of the input, the Actor collects the same post the Console prefills (`/p/DeTUk4sDSp-/`), so a bare start still returns a sample. An empty list is an input error. |
| `maxCommentsPerPost` | `100` | Maximum delivered comments per post, after filtering and deduplication. An empty run returns a small sample of 20 comments from the sample post. |
| `maxItems` | `1000` | Maximum delivered comments in the whole run. |
| `maxPagesPerPost` | `100` | Work limit per post, including the initial page. Useful when many comments are old or already delivered. |
| `onlyCommentsNewerThan` | Unset | ISO timestamp with timezone, such as `2026-11-01T00:00:00Z`. Deliver comments strictly after this date; unknown dates are skipped. |
| `monitoringKey` | Unset | A stable name for a monitor that remembers delivered comments across runs. |

Both comment limits allow 1–100,000. The page limit allows 1–1,000. A short page
does not mean collection is finished: collection follows Instagram's next-page
indicator until a configured limit, source error, stalled cursor or exhaustion.

### Scheduled monitoring

```json
{
  "postUrls": ["https://www.instagram.com/p/DeTUk4sDSp-/"],
  "monitoringKey": "campaign-november",
  "onlyCommentsNewerThan": "2026-11-01T00:00:00Z",
  "maxCommentsPerPost": 500,
  "maxPagesPerPost": 50
}
```

The first run delivers matching comments. Later runs with the same key skip
previously delivered comment IDs and continue looking through the allowed pages.
Only the latest 50,000 delivered IDs are remembered across all posts for that
key; older comments can appear again after eviction. Changing the key starts an
independent monitor. Run one task at a time per key: overlapping runs can deliver
duplicates. Dataset delivery and monitor checkpoints are separate operations,
so a crash or platform retry can also repeat a delivered comment. Deduplicate
by `id` in downstream systems.

### Output

| Fields | Meaning |
| --- | --- |
| `id`, `commentUrl` | Comment identity and direct link. |
| `postId`, `postShortCode`, `postUrl` | Source post identity. |
| `text`, `gifUrl` | Original text and optional GIF; text may be empty for a GIF-only comment. |
| `timestamp`, `scrapedAt` | Published time when available, and collection time, in UTC. |
| `likesCount`, `repliesCount` | Source-provided counts, or `null` when unavailable. Reply counts are commonly unavailable. |
| `ownerUsername`, `ownerId`, `ownerIsVerified` | Public commenter identity and verification status when shown. |
| `ownerProfileUrl`, `ownerProfilePicUrl` | Public profile and picture links when shown. |
| `parentCommentId`, `isReply` | Parent identity if the source provides it. Reply threads are not fetched. |

The `OUTPUT` record reports delivered rows, per-post pages and stop reasons,
date-filter skips, already-delivered comments, errors and `hasMore`. Its
`sourceReportedComments` is the post's displayed count where available, which
may include replies and unavailable comments; it is not a promise of collectable
rows. `exhausted` means the public comment connection ended, not that every
comment on Instagram was available. A `complete` run means collection finished
under your configured limits; inspect each post's stop reason for coverage.

Failed posts do not become dataset rows. A run where every post fails exits
with an error. A genuinely empty post, a date filter with no matches, or a monitor
with no new comments can finish successfully with zero rows.

### Limits

- Public top-level comments only. No private accounts, account cookies or reply-thread collection.
- Instagram can hide, remove, reorder or refuse comments. Collection is not guaranteed to include every comment or maintain a fixed order.
- Filtering examines all fetched comments; it does not assume old comments mean later pages are also old.
- Profile pictures and GIF links can expire. Counts reflect the time of collection.
- No sentiment or buying-intent inference is included; the output preserves source data.

# Actor input Schema

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

Public Instagram /p/, /reel/ links or shortcodes. Repeated links are collected once.

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

Maximum delivered comments per post after filtering and monitoring deduplication. An empty run returns a small sample of 20 comments from the prefilled post.

## `maxItems` (type: `integer`):

Maximum delivered comments across all supplied posts.

## `maxPagesPerPost` (type: `integer`):

Bound the work when comments are old or already delivered. Includes the initial page. The summary reports when this limit stops collection.

## `onlyCommentsNewerThan` (type: `string`):

Optional ISO timestamp with timezone, such as 2026-11-01T00:00:00Z. Deliver comments strictly after this time; unknown dates are skipped.

## `monitoringKey` (type: `string`):

Optional name for scheduled runs. Later runs skip IDs among the latest 50,000 deliveries remembered for this name. Do not overlap runs with the same name.

## `proxyConfiguration` (type: `object`):

Optional override for the automatic connection settings. Explicit settings replace the default route.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.instagram.com/p/DeTUk4sDSp-/"
  ],
  "maxCommentsPerPost": 100,
  "maxItems": 1000,
  "maxPagesPerPost": 100
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "postUrls": [
        "https://www.instagram.com/p/DeTUk4sDSp-/"
    ],
    "maxCommentsPerPost": 100,
    "maxItems": 1000,
    "maxPagesPerPost": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("automatic/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 = {
    "postUrls": ["https://www.instagram.com/p/DeTUk4sDSp-/"],
    "maxCommentsPerPost": 100,
    "maxItems": 1000,
    "maxPagesPerPost": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("automatic/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 '{
  "postUrls": [
    "https://www.instagram.com/p/DeTUk4sDSp-/"
  ],
  "maxCommentsPerPost": 100,
  "maxItems": 1000,
  "maxPagesPerPost": 100
}' |
apify call automatic/instagram-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automatic/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/GWirtndnls1vn7ERo/builds/nYftj54fxpIrZAZvk/openapi.json
