---
title: "List Instagram post comments"
method: GET
path: "/instagram/post/comments"
tags: ["instagram"]
---

# List Instagram post comments

`GET /instagram/post/comments`

## Request

- Base URL: `https://www.socialcrawl.dev/v1`
- URL: `https://www.socialcrawl.dev/v1/instagram/post/comments`
- Auth: API key in header `x-api-key`

Returns a list of comments on an Instagram post, ranked by the platform's own popularity order by default (`sort=top`) so the most-liked comments come first, or newest-first with `sort=recent`. Each comment includes the author, comment text, real like count, reply count, and creation timestamp. Page through with `cursor`. Note: comment.author.display_name is usually null, because the Instagram surface that serves this endpoint withholds commenter display names. Join on comment.author.username.

## Query parameters

- `url` string, required
- `sort` 'top' | 'recent'
- `cursor` string
- `safe_url` boolean
- `scan_pages` integer
- `label` string
- `exclude` string
- `judgments` 'on' | 'off'
- `dry_run` '1'
- `label_evidence` '1'
- `fit` 'goal'
- `goal` string
- `fit_tokens` integer
- `since` string
- `until` string

## Headers

- `Cache-Control` string
- `Idempotency-Key` string

## Response `200`

Successful response

- object
  - `success` boolean, required: Whether the request succeeded
  - `platform` string, required: Platform name
  - `endpoint` string, required: API endpoint path
  - `data` object, required: Platform-specific response data
    - `items` object[]: Array of canonical comment wrappers ({ comment })
      - `comment` object: Canonical Comment object (unified across all platforms)
        - `id` string: Platform-specific comment ID (always a string)
        - `url` string, nullable: Direct URL to the comment on the source platform
        - `parent_id` string, nullable: Parent comment ID for nested replies, or null for top-level comments
        - `post_id` string, nullable: ID of the post this comment belongs to
        - `text` string, nullable: Comment body. Tombstone sentinels ([deleted] / [removed]) are collapsed to null upstream: customers never see them.
        - `author` object: Subset of Author fields for the comment author
          - `username` string, nullable: Comment author username (null when tombstoned)
          - `display_name` string, nullable: Comment author display name
          - `avatar_url` string, nullable: URL to comment author profile picture
          - `verified` boolean, nullable: Whether the comment author is verified
        - `engagement` object: Engagement counts on the comment
          - `likes` integer, nullable: Like / upvote count
          - `replies` integer, nullable: Reply / child-comment count. `0` when the upstream structurally reports the count and the comment has no replies; `null` only when the upstream does not surface a reply count at all.
        - `flags` object: Boolean flags on the comment
          - `pinned` boolean, nullable: Pinned flag (null when platform does not surface)
          - `deleted` boolean: Whether the comment is tombstoned (always present, even when false)
        - `published_at` union: Comment creation timestamp as an ISO 8601 UTC string. When the upstream sent a Unix epoch it is converted here and the raw epoch is preserved under `comment.ext.published_at_epoch` for one deprecation cycle.
          - string
          - integer
        - `ext` object, nullable: Platform-specific passthrough tokens for reply expansion (present only on platforms that surface them)
          - `replies_token` string, nullable: YouTube reply continuation token: pass to `/v1/youtube/video/comment/replies?continuationToken=`
          - `replies_cursor` string, nullable: Reddit reply-branch continuation cursor. Present when this comment's reply tree is truncated upstream: pass it back as `?cursor=` on `/v1/reddit/post/comments` to load the rest of the branch.
          - `depth` integer, nullable: Reddit comment nesting depth as the source reports it: 0 on a top-level comment, 1 on a direct reply, and so on. Present when the thread arrived flat and was re-nested into `replies[]`, so you can verify that nesting independently.
          - `published_at_epoch` integer, nullable: Raw Unix epoch for `published_at` (present only when the upstream sent a numeric epoch that was normalised to the ISO 8601 string).
          - `feedback_id` string, nullable: Facebook comment feedback id: feeds `/v1/facebook/post/comment/replies`
          - `expansion_token` string, nullable: Facebook comment expansion/paginator token: feeds `/v1/facebook/post/comment/replies`
          - `author_id` string, nullable: The commenter's platform-native numeric user id, where the upstream exposes one.
          - `ip_location` string, nullable: String at comment.ext.ip_location
          - `urn` string, nullable: String at comment.ext.urn
          - `reaction_counts` string[], nullable: Array at comment.ext.reaction_counts
          - `is_edited` boolean, nullable: Boolean at comment.ext.is_edited
          - `previous_replies_token` string, nullable: String at comment.ext.previous_replies_token
          - `author_headline` string, nullable: String at comment.ext.author_headline
          - `updated_at` string, nullable: String at comment.ext.updated_at
          - `author_channel_id` string, nullable: String at comment.ext.author_channel_id
          - `author_url` string, nullable: String at comment.ext.author_url
          - `viewer_rating` string, nullable: String at comment.ext.viewer_rating
          - `text_original` string, nullable: String at comment.ext.text_original
          - `preview_replies` string[], nullable: Array at comment.ext.preview_replies
          - `lookup` string, nullable: Leaf at comment.ext.lookup
          - `post_title` string, nullable: String at comment.ext.post_title
          - `post_url` string, nullable: String at comment.ext.post_url
          - `subreddit` string, nullable: String at comment.ext.subreddit
          - `subreddit_subscribers` integer, nullable: Numeric at comment.ext.subreddit_subscribers
          - `post_score` integer, nullable: Numeric at comment.ext.post_score
          - `post_comment_count` integer, nullable: Numeric at comment.ext.post_comment_count
          - `post_author` string, nullable: String at comment.ext.post_author
          - `post_published_at` string, nullable: String at comment.ext.post_published_at
          - `post_flair` string, nullable: String at comment.ext.post_flair
          - `is_submitter` boolean, nullable: Boolean at comment.ext.is_submitter
          - `edited_at` string, nullable: String at comment.ext.edited_at
          - `controversiality` integer, nullable: Numeric at comment.ext.controversiality
          - `content_language` string, nullable: ISO 639-1 language tag for this comment, when the source reports one. X writes `zxx` / `und` for no linguistic content; those collapse to null.
          - `author_followers` integer, nullable: The commenter's follower count as embedded in this row. Snapshot as of whenever the replies source saw the account, not a live figure. On X this is present on every `tweet/replies` row.
          - `author_following` integer, nullable: The commenter's following count as embedded in this row. Same snapshot caveat as `author_followers`.
          - `author_posts_count` integer, nullable: The commenter's post count as embedded in this row. Same snapshot caveat as `author_followers`.
          - `quote_count` integer, nullable: How many quote-posts this comment has, when the source reports it. On X a reply is a tweet, so this is the same figure `post.ext.quote_count` carries on tweet lanes.
          - `views` integer, nullable: View count for this comment, when the source reports it. On X a reply is a tweet and the count is public on posts from ~2022 onward.
          - `saves` integer, nullable: Bookmark / save count for this comment, when the source reports it. On X this is `legacy.bookmark_count`.
        - `replies` object[], nullable: Nested reply tree: array of child comments, each itself a full Comment object with its own `replies`. Populated on threaded platforms (Reddit); absent on flat-comment platforms, which thread only via `parent_id`.
    - `next_cursor` string, nullable: Opaque cursor for the next page. Pass it back as a query parameter on endpoints that support pagination. Present only when the upstream reports more results.
    - `total` integer, nullable: Total number of matching results, when the upstream provides a count. Omitted otherwise.
    - `dropped` integer, required: Number of upstream list items dropped because they could not be repaired to the endpoint schema. Valid list responses include 0.
    - `_warnings` string[]: Non-fatal notices about this response (field-map drift, clamped computed values). Advisory only: its presence never means the request failed. Omitted entirely when there is nothing to report, so treat absent as 'no warnings'.
  - `credits_used` integer, required: Number of credits consumed
  - `credits_remaining` integer, nullable, required: Current account balance, or null when this response could not establish one. Free cache hits always return null because they do not establish an authoritative post-request balance. An idempotency replay also returns null when its current-balance lookup fails. It is never a fabricated zero, so a zero here means the account really is empty. The authoritative reading is the one on a billed response, which comes straight from the deduction.
  - `request_id` string, required: Unique request identifier for support
  - `cached` boolean, required: Whether the response was served from cache
  - `idempotent_replay` boolean: True only when this response is an idempotency replay
  - `meta` object: Optional. Present only when this call completed a pattern that one other call does more cheaply or in one step, at most once per pattern per API key per day. Send the header `X-SocialCrawl-Hints: off` to never receive it.
    - `hint` object: One suggestion: what to call instead and why, with the price when the suggested call costs more than the calls it replaces.
      - `code` string: creator_card | batch_profiles | search_multi | incremental_sync | comment_labels | search_repeat
      - `message` string: One sentence for a person or an agent to read.
      - `method` string: GET or POST.
      - `path` string: The call the hint points to.
  - `pagination` object, required: Cursor state for this page. Present on every list response.
    - `next_cursor` string, nullable, required: Opaque token to send back as `cursor` for the next page, or null at end-of-list. Pass it back verbatim; never decode or trim it.
    - `has_more` boolean, required: Explicit stop signal. Prefer this over inspecting next_cursor or comparing against total.
    - `page_size` integer, required: Number of items in THIS page.
    - `stopped_at` 'since' | 'known_id' | 'end' | 'null', nullable: Present only when the request sent `since` or `stop_at_id`. Why the walk stopped: `since` (this page reached a post older than the date), `known_id` (this page reached the post you already hold), `end` (the list ran out first), or null (not yet, keep walking with `next_cursor`).

## Other responses

- `400`: Invalid request - missing or malformed parameters
- `401`: Unauthorized - missing or invalid API key
- `402`: Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit
- `404`: Not found - the endpoint does not exist, or the requested resource was not found upstream
- `405`: Method not allowed - wrong HTTP verb for this endpoint
- `409`: Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation
- `410`: Gone - the discover run's retention passed and its rows were deleted; start a new run
- `413`: Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling
- `422`: Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)
- `429`: Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.
- `500`: Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit
- `502`: Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge
- `503`: Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge
- `504`: Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After

---

[API](https://skmtc.dev/socialcrawl/apis/socialcrawl-api.md) · [All operations](https://skmtc.dev/socialcrawl/apis/socialcrawl-api/llms.txt) · [OpenAPI document](https://skmtc.dev/socialcrawl/apis/socialcrawl-api/revisions/a0ad2511004a?raw)
