{
  "data": {
    "id": "WHJIbn32YSgaUw2nE",
    "actId": "2LMMaJNlotnjVt3iw",
    "userId": "9Um4NEFR7z42j35AD",
    "startedAt": "2026-10-29T19:41:53.513Z",
    "finishedAt": "2026-10-29T19:42:16.473Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CI",
      "githubActionsRunUrl": "https://github.com/chronometrica/instagram-comments-scraper/actions/runs/40942353652"
    },
    "stats": {
      "durationMillis": 22833,
      "runTimeSecs": 22.833,
      "computeUnits": 0.02537,
      "imageSizeBytes": 2326970368
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Instagram comments scraper\",\n  \"description\": \"Collect public Instagram comments and optional replies without an Instagram account.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"additionalProperties\": false,\n  \"properties\": {\n    \"postUrls\": {\n      \"sectionCaption\": \"Instagram comments\",\n      \"sectionDescription\": \"Add public posts or Reels, then choose the result limit, order, and optional dates.\",\n      \"title\": \"Post and Reel URLs\",\n      \"description\": \"Add one or more public Instagram post or Reel URLs.\",\n      \"type\": \"array\",\n      \"editor\": \"stringList\",\n      \"prefill\": [\n        \"https://www.instagram.com/reel/DZu6dkVyImf/\"\n      ],\n      \"minItems\": 1,\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"maxCommentsPerPost\": {\n      \"title\": \"Maximum top-level comments per post\",\n      \"description\": \"Save at most this many unique top-level comments for each post. Replies do not count toward this limit. Ignored when Remove the result limit is on.\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"default\": 100,\n      \"minimum\": 1,\n      \"maximum\": 999999\n    },\n    \"includeReplies\": {\n      \"title\": \"Include replies\",\n      \"description\": \"Save public replies under the top-level comments saved by this run. Each reply is a separate paid row. Off by default. Replies can increase runtime and cost.\",\n      \"type\": \"boolean\",\n      \"editor\": \"checkbox\",\n      \"default\": false\n    },\n    \"maxRepliesPerComment\": {\n      \"title\": \"Maximum replies per comment\",\n      \"description\": \"Save up to this many unique public replies under each saved top-level comment. Enter a positive whole number. Default: 10. Used only when Include replies is on. Larger values can increase runtime and cost.\",\n      \"type\": \"integer\",\n      \"editor\": \"number\",\n      \"minimum\": 1,\n      \"default\": 10\n    },\n    \"commentSortMode\": {\n      \"title\": \"Comment order\",\n      \"description\": \"Keep Instagram's default order, or sort the collected top-level comment sample by date.\",\n      \"type\": \"string\",\n      \"editor\": \"select\",\n      \"default\": \"default\",\n      \"enum\": [\n        \"default\",\n        \"newest\",\n        \"oldest\"\n      ],\n      \"enumTitles\": [\n        \"Default\",\n        \"Newest first\",\n        \"Oldest first\"\n      ]\n    },\n    \"commentsFrom\": {\n      \"title\": \"From date\",\n      \"description\": \"Only save comments and replies on or after this date. Replies are collected only under saved top-level comments. Leave empty for no start date.\",\n      \"type\": \"string\",\n      \"editor\": \"datepicker\",\n      \"dateType\": \"absolute\"\n    },\n    \"commentsUntil\": {\n      \"title\": \"To date\",\n      \"description\": \"Only save comments and replies on or before this date. Replies are collected only under saved top-level comments. Leave empty for no end date.\",\n      \"type\": \"string\",\n      \"editor\": \"datepicker\",\n      \"dateType\": \"absolute\"\n    },\n    \"collectAllAvailable\": {\n      \"sectionCaption\": \"Advanced\",\n      \"sectionDescription\": \"Use only when you need more top-level comments. This can cost much more.\",\n      \"title\": \"Remove the result limit\",\n      \"description\": \"Ignore the maximum top-level comment limit and save comments as they arrive. Use Default comment order. The separate reply limit still applies. The run stops when the public feed ends, time runs out, or the source fails. This may cost much more.\",\n      \"type\": \"boolean\",\n      \"editor\": \"checkbox\",\n      \"default\": false\n    }\n  },\n  \"required\": [\n    \"postUrls\",\n    \"maxCommentsPerPost\"\n  ]\n}",
    "readme": "# 💬 Instagram Comments Scraper — Fast, Clean & No Login\n\n## 💬 What does Instagram Comments Scraper do?\n\nPaste one or more public Instagram post or Reel URLs. Get fast, clean, unique,\nand structured comment rows with text, public author details, dates, likes, and\nstable IDs. Turn on **Include replies** to collect replies with parent links.\n\nSkip manual copy-and-paste. Choose a clear per-post limit or collect until the\npublic feed ends, sort the sample, add optional dates, and export organized rows.\n\nUse it for social listening, brand monitoring, creator research, customer\nfeedback, academic research, spreadsheets, AI work, and data pipelines. Each\nsaved result is one public comment or reply. Empty or unavailable posts do not\nmake fake dataset rows.\n\nThe Actor uses logged-out public Instagram pages. It does not need your\nInstagram account, cookies, API key, or copied browser session. It does not\nopen private posts or bypass access controls.\n\nWith Instagram Comments Scraper, you can:\n\n- 💬 Collect public comments and optional replies from posts, Reels, and old TV URLs.\n- 👤 Save public usernames, verification flags, and stable author IDs.\n- ❤️ Collect public comment likes and reply totals when Instagram shows them.\n- 🆔 Join data with stable post, short code, and comment IDs.\n- 🎯 Set a positive comment limit for each post, or remove it.\n- ↕️ Keep Instagram's default order, or sort the collected sample by date.\n- 📅 Save only comments inside an optional date range.\n- 🧹 Get unique rows with one stable field shape.\n- 📦 Export JSON, JSONL, CSV, Excel, XML, RSS, or HTML.\n- 🔁 Use the Apify API, SDKs, webhooks, schedules, and integrations.\n\nEach paid result is one unique public comment or reply saved to the default\ndataset. Invalid, unavailable, empty, and duplicate results do not create paid\ncomment rows.\n\n## ✨ Why use this Actor?\n\n- 🪄 **Easy setup:** paste public post URLs, choose a limit, an order, and optional dates.\n- 🔓 **No login:** no Instagram account, cookie, or browser session is needed.\n- 🧹 **Clean, structured rows:** one unique comment or reply per result.\n- 🆔 **Strict identity:** each row stays tied to the requested post short code.\n- 🎛️ **Visible limits:** choose a positive row limit per post or collect until the public feed ends.\n- 🚦 **Honest results:** the public feed may return fewer rows, and `OUTPUT` gives a clear reason.\n- 💸 **Clear billing:** pay only for unique comments and replies saved to the dataset.\n\n## 📦 What data do I get?\n\nEach dataset row is one public Instagram comment or reply.\n\n| Data group         | Main fields                                         |\n| ------------------ | --------------------------------------------------- |\n| 🔗 Post identity   | `postId`, `postShortCode`, `postUrl`                |\n| 💬 Comment         | `commentId`, `text`, `createdAt`                    |\n| ↩️ Reply link      | `isReply`, `parentCommentId`                         |\n| ❤️ Public signals  | `likesCount`, `repliesCount`                        |\n| 👤 Public author   | `ownerId`, `ownerUsername`, `ownerVerified`         |\n| 🕒 Collection time | `collectedAt`                                       |\n\nOptional values that Instagram does not expose stay `null`. They are not\nguessed and are not replaced with fake zeros.\n\n`repliesCount` is the public reply total shown for a top-level comment when it\nis available. `isReply` is true for replies. `parentCommentId` links a reply\nto its saved parent and is null for top-level comments.\n\n## ⚙️ Can I use this Actor through an API?\n\nYes. You can use:\n\n- 🔌 Apify API\n- 🐍 Python SDK\n- 🟢 JavaScript SDK\n- 🪝 Webhooks\n- ⏰ Scheduled runs\n- 🧩 Apify integrations\n\nThis makes it easy to send comments into spreadsheets, databases, dashboards,\nAI analysis tools, customer-feedback systems, and research pipelines.\n\n### 🔌 API example\n\nKeep your Apify token in an environment variable or secret store.\n\n```bash\ncurl -X POST \\\n  \"https://api.apify.com/v2/acts/chronometrica~instagram-comments-scraper/runs?token=$APIFY_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"postUrls\": [\"https://www.instagram.com/reel/DZu6dkVyImf/\"],\n    \"maxCommentsPerPost\": 100,\n    \"collectAllAvailable\": false,\n    \"commentSortMode\": \"default\",\n    \"includeReplies\": false,\n    \"maxRepliesPerComment\": 10\n  }'\n```\n\n## 🎯 Why scrape Instagram comments?\n\n| Use case                  | How comment data helps                                           |\n| ------------------------- | ---------------------------------------------------------------- |\n| 📣 Brand monitoring       | Find public praise, complaints, questions, and product feedback. |\n| 🧑‍🎨 Creator research       | Review the public words around known creator posts.              |\n| 🚀 Campaign research      | Study public response to a launch, ad, event, or partnership.    |\n| 🔎 Social listening       | Track common topics and language in public discussions.          |\n| 🧑‍🔬 Academic research      | Build structured public text samples for analysis.               |\n| 🤖 AI and NLP             | Feed clean comment text into topic or sentiment tools.           |\n| 🧱 Data pipeline building | Load stable rows into a spreadsheet, app, database, or warehouse. |\n\nThe Actor gives you public source data. It does not add sentiment labels or\nguess a person's intent.\n\n## 💵 Pricing\n\nThe price depends on your Apify pricing tier. Each result charge represents one\nunique comment or reply saved to the default dataset. Empty, unavailable, and\nduplicate comments do not create comment result charges.\n\n| Apify tier | Price per comment | Price per 1,000 comments |\n| --- | ---: | ---: |\n| Free | `$0.0020` | $2.00 |\n| Bronze | `$0.0015` | $1.50 |\n| Silver | `$0.0014` | $1.40 |\n| Gold, Platinum, or Diamond | `$0.0013` | $1.30 |\n\nThere is no start fee or minimum run charge.\n\nUse `maxCommentsPerPost` to limit top-level comments and `maxRepliesPerComment`\nto limit replies under each saved parent. Replies are extra paid rows. Begin with 20 to 100 comments while testing a new workflow. Turn on\n`collectAllAvailable` only when you accept a larger and less predictable bill.\n\n## 🚀 How do I use Instagram Comments Scraper?\n\n1. Open **Instagram Comments Scraper** in Apify Console.\n2. Paste one or more public Instagram post or Reel URLs.\n3. Choose the maximum comments to save for each post.\n4. Keep the default order or choose newest-first or oldest-first with optional dates.\n5. Click **Start**.\n6. Open **Output** to inspect the rows and run summary.\n7. Download the dataset or send it to another tool.\n\n## ⬇️ Input\n\n```json\n{\n  \"postUrls\": [\"https://www.instagram.com/reel/DZu6dkVyImf/\"],\n  \"maxCommentsPerPost\": 100,\n  \"collectAllAvailable\": false,\n  \"commentSortMode\": \"default\",\n  \"includeReplies\": false,\n  \"maxRepliesPerComment\": 10\n}\n```\n\n### 🔗 Supported URLs\n\n- 🖼️ `https://www.instagram.com/p/SHORT_CODE/`\n- 🎬 `https://www.instagram.com/reel/SHORT_CODE/`\n- 📺 `https://www.instagram.com/tv/SHORT_CODE/`\n\nQuery strings are removed. Duplicate versions of the same URL are collected\nonce. Profile, hashtag, search, Story, and Explore URLs are not supported.\n\n### 🎛️ Input settings\n\n| Setting | What it controls |\n| --- | --- |\n| `postUrls` | Add one or more public Instagram post, Reel, or old TV URLs. |\n| `maxCommentsPerPost` | Save at most this many unique top-level comments for each URL. Use a positive whole number. Default: 100. Ignored when the limit is removed. |\n| `includeReplies` | Save replies under saved top-level comments. Default: false. Each reply is a separate paid result. |\n| `maxRepliesPerComment` | Maximum replies under each saved parent. Any positive whole number. Default: 10. Used only when replies are on. |\n| `collectAllAvailable` | Remove the top-level limit and stream comments until the public feed ends, time runs out, or the source fails. The reply limit still applies. Use Default order. Off by default and may cost much more. |\n| `commentSortMode` | Keep Instagram's order, or sort the collected public sample with newest or oldest comments first. Default: Instagram's order. |\n| `commentsFrom` | Only save comments on or after this date. Optional. |\n| `commentsUntil` | Only save comments on or before this date. Optional. |\n\nDates are inclusive. A comment without a public date is skipped when either\ndate setting is used. Instagram chooses the public sample. Default keeps the\nsource order. The date options sort that sample; they do not ask Instagram for\na different comment feed. Replies are collected only under saved parents and\nmust also pass the date filters. The remove-limit switch removes the top-level\nlimit; the separate reply limit still applies.\n\nTo include replies:\n\n```json\n{\n  \"postUrls\": [\"https://www.instagram.com/p/CfhVcINpHiY/\"],\n  \"maxCommentsPerPost\": 20,\n  \"includeReplies\": true,\n  \"maxRepliesPerComment\": 10\n}\n```\n\n## ⬆️ Output sample\n\n```json\n{\n  \"postUrl\": \"https://www.instagram.com/reel/DZu6dkVyImf/\",\n  \"postId\": \"3922329444068919711\",\n  \"postShortCode\": \"DZu6dkVyImf\",\n  \"commentId\": \"18000000000000000\",\n  \"isReply\": false,\n  \"parentCommentId\": null,\n  \"text\": \"Example public comment\",\n  \"createdAt\": \"2026-07-14T12:00:00.000Z\",\n  \"likesCount\": 12,\n  \"repliesCount\": 3,\n  \"ownerId\": \"123456789\",\n  \"ownerUsername\": \"example_user\",\n  \"ownerVerified\": false,\n  \"collectedAt\": \"2026-07-14T16:00:00.000Z\"\n}\n```\n\n### 📊 Run summary\n\nThe `OUTPUT` record includes:\n\n- 🎯 Posts requested, successful, empty, and failed;\n- 💬 Total rows, top-level comments, and replies saved;\n- ↩️ Reply threads that failed or were skipped after a source error;\n- 🧢 Posts that reached the chosen limit;\n- 🎛️ The chosen per-post limit, remove-limit switch, order, and optional dates;\n- 🚦 A clear result and stop reason for each input URL.\n\nCommon target results are:\n\n| Result | Meaning |\n| --- | --- |\n| `capped` | The Actor saved the chosen per-post limit. |\n| `sample` | The Actor saved a useful sample below the limit. |\n| `source_exhausted` | The public feed ended before the limit. |\n| `unavailable_or_no_public_data` | Instagram did not expose a public comment feed for that view. |\n| `failed` | A temporary target error stopped that URL. |\n\nAn empty dataset does not always mean the post has no comments. Instagram may\nshow a page but leave the logged-out comment feed empty. Check `OUTPUT`, then\nretry later if the post is public and comments are visible in your browser.\n\n## 🔒 Source boundary\n\nInstagram Comments Scraper uses logged-out public Instagram data only.\n\nIt does not:\n\n- 🔑 Ask for your Instagram username or password;\n- 🍪 Use your account, cookies, or copied session;\n- 🔒 Collect private, followers-only, or login-only posts;\n- 🧩 Solve access challenges or bypass access controls;\n- 🔎 Discover posts from profiles, hashtags, search, or Explore;\n- ♾️ Promise every comment in Instagram's displayed total.\n\n## ⚠️ Limits and interpretation\n\n- Instagram controls which comments are visible to a logged-out viewer.\n- The same post can return a different public sample on another run.\n- A displayed comment total can be higher than the public rows available.\n- `maxCommentsPerPost` is a maximum, not a promise.\n- Date filters and oldest-first order inspect at most 250 public comments per post unless the result limit is removed.\n- Comment order applies to the collected sample, not every comment on Instagram.\n- Deleted, hidden, filtered, region-limited, or moderated comments may be absent.\n- Comment text, likes, reply totals, and author details can change.\n- This Actor is not affiliated with Instagram or Meta.\n\n## ❓ FAQ\n\n### Does this Actor need an Instagram login, cookie, or API key?\n\nNo. It uses public logged-out Instagram pages.\n\n### Why did I get fewer comments than the displayed total?\n\nInstagram's displayed total and logged-out public feed can differ. The public\nfeed may end early or change between runs. Check each target in `OUTPUT`.\n\n### Can I collect replies?\n\nYes. Turn on `includeReplies` and choose `maxRepliesPerComment`. Replies do not\nuse the top-level comment limit. Each reply has its own `commentId`, with\n`isReply: true` and `parentCommentId` set to its saved parent. Public reply\naccess can vary. A partial target and reply failure counts identify incomplete\nreply collection in `OUTPUT`.\n\n### How do date filters and comment order work?\n\nThe Actor filters and sorts the public sample it collected. Dates include the\nwhole chosen day. Instagram can expose a different sample on a later run.\n\n### How are duplicates removed?\n\nDuplicate input URLs are collected once. Saved rows use the post short code and\nInstagram comment ID as the run key.\n\n### What happens when a post returns no public comments?\n\nThe target appears in `OUTPUT`. It does not create a fake comment row.\n\n### Can I remove the comment limit?\n\nYes. Turn on `collectAllAvailable`. The Actor then ignores the numeric limit\nand streams rows until Instagram's public feed ends, the run times out, or the\nsource fails. Use Default comment order with this switch. This can take longer\nand cost much more. It still cannot promise comments that Instagram does not\nexpose publicly.\n\n### Can I paste an Instagram profile URL?\n\nNo. Use known post, Reel, or old TV URLs. This Actor does not discover posts\nfrom profiles.\n\n## 🏆 Best practices\n\n- 🎯 Start with 20 to 100 comments per post.\n- 📚 Batch several known URLs in one run to lower run overhead per row.\n- 🧾 Check `OUTPUT` before treating a small or empty dataset as a bug.\n- 🆔 Join and deduplicate later work with `postShortCode` and `commentId`.\n- 🔁 Use scheduled runs when you want to observe public comment changes.\n\n## 🛟 Support\n\nFor help, include the Apify run ID, one public input URL, what you expected, and\nthe target result shown in `OUTPUT`. Do not send Instagram passwords, cookies,\nsession data, or private links.\n\n## ⚖️ Responsible use\n\nThis Actor collects data that Instagram exposes to logged-out public viewers at\nrun time. You are responsible for using the data lawfully and for following\nprivacy, data-protection, research, and platform rules. Do not use public\ncomments to harass people, infer sensitive traits, or make high-impact choices\nabout individuals.\n\n## 🔗 Related social media scrapers\n\nContinue the same workflow on this platform or compare public data across\nplatforms.\n\n### Continue on Instagram\n\n- [Instagram Profile Scraper](https://apify.com/chronometrica/instagram-channel-scraper)\n  — collect public profile details, links, and audience stats.\n- [Instagram Search Scraper](https://apify.com/chronometrica/instagram-search-scraper)\n  — find public Reels and metrics by keyword.\n- [Instagram Metrics Scraper](https://apify.com/chronometrica/instagram-metrics-scraper)\n  — collect public post, Reel, carousel, profile, and collaboration metrics.\n\n### Compare comments across platforms\n\n- [Facebook Comments Scraper](https://apify.com/chronometrica/facebook-comments-scraper)\n  — collect public comments, replies, authors, dates, and reactions.\n- [TikTok Comments Scraper](https://apify.com/chronometrica/tiktok-comments-scraper)\n  — collect public comments, replies, authors, likes, and thread links.\n- [YouTube Comments Scraper](https://apify.com/chronometrica/youtube-comments-scraper)\n  — collect public comments, replies, authors, likes, pins, and creator\n  hearts.\n- [Reddit Comments Scraper](https://apify.com/chronometrica/reddit-comments-scraper)\n  — collect public thread comments, replies, authors, scores, and dates.\n- [Snapchat Comments Scraper](https://apify.com/chronometrica/snapchat-comments-scraper)\n  — collect public comments and replies from Snapchat Spotlight posts.\n- [LinkedIn Comments Scraper](https://apify.com/chronometrica/linkedin-comments-scraper)\n  — collect public comments, replies, authors, dates, and reactions.\n",
    "changelog": "# Changelog\n\n## September 2026\n\n- Improved comment reliability when Instagram briefly returns no results.\n\n## July 2026\n\n- First public release with comment limits, date filters, and comment ordering.\n",
    "actorDefinition": {
      "$schema": "https://apify.com/schemas/v1/actor.ide.json",
      "actorSpecification": 1,
      "name": "instagram-comments-scraper",
      "title": "Instagram Comments Scraper - Fast & No Login",
      "description": "Collect public Instagram comments and optional replies. Get unique rows with text, dates, likes, authors, IDs, and parent links. No Instagram account required.",
      "version": "0.1",
      "buildTag": "latest",
      "defaultRunOptions": {
        "build": "latest",
        "timeoutSecs": 600,
        "memoryMbytes": 2048
      },
      "exampleRunInput": {
        "contentType": "application/json; charset=utf-8",
        "body": "{\n  \"postUrls\": [\n    \"https://www.instagram.com/reel/DZu6dkVyImf/\"\n  ],\n  \"maxCommentsPerPost\": 100,\n  \"collectAllAvailable\": false,\n  \"commentSortMode\": \"default\",\n  \"includeReplies\": false,\n  \"maxRepliesPerComment\": 10\n}"
      },
      "input": {
        "title": "Instagram comments scraper",
        "description": "Collect public Instagram comments and optional replies without an Instagram account.",
        "type": "object",
        "schemaVersion": 1,
        "additionalProperties": false,
        "properties": {
          "postUrls": {
            "sectionCaption": "Instagram comments",
            "sectionDescription": "Add public posts or Reels, then choose the result limit, order, and optional dates.",
            "title": "Post and Reel URLs",
            "description": "Add one or more public Instagram post or Reel URLs.",
            "type": "array",
            "editor": "stringList",
            "prefill": [
              "https://www.instagram.com/reel/DZu6dkVyImf/"
            ],
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "maxCommentsPerPost": {
            "title": "Maximum top-level comments per post",
            "description": "Save at most this many unique top-level comments for each post. Replies do not count toward this limit. Ignored when Remove the result limit is on.",
            "type": "integer",
            "editor": "number",
            "default": 100,
            "minimum": 1,
            "maximum": 999999
          },
          "includeReplies": {
            "title": "Include replies",
            "description": "Save public replies under the top-level comments saved by this run. Each reply is a separate paid row. Off by default. Replies can increase runtime and cost.",
            "type": "boolean",
            "editor": "checkbox",
            "default": false
          },
          "maxRepliesPerComment": {
            "title": "Maximum replies per comment",
            "description": "Save up to this many unique public replies under each saved top-level comment. Enter a positive whole number. Default: 10. Used only when Include replies is on. Larger values can increase runtime and cost.",
            "type": "integer",
            "editor": "number",
            "minimum": 1,
            "default": 10
          },
          "commentSortMode": {
            "title": "Comment order",
            "description": "Keep Instagram's default order, or sort the collected top-level comment sample by date.",
            "type": "string",
            "editor": "select",
            "default": "default",
            "enum": [
              "default",
              "newest",
              "oldest"
            ],
            "enumTitles": [
              "Default",
              "Newest first",
              "Oldest first"
            ]
          },
          "commentsFrom": {
            "title": "From date",
            "description": "Only save comments and replies on or after this date. Replies are collected only under saved top-level comments. Leave empty for no start date.",
            "type": "string",
            "editor": "datepicker",
            "dateType": "absolute"
          },
          "commentsUntil": {
            "title": "To date",
            "description": "Only save comments and replies on or before this date. Replies are collected only under saved top-level comments. Leave empty for no end date.",
            "type": "string",
            "editor": "datepicker",
            "dateType": "absolute"
          },
          "collectAllAvailable": {
            "sectionCaption": "Advanced",
            "sectionDescription": "Use only when you need more top-level comments. This can cost much more.",
            "title": "Remove the result limit",
            "description": "Ignore the maximum top-level comment limit and save comments as they arrive. Use Default comment order. The separate reply limit still applies. The run stops when the public feed ends, time runs out, or the source fails. This may cost much more.",
            "type": "boolean",
            "editor": "checkbox",
            "default": false
          }
        },
        "required": [
          "postUrls",
          "maxCommentsPerPost"
        ]
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Instagram comments output",
        "description": "Comment and reply rows are in the dataset. OUTPUT contains a short run summary.",
        "properties": {
          "summary": {
            "type": "string",
            "title": "Run summary",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/OUTPUT"
          },
          "comments": {
            "type": "string",
            "title": "Comment and reply rows",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "fields": {
            "$schema": "http://json-schema.org/draft-07/schema#",
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "postUrl": {
                "title": "Post URL",
                "description": "Canonical URL of the Instagram post or Reel.",
                "type": "string"
              },
              "postId": {
                "title": "Post ID",
                "description": "Instagram media ID, or null when Instagram does not expose it.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "postShortCode": {
                "title": "Post short code",
                "description": "Short code from the Instagram post or Reel URL.",
                "type": "string"
              },
              "commentId": {
                "title": "Comment ID",
                "description": "Stable Instagram ID of the comment or reply.",
                "type": "string"
              },
              "isReply": {
                "title": "Is reply",
                "description": "True for a reply and false for a top-level comment.",
                "type": "boolean"
              },
              "parentCommentId": {
                "title": "Parent comment ID",
                "description": "ID of the parent comment for a reply; null for a top-level comment.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "text": {
                "title": "Comment text",
                "description": "Public text of the comment or reply.",
                "type": "string"
              },
              "createdAt": {
                "title": "Comment created at",
                "description": "Comment creation time in UTC, or null when unavailable.",
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "likesCount": {
                "title": "Likes count",
                "description": "Public comment like count; zero is known zero and null means unavailable.",
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0
              },
              "repliesCount": {
                "title": "Replies count",
                "description": "Public reply count; zero is known zero and null means unavailable.",
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0
              },
              "ownerId": {
                "title": "Owner ID",
                "description": "Instagram ID of the public comment author, or null when unavailable.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "ownerUsername": {
                "title": "Owner username",
                "description": "Public username of the comment author, or null when unavailable.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "ownerVerified": {
                "title": "Owner verified",
                "description": "Whether the author is verified; false is known false and null means unavailable.",
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "collectedAt": {
                "title": "Collected at",
                "description": "Time when the Actor collected the comment, in UTC.",
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "postUrl",
              "postId",
              "postShortCode",
              "commentId",
              "isReply",
              "parentCommentId",
              "text",
              "createdAt",
              "likesCount",
              "repliesCount",
              "ownerId",
              "ownerUsername",
              "ownerVerified",
              "collectedAt"
            ]
          },
          "views": {
            "overview": {
              "title": "Comments and replies",
              "transformation": {
                "fields": [
                  "postUrl",
                  "postId",
                  "postShortCode",
                  "commentId",
                  "isReply",
                  "parentCommentId",
                  "text",
                  "createdAt",
                  "likesCount",
                  "repliesCount",
                  "ownerId",
                  "ownerUsername",
                  "ownerVerified",
                  "collectedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {}
              }
            }
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# 💬 Instagram Comments Scraper — Fast, Clean & No Login\n\n## 💬 What does Instagram Comments Scraper do?\n\nPaste one or more public Instagram post or Reel URLs. Get fast, clean, unique,\nand structured comment rows with text, public author details, dates, likes, and\nstable IDs. Turn on **Include replies** to collect replies with parent links.\n\nSkip manual copy-and-paste. Choose a clear per-post limit or collect until the\npublic feed ends, sort the sample, add optional dates, and export organized rows.\n\nUse it for social listening, brand monitoring, creator research, customer\nfeedback, academic research, spreadsheets, AI work, and data pipelines. Each\nsaved result is one public comment or reply. Empty or unavailable posts do not\nmake fake dataset rows.\n\nThe Actor uses logged-out public Instagram pages. It does not need your\nInstagram account, cookies, API key, or copied browser session. It does not\nopen private posts or bypass access controls.\n\nWith Instagram Comments Scraper, you can:\n\n- 💬 Collect public comments and optional replies from posts, Reels, and old TV URLs.\n- 👤 Save public usernames, verification flags, and stable author IDs.\n- ❤️ Collect public comment likes and reply totals when Instagram shows them.\n- 🆔 Join data with stable post, short code, and comment IDs.\n- 🎯 Set a positive comment limit for each post, or remove it.\n- ↕️ Keep Instagram's default order, or sort the collected sample by date.\n- 📅 Save only comments inside an optional date range.\n- 🧹 Get unique rows with one stable field shape.\n- 📦 Export JSON, JSONL, CSV, Excel, XML, RSS, or HTML.\n- 🔁 Use the Apify API, SDKs, webhooks, schedules, and integrations.\n\nEach paid result is one unique public comment or reply saved to the default\ndataset. Invalid, unavailable, empty, and duplicate results do not create paid\ncomment rows.\n\n## ✨ Why use this Actor?\n\n- 🪄 **Easy setup:** paste public post URLs, choose a limit, an order, and optional dates.\n- 🔓 **No login:** no Instagram account, cookie, or browser session is needed.\n- 🧹 **Clean, structured rows:** one unique comment or reply per result.\n- 🆔 **Strict identity:** each row stays tied to the requested post short code.\n- 🎛️ **Visible limits:** choose a positive row limit per post or collect until the public feed ends.\n- 🚦 **Honest results:** the public feed may return fewer rows, and `OUTPUT` gives a clear reason.\n- 💸 **Clear billing:** pay only for unique comments and replies saved to the dataset.\n\n## 📦 What data do I get?\n\nEach dataset row is one public Instagram comment or reply.\n\n| Data group         | Main fields                                         |\n| ------------------ | --------------------------------------------------- |\n| 🔗 Post identity   | `postId`, `postShortCode`, `postUrl`                |\n| 💬 Comment         | `commentId`, `text`, `createdAt`                    |\n| ↩️ Reply link      | `isReply`, `parentCommentId`                         |\n| ❤️ Public signals  | `likesCount`, `repliesCount`                        |\n| 👤 Public author   | `ownerId`, `ownerUsername`, `ownerVerified`         |\n| 🕒 Collection time | `collectedAt`                                       |\n\nOptional values that Instagram does not expose stay `null`. They are not\nguessed and are not replaced with fake zeros.\n\n`repliesCount` is the public reply total shown for a top-level comment when it\nis available. `isReply` is true for replies. `parentCommentId` links a reply\nto its saved parent and is null for top-level comments.\n\n## ⚙️ Can I use this Actor through an API?\n\nYes. You can use:\n\n- 🔌 Apify API\n- 🐍 Python SDK\n- 🟢 JavaScript SDK\n- 🪝 Webhooks\n- ⏰ Scheduled runs\n- 🧩 Apify integrations\n\nThis makes it easy to send comments into spreadsheets, databases, dashboards,\nAI analysis tools, customer-feedback systems, and research pipelines.\n\n### 🔌 API example\n\nKeep your Apify token in an environment variable or secret store.\n\n```bash\ncurl -X POST \\\n  \"https://api.apify.com/v2/acts/chronometrica~instagram-comments-scraper/runs?token=$APIFY_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"postUrls\": [\"https://www.instagram.com/reel/DZu6dkVyImf/\"],\n    \"maxCommentsPerPost\": 100,\n    \"collectAllAvailable\": false,\n    \"commentSortMode\": \"default\",\n    \"includeReplies\": false,\n    \"maxRepliesPerComment\": 10\n  }'\n```\n\n## 🎯 Why scrape Instagram comments?\n\n| Use case                  | How comment data helps                                           |\n| ------------------------- | ---------------------------------------------------------------- |\n| 📣 Brand monitoring       | Find public praise, complaints, questions, and product feedback. |\n| 🧑‍🎨 Creator research       | Review the public words around known creator posts.              |\n| 🚀 Campaign research      | Study public response to a launch, ad, event, or partnership.    |\n| 🔎 Social listening       | Track common topics and language in public discussions.          |\n| 🧑‍🔬 Academic research      | Build structured public text samples for analysis.               |\n| 🤖 AI and NLP             | Feed clean comment text into topic or sentiment tools.           |\n| 🧱 Data pipeline building | Load stable rows into a spreadsheet, app, database, or warehouse. |\n\nThe Actor gives you public source data. It does not add sentiment labels or\nguess a person's intent.\n\n## 💵 Pricing\n\nThe price depends on your Apify pricing tier. Each result charge represents one\nunique comment or reply saved to the default dataset. Empty, unavailable, and\nduplicate comments do not create comment result charges.\n\n| Apify tier | Price per comment | Price per 1,000 comments |\n| --- | ---: | ---: |\n| Free | `$0.0020` | $2.00 |\n| Bronze | `$0.0015` | $1.50 |\n| Silver | `$0.0014` | $1.40 |\n| Gold, Platinum, or Diamond | `$0.0013` | $1.30 |\n\nThere is no start fee or minimum run charge.\n\nUse `maxCommentsPerPost` to limit top-level comments and `maxRepliesPerComment`\nto limit replies under each saved parent. Replies are extra paid rows. Begin with 20 to 100 comments while testing a new workflow. Turn on\n`collectAllAvailable` only when you accept a larger and less predictable bill.\n\n## 🚀 How do I use Instagram Comments Scraper?\n\n1. Open **Instagram Comments Scraper** in Apify Console.\n2. Paste one or more public Instagram post or Reel URLs.\n3. Choose the maximum comments to save for each post.\n4. Keep the default order or choose newest-first or oldest-first with optional dates.\n5. Click **Start**.\n6. Open **Output** to inspect the rows and run summary.\n7. Download the dataset or send it to another tool.\n\n## ⬇️ Input\n\n```json\n{\n  \"postUrls\": [\"https://www.instagram.com/reel/DZu6dkVyImf/\"],\n  \"maxCommentsPerPost\": 100,\n  \"collectAllAvailable\": false,\n  \"commentSortMode\": \"default\",\n  \"includeReplies\": false,\n  \"maxRepliesPerComment\": 10\n}\n```\n\n### 🔗 Supported URLs\n\n- 🖼️ `https://www.instagram.com/p/SHORT_CODE/`\n- 🎬 `https://www.instagram.com/reel/SHORT_CODE/`\n- 📺 `https://www.instagram.com/tv/SHORT_CODE/`\n\nQuery strings are removed. Duplicate versions of the same URL are collected\nonce. Profile, hashtag, search, Story, and Explore URLs are not supported.\n\n### 🎛️ Input settings\n\n| Setting | What it controls |\n| --- | --- |\n| `postUrls` | Add one or more public Instagram post, Reel, or old TV URLs. |\n| `maxCommentsPerPost` | Save at most this many unique top-level comments for each URL. Use a positive whole number. Default: 100. Ignored when the limit is removed. |\n| `includeReplies` | Save replies under saved top-level comments. Default: false. Each reply is a separate paid result. |\n| `maxRepliesPerComment` | Maximum replies under each saved parent. Any positive whole number. Default: 10. Used only when replies are on. |\n| `collectAllAvailable` | Remove the top-level limit and stream comments until the public feed ends, time runs out, or the source fails. The reply limit still applies. Use Default order. Off by default and may cost much more. |\n| `commentSortMode` | Keep Instagram's order, or sort the collected public sample with newest or oldest comments first. Default: Instagram's order. |\n| `commentsFrom` | Only save comments on or after this date. Optional. |\n| `commentsUntil` | Only save comments on or before this date. Optional. |\n\nDates are inclusive. A comment without a public date is skipped when either\ndate setting is used. Instagram chooses the public sample. Default keeps the\nsource order. The date options sort that sample; they do not ask Instagram for\na different comment feed. Replies are collected only under saved parents and\nmust also pass the date filters. The remove-limit switch removes the top-level\nlimit; the separate reply limit still applies.\n\nTo include replies:\n\n```json\n{\n  \"postUrls\": [\"https://www.instagram.com/p/CfhVcINpHiY/\"],\n  \"maxCommentsPerPost\": 20,\n  \"includeReplies\": true,\n  \"maxRepliesPerComment\": 10\n}\n```\n\n## ⬆️ Output sample\n\n```json\n{\n  \"postUrl\": \"https://www.instagram.com/reel/DZu6dkVyImf/\",\n  \"postId\": \"3922329444068919711\",\n  \"postShortCode\": \"DZu6dkVyImf\",\n  \"commentId\": \"18000000000000000\",\n  \"isReply\": false,\n  \"parentCommentId\": null,\n  \"text\": \"Example public comment\",\n  \"createdAt\": \"2026-07-14T12:00:00.000Z\",\n  \"likesCount\": 12,\n  \"repliesCount\": 3,\n  \"ownerId\": \"123456789\",\n  \"ownerUsername\": \"example_user\",\n  \"ownerVerified\": false,\n  \"collectedAt\": \"2026-07-14T16:00:00.000Z\"\n}\n```\n\n### 📊 Run summary\n\nThe `OUTPUT` record includes:\n\n- 🎯 Posts requested, successful, empty, and failed;\n- 💬 Total rows, top-level comments, and replies saved;\n- ↩️ Reply threads that failed or were skipped after a source error;\n- 🧢 Posts that reached the chosen limit;\n- 🎛️ The chosen per-post limit, remove-limit switch, order, and optional dates;\n- 🚦 A clear result and stop reason for each input URL.\n\nCommon target results are:\n\n| Result | Meaning |\n| --- | --- |\n| `capped` | The Actor saved the chosen per-post limit. |\n| `sample` | The Actor saved a useful sample below the limit. |\n| `source_exhausted` | The public feed ended before the limit. |\n| `unavailable_or_no_public_data` | Instagram did not expose a public comment feed for that view. |\n| `failed` | A temporary target error stopped that URL. |\n\nAn empty dataset does not always mean the post has no comments. Instagram may\nshow a page but leave the logged-out comment feed empty. Check `OUTPUT`, then\nretry later if the post is public and comments are visible in your browser.\n\n## 🔒 Source boundary\n\nInstagram Comments Scraper uses logged-out public Instagram data only.\n\nIt does not:\n\n- 🔑 Ask for your Instagram username or password;\n- 🍪 Use your account, cookies, or copied session;\n- 🔒 Collect private, followers-only, or login-only posts;\n- 🧩 Solve access challenges or bypass access controls;\n- 🔎 Discover posts from profiles, hashtags, search, or Explore;\n- ♾️ Promise every comment in Instagram's displayed total.\n\n## ⚠️ Limits and interpretation\n\n- Instagram controls which comments are visible to a logged-out viewer.\n- The same post can return a different public sample on another run.\n- A displayed comment total can be higher than the public rows available.\n- `maxCommentsPerPost` is a maximum, not a promise.\n- Date filters and oldest-first order inspect at most 250 public comments per post unless the result limit is removed.\n- Comment order applies to the collected sample, not every comment on Instagram.\n- Deleted, hidden, filtered, region-limited, or moderated comments may be absent.\n- Comment text, likes, reply totals, and author details can change.\n- This Actor is not affiliated with Instagram or Meta.\n\n## ❓ FAQ\n\n### Does this Actor need an Instagram login, cookie, or API key?\n\nNo. It uses public logged-out Instagram pages.\n\n### Why did I get fewer comments than the displayed total?\n\nInstagram's displayed total and logged-out public feed can differ. The public\nfeed may end early or change between runs. Check each target in `OUTPUT`.\n\n### Can I collect replies?\n\nYes. Turn on `includeReplies` and choose `maxRepliesPerComment`. Replies do not\nuse the top-level comment limit. Each reply has its own `commentId`, with\n`isReply: true` and `parentCommentId` set to its saved parent. Public reply\naccess can vary. A partial target and reply failure counts identify incomplete\nreply collection in `OUTPUT`.\n\n### How do date filters and comment order work?\n\nThe Actor filters and sorts the public sample it collected. Dates include the\nwhole chosen day. Instagram can expose a different sample on a later run.\n\n### How are duplicates removed?\n\nDuplicate input URLs are collected once. Saved rows use the post short code and\nInstagram comment ID as the run key.\n\n### What happens when a post returns no public comments?\n\nThe target appears in `OUTPUT`. It does not create a fake comment row.\n\n### Can I remove the comment limit?\n\nYes. Turn on `collectAllAvailable`. The Actor then ignores the numeric limit\nand streams rows until Instagram's public feed ends, the run times out, or the\nsource fails. Use Default comment order with this switch. This can take longer\nand cost much more. It still cannot promise comments that Instagram does not\nexpose publicly.\n\n### Can I paste an Instagram profile URL?\n\nNo. Use known post, Reel, or old TV URLs. This Actor does not discover posts\nfrom profiles.\n\n## 🏆 Best practices\n\n- 🎯 Start with 20 to 100 comments per post.\n- 📚 Batch several known URLs in one run to lower run overhead per row.\n- 🧾 Check `OUTPUT` before treating a small or empty dataset as a bug.\n- 🆔 Join and deduplicate later work with `postShortCode` and `commentId`.\n- 🔁 Use scheduled runs when you want to observe public comment changes.\n\n## 🛟 Support\n\nFor help, include the Apify run ID, one public input URL, what you expected, and\nthe target result shown in `OUTPUT`. Do not send Instagram passwords, cookies,\nsession data, or private links.\n\n## ⚖️ Responsible use\n\nThis Actor collects data that Instagram exposes to logged-out public viewers at\nrun time. You are responsible for using the data lawfully and for following\nprivacy, data-protection, research, and platform rules. Do not use public\ncomments to harass people, infer sensitive traits, or make high-impact choices\nabout individuals.\n\n## 🔗 Related social media scrapers\n\nContinue the same workflow on this platform or compare public data across\nplatforms.\n\n### Continue on Instagram\n\n- [Instagram Profile Scraper](https://apify.com/chronometrica/instagram-channel-scraper)\n  — collect public profile details, links, and audience stats.\n- [Instagram Search Scraper](https://apify.com/chronometrica/instagram-search-scraper)\n  — find public Reels and metrics by keyword.\n- [Instagram Metrics Scraper](https://apify.com/chronometrica/instagram-metrics-scraper)\n  — collect public post, Reel, carousel, profile, and collaboration metrics.\n\n### Compare comments across platforms\n\n- [Facebook Comments Scraper](https://apify.com/chronometrica/facebook-comments-scraper)\n  — collect public comments, replies, authors, dates, and reactions.\n- [TikTok Comments Scraper](https://apify.com/chronometrica/tiktok-comments-scraper)\n  — collect public comments, replies, authors, likes, and thread links.\n- [YouTube Comments Scraper](https://apify.com/chronometrica/youtube-comments-scraper)\n  — collect public comments, replies, authors, likes, pins, and creator\n  hearts.\n- [Reddit Comments Scraper](https://apify.com/chronometrica/reddit-comments-scraper)\n  — collect public thread comments, replies, authors, scores, and dates.\n- [Snapchat Comments Scraper](https://apify.com/chronometrica/snapchat-comments-scraper)\n  — collect public comments and replies from Snapchat Spotlight posts.\n- [LinkedIn Comments Scraper](https://apify.com/chronometrica/linkedin-comments-scraper)\n  — collect public comments, replies, authors, dates, and reactions.\n",
      "changelog": "# Changelog\n\n## September 2026\n\n- Improved comment reliability when Instagram briefly returns no results.\n\n## July 2026\n\n- First public release with comment limits, date filters, and comment ordering.\n"
    },
    "buildNumber": "0.1.23",
    "imageDigest": "7e2f37c53f3f04ba197259d9a07983f8bbd401ecaa215a4a828c86961e503258",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "release-candidate",
      "versionNumber": "0.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.02537
    }
  }
}