> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-fetch.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Instagram comments

> Comments and replies from Instagram posts and reels. scraper_type instagram_comments.

`instagram_comments` collects the comments on Instagram posts and reels, and their replies if you ask. One result is
one comment or one reply.

## Run it

```python Python theme={null}
import os

from gofetch import GoFetchClient

client = GoFetchClient(api_key=os.environ["GOFETCH_API_KEY"])

run = client.actor("instagram_comments").call(run_input={
    "directUrls": ["https://www.instagram.com/p/DPPPDobiXL3/"],
    "maxCommentsPerPost": 100,
    "maxComments": 500,
})

for comment in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(comment["timestamp"], comment["likesCount"], comment["text"])
```

```bash cURL theme={null}
curl https://go-fetch.io/api/v1/jobs/create/ \
  -H "X-API-Key: $GOFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scraper_type": "instagram_comments",
    "config": {"handles": ["nasa"], "maxPosts": 2, "maxCommentsPerPost": 100, "maxComments": 500}
  }'
```

## Inputs

Send `directUrls`, `handles`, or both, in `config`.

| Field | Type | Default | What it does |
| - | - | - | - |
| `directUrls` | list of URLs | | Post or reel links (`/p/`, `/reel/`, `/reels/`, `/tv/`). The most reliable input. Other Instagram links are skipped. |
| `handles` | list of text | | Accounts, with or without `@`. Their most recent posts are found for you. For business accounts, prefer post links: Instagram refuses some business handles to signed-out visitors. |
| `maxPosts` | integer | `10` | Posts per handle, up to 1,000. Not used for `directUrls`. |
| `maxComments` | integer | no cap | The budget for the whole job, comments and replies together, up to 1,000,000. The job stops cleanly when it is reached. |
| `maxCommentsPerPost` | integer | `500` | Top-level comments per post, up to 100,000. |
| `includeReplies` | true / false | `false` | Also collect replies. Every comment is checked for replies, which takes about 13 times the requests, and each reply is a billed result. JSON `true` or `false` only: anything else, such as the string `"false"`, is refused with `400`. |
| `maxRepliesPerComment` | integer | `50` | Replies per comment, up to 10,000. |
| `onlyCommentsNewerThan` | date or date-time | | Only comments posted on or after this time. Not in the future. |
| `enrichCommenterProfiles` | true / false | `false` | Look up each commenter for their full name and whether the account is private. One extra request per commenter. JSON `true` or `false` only. |
| `maxTotalChargeUsd` | number | | A spending cap. If you leave out `maxComments`, it becomes what the cap buys. See [Billing](https://docs.go-fetch.io/billing.md#cap-a-job-with-maxtotalchargeusd). |

> [!TIP]
>
> Always set `maxComments`. It is your cost ceiling. Without it, credit is reserved for `maxPosts` ×
> `maxCommentsPerPost` comments (twice that with replies) when the job is created.

## Output

One row per comment, and one per reply when `includeReplies` is on. Every field is always present. Real rows from a
job on a NASA post; the commenters' handles, ids and pictures are replaced with placeholders here:

```json theme={null}
[
  {
    "type": "comment",
    "platform": "instagram",
    "postUrl": "https://www.instagram.com/p/DPPPDobiXL3/",
    "commentUrl": "https://www.instagram.com/p/DPPPDobiXL3/c/18031446110890400",
    "parentCommentUrl": null,
    "id": "18031446110890400",
    "text": "The most beautiful thing in the universe is the universe by itself ✨❤️💞",
    "ownerUsername": "example_commenter_1",
    "ownerProfilePicUrl": "https://example.com/placeholder-avatar.jpg",
    "timestamp": "2026-09-23T19:56:53.000Z",
    "likesCount": 1,
    "repliesCount": null,
    "replies": null,
    "parentCommentId": null,
    "isReply": false,
    "owner": {
      "username": "example_commenter_1",
      "id": "00000000000",
      "profile_pic_url": "https://example.com/placeholder-avatar.jpg",
      "is_verified": false,
      "fbid_v2": null,
      "full_name": null,
      "is_private": null,
      "is_mentionable": null,
      "profile_pic_id": null,
      "latest_reel_media": null,
      "sec_uid": null
    }
  },
  {
    "type": "comment",
    "platform": "instagram",
    "postUrl": "https://www.instagram.com/p/DPPPDobiXL3/",
    "commentUrl": "https://www.instagram.com/p/DPPPDobiXL3/c/18147098077534069",
    "parentCommentUrl": null,
    "id": "18147098077534069",
    "text": "Wow, what a stunning celestial scene! 🌐 The galaxy's beauty never ceases to amaze me.",
    "ownerUsername": "example_commenter_2",
    "ownerProfilePicUrl": "https://example.com/placeholder-avatar.jpg",
    "timestamp": "2026-08-22T08:16:35.000Z",
    "likesCount": 1,
    "repliesCount": null,
    "replies": null,
    "parentCommentId": null,
    "isReply": false,
    "owner": {
      "username": "example_commenter_2",
      "id": "00000000000",
      "profile_pic_url": "https://example.com/placeholder-avatar.jpg",
      "is_verified": false,
      "fbid_v2": null,
      "full_name": null,
      "is_private": null,
      "is_mentionable": null,
      "profile_pic_id": null,
      "latest_reel_media": null,
      "sec_uid": null
    }
  }
]
```

| Field | Type | What it holds |
| - | - | - |
| `type` | text | Always `comment`, replies included. |
| `platform` | text | `instagram`. |
| `postUrl` | URL | The post, as you sent it, or as found from a handle. |
| `commentUrl` | URL | Link to the comment (a reply's link includes its parent). |
| `parentCommentUrl` | URL or null | The parent comment's link, on a reply. |
| `id` | text | The comment's id. |
| `text` | text or null | The comment. |
| `ownerUsername` | text or null | The commenter's handle. |
| `ownerProfilePicUrl` | URL or null | The commenter's picture. |
| `timestamp` | date-time or null | When it was posted (ISO 8601, UTC). |
| `likesCount` | integer or null | Likes on the comment. |
| `repliesCount` | integer or null | `null` means not counted: Instagram shows no reply count to signed-out visitors. A number appears only when the replies were collected to the end; `0` means checked, none. Always `null` on a reply. |
| `replies` | null | Always `null`: replies are rows of their own. |
| `parentCommentId` | text or null | The parent comment's id, on a reply. |
| `isReply` | true / false | The row is a reply. |
| `owner` | object | The commenter: `username`, `id`, `profile_pic_url`, `is_verified`; `full_name` and `is_private` only with `enrichCommenterProfiles`. Other keys are always `null` on Instagram. |
| `raw` | object | Instagram's original comment object, unchanged. Its shape can change without notice. |

A post that delivered no comments returns a `post_error` row (`type: "post_error"`, `postUrl`, `error`, `status`:
`error`, `throttled` or `unavailable`). It is not billed. The job's `error_message` then names up to five such posts,
even when the job completed.

## What logged-out means here

**You get:** comments and replies on public posts and reels, with the commenter's handle, picture and verified badge.

**Not available:**

* Comments on private, deleted or region-blocked posts (a `post_error` row with `status: "unavailable"`).
* Reply counts, until the replies are collected.
* A commenter's full name and privacy, unless you turn on `enrichCommenterProfiles`.
* Posts of private, age-restricted or unavailable accounts given as `handles`. They are skipped without a per-handle
  report; if no post is found at all, the job fails.

## Completeness

`scraper_metadata.coverage` compares what was collected with the comment count each post shows:

| Key | What it says |
| - | - |
| `weighted` | Comments collected ÷ comments the posts show, across the job. Prefer it to `mean`. |
| `mean` | The average of each post's ratio; `null` when no post showed a count. |
| `posts_partial`, `posts_failed`, `posts_throttled` | Posts below the threshold, posts that failed, posts Instagram stopped serving. |
| `posts_exhausted` | The job ran out of posts before `maxComments`: raise `maxPosts`. |
| `comparable` | Whether the ratio is meaningful. A post's count includes replies, so compare with `includeReplies: true`. |

With replies on, `scraper_metadata.replies` adds `replies_collected`, `parents_probed`, `parents_with_replies` and
`parents_truncated`. With enrichment on, `scraper_metadata.enrichment` adds `requests`, `uniqueCommenters` and
`failures`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.