# Instagram Comments Scraper (`coregent/instagram-comments-scraper`) Actor

Scrape public Instagram comments and replies from Posts and Reels. Extract comment text, timestamps, likes, usernames, user IDs, profile pictures, mentions and thread relationships. Process multiple URLs and export clean JSON, CSV or Excel.

- **URL**: https://apify.com/coregent/instagram-comments-scraper.md
- **Developed by:** [Delowar Munna](https://apify.com/coregent) (community)
- **Stats:** 6 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 comment results

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?

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

![Instagram Comments Scraper](https://raw.githubusercontent.com/coregentdevspace/instagram-comments-scraper-assets/main/thumbnail-instagram-comments-scraper.png "Instagram Comments Scraper")

Scrape public Instagram comments and replies from Posts and Reels. Extract comment text, timestamps, likes, usernames, user IDs, profile pictures, mentions and thread relationships. Process multiple URLs and export clean JSON, CSV or Excel.

### What this actor does

**Instagram Comments Scraper** takes a list of Instagram Post or Reel URLs and returns **one flat row per comment or reply**:

- 💬 **Comment**: ID, text (unchanged), timestamp, likes, reply count, `@mentions`, comment link
- 🧵 **Thread**: `isReply`, `threadingDepth`, `rootCommentId`, `parentCommentId`, `replyToCommentId`. Replies are their own rows, so threads stay intact in spreadsheets, SQL and AI pipelines
- 👤 **Commenter**: user ID, username, full name, profile URL, profile picture, verified and private flags
- 🖼️ **Source context**: post ID, shortcode, URL, type (`POST` / `REEL` / `VIDEO` / `CAROUSEL`), owner username, caption preview
- 🚦 **Status rows**: every input that yields no comments (comments disabled, deleted, invalid URL, …) gets a free status row, so inputs always reconcile with outputs

It covers image posts, video posts, carousels, Reels and legacy `/tv/` links. No Instagram login, password, cookies or Meta token is needed.

It extracts comments and only comments. For full post metadata use a posts or Reels scraper, and to enrich commenters feed `ownerUsername` into [Instagram Profile Scraper](https://apify.com/coregent/instagram-profile-scraper).

### How it works

1. **Normalize URLs.** `/p/`, `/reel/`, `/reels/`, `/tv/` and `/{username}/p/…` links are accepted. Tracking parameters (`igsh`, `utm_*`, `img_index`) are stripped and duplicate links to the same post are merged.
2. **Resolve the post** from its public page: type, owner, caption, availability.
3. **Page through comments** in Instagram's own order, then load each comment's replies. Comment pages of one post are fetched in order; replies for a few comments at a time load in parallel.
4. **Fall back instead of failing.** Instagram often refuses anonymous comment loading. When it redirects to its login page, the actor switches that post to an alternative source right away. Rate limits and blocks get one retry on a fresh session/IP first. When Instagram refuses several requests in a row, posts go to the alternative source first and the actor keeps checking whether Instagram has recovered. On the alternative source, the next page of comments loads while the current page's replies are fetched, so rows start appearing within seconds.
5. **Deduplicate and export.** Each comment ID is saved, and charged, once per run.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | required (prefilled with a sample Reel) | Post / Reel / TV URLs (up to 1,000 per run) |
| `resultsLimit` | int | `100` | Max comment **and reply** rows per URL |
| `includeReplies` | bool | `true` | Also collect replies, one row each |
| `sort` | enum | `RECENT` | `RECENT` (newest first) or `TOP` (Instagram's most relevant first) |
| `commentsNewerThan` | string | empty | Keep comments after this point: `24 hours`, `7 days`, `2 weeks`, `2026-09-01`, … |
| `commentsOlderThan` | string | empty | Keep comments before this point |
| `includePostDetails` | bool | `true` | Add the `post` context object to every row |
| `proxyConfiguration` | object | Apify Proxy on | Proxy settings (see [Proxy policy](#-proxy-policy)) |
| `maxConcurrency` | int | `5` | Posts processed in parallel (1–10) |
| `maxRetries` | int | `3` | Retries per request on rate limits / temporary errors |
| `debugMode` | bool | `false` | Verbose logging |

#### Example 1: Minimal

```json
{
  "startUrls": [{ "url": "https://www.instagram.com/reel/DeR1rDbOo2m/" }],
  "resultsLimit": 100
}
```

#### Example 2: Up to 500 comments and replies, newest first

```json
{
  "startUrls": [{ "url": "https://www.instagram.com/reels/DeR1rDbOo2m/" }],
  "resultsLimit": 500,
  "includeReplies": true,
  "sort": "RECENT"
}
```

#### Example 3: Last 30 days only

With `RECENT`, the actor stops paging as soon as it reaches comments older than the window, so you pay neither for the older comments nor for the time spent fetching them.

```json
{
  "startUrls": [{ "url": "https://www.instagram.com/reel/DeR1rDbOo2m/" }],
  "resultsLimit": 1000,
  "includeReplies": true,
  "sort": "RECENT",
  "commentsNewerThan": "30 days"
}
```

#### Example 4: Top comments only, no replies, minimal rows

```json
{
  "startUrls": [{ "url": "https://www.instagram.com/reel/DeR1rDbOo2m/" }],
  "resultsLimit": 50,
  "includeReplies": false,
  "sort": "TOP",
  "includePostDetails": false
}
```

### Output

One row per comment or reply. Unavailable values are `null` (a missing like count is `null`, never a fake `0`). Every row has the same columns, so CSV/Excel exports stay stable. The dataset has four tabs: **Comments**, **Threads**, **Commenters & posts** and **Status & errors**.

The samples below are real rows from a run on `reels/DeR1rDbOo2m` with `resultsLimit: 100` (100 rows: 86 comments + 14 replies). Profile picture URLs are shortened.

#### Comments tab

![Instagram Comments Scraper — Comments tab (table view)](https://raw.githubusercontent.com/coregentdevspace/instagram-comments-scraper-assets/main/instagram-comments-scraper-output-comments-table-view.png "Instagram Comments Scraper — Comments tab (table view)")

```json
{
  "ownerUsername": "talisasg",
  "text": "insoportable mal",
  "timestamp": "2026-10-09T15:42:28.000Z",
  "likesCount": 3,
  "repliesCount": 3,
  "isReply": false,
  "mentionedUsers": [],
  "commentUrl": "https://www.instagram.com/p/DeR1rDbOo2m/c/18126650533830415/",
  "postUrl": "https://www.instagram.com/reel/DeR1rDbOo2m/",
  "commentId": "18126650533830415",
  "ownerId": "225407155",
  "scrapedAt": "2026-10-09T16:13:11.977Z"
}
```

#### Threads tab

A reply row from the same thread. It points at its root comment, and `mentionedUsers` picks up the `@mention`:

```json
{
  "postId": "4004217598789717414",
  "rootCommentId": "18126650533830415",
  "commentId": "17884853547688420",
  "parentCommentId": "18126650533830415",
  "replyToCommentId": "18126650533830415",
  "threadingDepth": 1,
  "isReply": true,
  "ownerUsername": "crab.83643369",
  "text": "@talisasg 😍😍",
  "timestamp": "2026-10-09T15:59:25.000Z"
}
```

#### Commenters & posts tab

```json
{
  "owner": {
    "id": "42060298184",
    "username": "aghalondon",
    "fullName": "Agha beauty/ Men’s Skincare",
    "profileUrl": "https://www.instagram.com/aghalondon/",
    "profilePicUrl": "https://scontent-iad3-2.cdninstagram.com/v/t51.82787-19/649242314_18059727068402185_8936880996156801292_n.jpg?…",
    "isVerified": true,
    "isPrivate": false
  },
  "ownerUsername": "aghalondon",
  "text": "🔥🔥🔥🔥🔥",
  "post": {
    "id": "4004217598789717414",
    "shortCode": "DeR1rDbOo2m",
    "url": "https://www.instagram.com/reel/DeR1rDbOo2m/",
    "type": "REEL",
    "ownerUsername": "oakleymeta",
    "captionPreview": "“Hey Meta, how many putts have I taken today?” This and more putting green questions answered by @meta.ai with @arccosgolf or @18birdiesapp. \n\n*18Birdies app or Arccos game tracking subscription requi…"
  },
  "postUrl": "https://www.instagram.com/reel/DeR1rDbOo2m/"
}
```

#### Status & errors tab

Free status row for a deleted post (from a run on a URL that no longer exists):

```json
{
  "inputUrl": "https://www.instagram.com/p/DPwhVB-jo9k/",
  "rowType": "error",
  "error": "POST_NOT_FOUND",
  "errorMessage": "Fallback source returned no data: \"The requested resource does not exist. Please check the input parameters and verify manually (post, video, comment, user, etc.).\" (data keys: status, errorMessage, attempts)",
  "postUrl": "https://www.instagram.com/p/DPwhVB-jo9k/",
  "scrapedAt": "2026-10-09T15:46:49.965Z"
}
```

All comment columns of a status row are `null`.

#### Full row (all fields)

```json
{
  "rowType": "comment",
  "commentId": "18126650533830415",
  "commentUrl": "https://www.instagram.com/p/DeR1rDbOo2m/c/18126650533830415/",
  "text": "insoportable mal",
  "timestamp": "2026-10-09T15:42:28.000Z",
  "likesCount": 3,
  "repliesCount": 3,
  "isReply": false,
  "threadingDepth": 0,
  "rootCommentId": "18126650533830415",
  "parentCommentId": null,
  "replyToCommentId": null,
  "mentionedUsers": [],
  "ownerUsername": "talisasg",
  "ownerId": "225407155",
  "owner": {
    "id": "225407155",
    "username": "talisasg",
    "fullName": "Talisa Sg",
    "profileUrl": "https://www.instagram.com/talisasg/",
    "profilePicUrl": "https://scontent-iad3-1.cdninstagram.com/v/t51.82787-19/788081894_18623082562063156_3896261708583324431_n.jpg?…",
    "isVerified": false,
    "isPrivate": false
  },
  "isEdited": false,
  "hasTranslation": null,
  "postId": "4004217598789717414",
  "postUrl": "https://www.instagram.com/reel/DeR1rDbOo2m/",
  "post": {
    "id": "4004217598789717414",
    "shortCode": "DeR1rDbOo2m",
    "url": "https://www.instagram.com/reel/DeR1rDbOo2m/",
    "type": "REEL",
    "ownerUsername": "oakleymeta",
    "captionPreview": "“Hey Meta, how many putts have I taken today?” This and more putting green questions answered by @meta.ai with @arccosgolf or @18birdiesapp. \n\n*18Birdies app or Arccos game tracking subscription requi…"
  },
  "error": null,
  "errorMessage": null,
  "inputUrl": "https://www.instagram.com/reels/DeR1rDbOo2m/",
  "scrapedAt": "2026-10-09T16:13:11.977Z"
}
```

`commentUrl` uses Instagram's `/p/` form, which opens Reels too. `inputUrl` keeps the URL exactly as you entered it; `postUrl` is the canonical one.

#### Status values

| Status | Meaning |
|---|---|
| `NO_COMMENTS` | The content has no public comments, or none inside your date window |
| `COMMENTS_DISABLED` | Comments are turned off for this content |
| `INVALID_URL` | Not a Post/Reel URL (profile, hashtag, search, story, other site, malformed) |
| `POST_NOT_FOUND` | The Post or Reel doesn't exist or was deleted |
| `PRIVATE_OR_LOGIN_REQUIRED` | Private or restricted content, or Instagram refused anonymous access and the alternative source couldn't help |
| `CONTENT_UNAVAILABLE` | Gated for logged-out visitors (private, age-restricted), or Instagram kept serving its error page |
| `RATE_LIMITED` / `BLOCKED` | Instagram throttled the request and the alternative source couldn't return it either |
| `PARTIAL_RESULT` | Some comments were saved (and charged), then pagination stopped early. The message says why |
| `TEMPORARY_INSTAGRAM_ERROR` / `PROVIDER_ERROR` | Instagram, network or alternative-source error persisted through retries |

Inputs that end in a retry-worthy status (rate limits, blocks, partial results, temporary errors) are collected in a ready-to-run `RETRY_INPUT` record in the key-value store.

#### Run summary

Each run writes a `RUN_SUMMARY` record to the key-value store: input/success/failed URL counts, comments and replies saved, duplicates skipped, comments outside the date window, comments-disabled count, status counts, which route served each post, whether your spending limit stopped the run, and timing (runtime and when the first rows were saved).

### FAQ

**Which URLs work?** `instagram.com/p/{code}/`, `/reel/{code}/`, `/reels/{code}/`, `/tv/{code}/` (where Instagram still resolves it) and `/{username}/p/{code}/`. `www.`, bare and `m.` hosts are all accepted.

**Do I need to log in or provide cookies?** No. The actor never asks for credentials, cookies or tokens.

**Are Reels supported?** Yes, along with image posts, video posts and carousels.

**Are replies included? How deep?** Yes by default. Instagram threads are two levels deep: a comment and its replies (`threadingDepth` 0 and 1). A reply to a reply is attached to the same root comment. `replyToCommentId` holds the specific reply it answered when Instagram exposes it, otherwise the root comment.

**What does `resultsLimit` mean?** The maximum number of rows, comments plus replies, saved per input URL.

**How fast is it?** On our latest test run, 100 rows from one Reel took about 30 seconds, with the first rows saved after about 5 seconds. Comment pages of one post load one after another, so a very large post takes longer. Several posts run in parallel (`maxConcurrency`).

**Can I sort comments?** Yes. `RECENT` and `TOP` use Instagram's own ordering. `TOP` is never simulated by re-sorting a partial list.

**Can I filter by date?** Yes, with `commentsNewerThan` / `commentsOlderThan`. Each row is checked on its own timestamp, replies included. Replies are loaded only for comments inside the window. Comments outside the window are never charged.

**Are comment likes included?** Yes, as `likesCount`, or `null` when Instagram doesn't return it.

**Why might I get fewer comments than Instagram displays?** Instagram's displayed count includes comments that are hidden, filtered as offensive or spam, restricted, or deleted, and it counts replies the public list can't reach. `repliesCount` is Instagram's total and can be higher than the replies saved when `resultsLimit` is reached.

**What happens when comments are disabled?** You get one free `COMMENTS_DISABLED` status row for that URL, and the rest of the run continues.

**Can I schedule recurring runs or use the API?** Yes. Use Apify Schedules for recurring runs (with `commentsNewerThan` set to the schedule interval, each run picks up only new comments) and the Apify API, SDKs, integrations or MCP server for automation and AI agents.

**How do I enrich commenter profiles?** Pass the `ownerUsername` values into [Instagram Profile Scraper](https://apify.com/coregent/instagram-profile-scraper) for follower counts, bio, links and business contact fields.

### Pricing

Pay per event, **per delivered unique comment or reply**. You are not charged for invalid URLs, duplicates, comments outside your date filter, status/error rows, post resolution, pagination, retries or the run summary. There is no start fee. The rate per comment can differ by Apify plan, so see the **Pricing** tab for the current rate on yours. This README deliberately doesn't quote figures.

The actor respects the spending limit you set for a run. It never saves more comments than the limit pays for, and it doesn't start fetching what the remaining budget can't cover. When the limit is reached the run stops cleanly. A post cut short gets a free `PARTIAL_RESULT` row saying so. That post and any posts not yet started are listed in `RETRY_INPUT`, so you can continue with a larger budget. A re-run starts each post from the beginning, so comments already saved are collected again.

#### 🚦 Proxy policy

Use **Apify Datacenter** proxy (the default) or **no proxy** for normal runs. Both are supported: when Instagram throttles the proxy's IPs, comments are served by the alternative source instead. If you enable Apify Proxy without choosing a country, exits are pinned to the **US** to avoid regionally blocked IPs. Pick a country in the proxy editor to override.

**Apify Residential proxy is not supported.** The actor fails at startup if `apifyProxyGroups` includes `RESIDENTIAL`. In pay-per-event actors, residential bandwidth is billed per GB to the developer, not the run user, so a single bandwidth-heavy run could cost more than the per-result revenue.

If you need residential routing, supply your own residential provider in the proxy editor's **Custom proxy URLs** field. That traffic goes through your provider, not Apify, and is unaffected:

```
http://user:pass@proxy.iproyal.com:12321
http://user:pass@proxy.brightdata.com:22225
http://user:pass@proxy.oxylabs.io:7777
```

### Limitations

- **Public content only.** Private accounts and content gated for logged-out visitors are not supported. They return a free status row.
- **Instagram limits anonymous comment loading.** Many comment requests are served by the alternative source rather than Instagram directly. Results are the same comments, but a post that neither source can load ends as a free `RATE_LIMITED`, `BLOCKED` or `PRIVATE_OR_LOGIN_REQUIRED` row.
- **Hidden, filtered and deleted comments** aren't returned, and the actor doesn't attempt to reconstruct a logged-in user's personalised comment view.
- **Date-window scanning is bounded.** When comments can't be skipped by date (`TOP` sort, or `commentsOlderThan`), the actor pages through comments outside the window without charging for them. It stops after 50 such pages in a row on one post, or 500 across the run, and marks the post `PARTIAL_RESULT`. `RECENT` with `commentsNewerThan` stops early and never hits this.
- **`isEdited`** is `null` whenever Instagram doesn't expose an edit flag for a comment.
- **Profile picture URLs expire** after a while, as all Instagram CDN links do. Download them promptly if you need them.
- **Post type** comes from the post itself when it can be resolved. Otherwise it falls back to the URL (`/reel/` → `REEL`, `/tv/` → `VIDEO`, `/p/` → `POST`).

### Legal and privacy

This is an unofficial tool and is not affiliated with, endorsed by or sponsored by Instagram or Meta. It collects only publicly available comment data and doesn't log in, collect credentials or bypass private-account controls.

Public commenter information (usernames, names, profile pictures, comment text) can still be personal data. You are responsible for processing it lawfully (e.g. under GDPR/CCPA). Collect only what you need for your purpose, and don't use it for harassment, unlawful discrimination or sensitive profiling.

### Local development

```bash
cd actor
npm install
npm test       # unit tests (URL normalizer, comment parser, threading, response classification)
npm start      # run with INPUT.json
```

# Actor input Schema

## `startUrls` (type: `array`):

Public Post, Reel or legacy TV URLs: instagram.com/p/{shortcode}/, /reel/{shortcode}/, /reels/{shortcode}/ or /tv/{shortcode}/. Tracking parameters are stripped and duplicates removed. Profile, hashtag, search and story URLs are rejected as free INVALID_URL rows. Up to 1,000 URLs per run.

## `resultsLimit` (type: `integer`):

Maximum comment and reply rows saved per input URL. Replies count toward the limit. Typical values: 100, 500, 1,000, 5,000, 10,000.

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

Also collect replies. Each reply is its own row with rootCommentId and parentCommentId pointing at the comment it belongs to.

## `sort` (type: `string`):

Instagram's own comment ordering. RECENT = newest first (enables early stopping with a date filter). TOP = Instagram's most relevant comments first. TOP is never simulated by sorting locally.

## `commentsNewerThan` (type: `string`):

Keep only comments posted after this point. Relative ("24 hours", "7 days", "2 weeks", "3 months") or a date ("2026-09-01", "2026-09-01T00:00:00Z"). Leave empty for no limit. With RECENT sort, pagination stops once older comments are reached. Filtered-out comments are not charged.

## `commentsOlderThan` (type: `string`):

Keep only comments posted before this point. Same formats as above. Leave empty for no limit. Newer comments are still paged through (but not charged) to reach older ones.

## `includePostDetails` (type: `boolean`):

Add lightweight Post/Reel context to every row: post ID, shortcode, URL, type (POST / REEL / VIDEO / CAROUSEL), owner username and a caption preview. postId and postUrl are always included.

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

Apify Proxy configuration. Defaults to Apify Proxy (datacenter), which rotates IPs between sessions to spread Instagram's per-IP limits. Apify Residential is not supported; use Custom proxy URLs for your own residential provider.

## `maxConcurrency` (type: `integer`):

Number of Posts/Reels processed in parallel. Comment pages of one post are always fetched in order.

## `maxRetries` (type: `integer`):

How many times a request is retried on a fresh session/IP after rate limits, login walls or temporary Instagram errors. When Instagram keeps refusing, the post is fetched from an alternative source instead. Deleted, private and comments-disabled content is never retried.

## `debugMode` (type: `boolean`):

Enable verbose logging.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.instagram.com/reel/DeR1rDbOo2m/"
    }
  ],
  "resultsLimit": 100,
  "includeReplies": true,
  "sort": "RECENT",
  "commentsNewerThan": "",
  "commentsOlderThan": "",
  "includePostDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 5,
  "maxRetries": 3,
  "debugMode": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `threads` (type: `string`):

No description

## `commenters` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `runSummary` (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 = {
    "startUrls": [
        {
            "url": "https://www.instagram.com/reel/DeR1rDbOo2m/"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("coregent/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 = {
    "startUrls": [{ "url": "https://www.instagram.com/reel/DeR1rDbOo2m/" }],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("coregent/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 '{
  "startUrls": [
    {
      "url": "https://www.instagram.com/reel/DeR1rDbOo2m/"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call coregent/instagram-comments-scraper --silent --output-dataset

```

## MCP server setup

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