# Reddit Comment Scraper | Replies & Monitoring (`newbs/reddit-comment-scraper`) Actor

Scrape Reddit comments and nested replies with authors, scores, timestamps, permalinks and thread context. Monitor new comments without duplicate result charges. Export JSON, CSV or Excel; connect through the API, n8n or Apify MCP. Start with a 10-comment test.

- **URL**: https://apify.com/newbs/reddit-comment-scraper.md
- **Developed by:** [Newbs](https://apify.com/newbs) (community)
- **Categories:** Social media, AI, Automation
- **Features:** Limited permissions
- **Stats:** 102 total users, 4 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 comments

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

### What does Reddit Comment Scraper do?

**Extract Reddit comments and nested replies** from public [Reddit](https://www.reddit.com/) post URLs into JSON, CSV or Excel. Get comment text, author, score, timestamp, permalink, parent ID, reply depth and post context. No Reddit API key or login is required.

Use it for **product feedback, sentiment analysis, customer research and Reddit comment monitoring**. Run it from the input form, through the Apify API, or in n8n and AI-agent workflows.

**Try 10 comments first:** paste a post URL, click **Start**, then open the dataset. Ten saved comments cost $0.06 in result charges, plus the start event and platform usage. Increase the limit after checking your results.

### What you can do

- Analyze product feedback, complaints, feature requests, and customer language.
- Alert on new Reddit comments from Apify Schedules, webhooks, n8n, Make, Zapier, or Pipedream.
- Export available reply chains for sentiment analysis and topic classification.
- Build Reddit datasets for AI agents, RAG pipelines, and research.
- Collect AMA questions and identify replies written by the original post author.
- Export results as JSON, CSV, Excel, XML, or RSS through Apify.

### Quick start

1. Add one or more direct Reddit post URLs.
2. Keep **Maximum Comments** at 10 for your first run.
3. Choose whether to include replies and how deep to follow them.
4. Run the Actor and open the **Comment rows** output.

Example input:

```json
{
  "postUrls": [
    "https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"
  ],
  "maxComments": 10,
  "includeReplies": true,
  "maxCommentDepth": 20,
  "sortBy": "top",
  "maxConcurrency": 2
}
```

The Actor accepts standard `reddit.com`, `old.reddit.com`, and short `redd.it` post links. Subreddit listing pages and Reddit search pages are not supported.

### Input

| Field | Default | Description |
| --- | ---: | --- |
| `postUrls` | Required | Direct public Reddit post URLs |
| `onlyNewComments` | `false` | Persist state and save only comments not seen by earlier runs |
| `monitoringKey` | `default` | Stable name that isolates one recurring monitor |
| `sinceTimestamp` | Empty | Skip comments older than this ISO 8601 timestamp |
| `monitoringScanLimit` | `100` | Recent comments inspected per post when filtering or monitoring |
| `maxComments` | `10` | Maximum saved comments per post, including replies |
| `includeReplies` | `true` | Include nested replies |
| `maxCommentDepth` | `20` | Deepest reply level to save; `0` means top-level only |
| `sortBy` | `top` | `top`, `best`, `new`, `controversial`, `old`, or `qa` |
| `maxConcurrency` | `2` | Posts processed in parallel, from 1 to 4 |
| `proxy` | Residential | Proxy used by both HTTP and browser collection |
| `mcpOutputConnectors` | Empty | Optional Apify MCP destinations for a run summary |

`maxComments` applies to each post. For example, two URLs with `maxComments: 10` can save up to 20 paid comment rows.

### Monitor only new comments

Use this input in an Apify Schedule or automation:

```json
{
  "postUrls": [
    "https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"
  ],
  "onlyNewComments": true,
  "monitoringKey": "customer-feedback",
  "monitoringScanLimit": 100,
  "maxComments": 10,
  "includeReplies": true,
  "sortBy": "new"
}
```

The first run saves up to 10 unseen comments. Later runs with the same `monitoringKey` and post URL save comments whose IDs are not in the monitor's saved history. Unseen rows beyond the output or spending limit remain eligible for later runs. Already-seen rows are skipped before billing. Change the key to start a separate history.

Use `sortBy: "new"` to prioritize recent discussion and `sinceTimestamp` to exclude older history. Reddit's tree order does not guarantee a global timestamp order across nested replies. The Actor scans up to `monitoringScanLimit` comments and remembers the latest 20,000 saved IDs per post and key. Increase the scan limit for busy threads and avoid overlapping runs of the same monitor. Older IDs outside that history can be returned again.

Monitoring state is stored in `newbs-reddit-comment-monitor-state` in your Apify account. Use the same post URL across scheduled runs. A run with no unseen comments reports `no-new-comments`; it still incurs start and platform usage charges.

### Output

Each dataset item is one comment or reply. The flat format works directly with spreadsheets, databases, BI tools, and AI workflows.

```json
{
  "postUrl": "https://www.reddit.com/r/example/comments/abc123/example_post/",
  "postId": "t3_abc123",
  "postTitle": "Example post",
  "postAuthor": "original_poster",
  "postScore": 123,
  "postText": "Post body when available",
  "postCreatedAt": "2026-07-20T08:00:00.000Z",
  "subreddit": "example",
  "commentId": "t1_def456",
  "parentCommentId": "t3_abc123",
  "commentAuthor": "commenter",
  "commentText": "Example comment",
  "commentScore": 42,
  "commentPermalink": "https://www.reddit.com/r/example/comments/abc123/example_post/def456/",
  "commentTimestamp": "2026-07-20T09:00:00.000Z",
  "commentDepth": 0,
  "commentPath": "0",
  "parentPath": null,
  "isTopLevel": true,
  "isPostAuthor": false,
  "replyCount": 3,
  "scrapeSource": "reddit-json",
  "scrapedAt": "2026-07-28T10:00:00.000Z"
}
```

Reddit does not expose every field on every page. Fields such as score, permalink, or post body can be `null` when they are unavailable.

The Actor also writes an `OUTPUT` run summary with per-post status, scanned/new/skipped counts, monitoring state, collection source, duration, and an explanation when a post returns no rows. A successful monitor with no updates reports `no-new-comments` instead of looking like a scraping failure.

### Pricing

The Actor uses pay-per-event pricing:

- **$0.006 per saved comment**
- **$0.00005 when the Actor starts**
- Apify platform usage can also apply as shown in the Console pricing estimate

Estimated result charges:

| Saved comments | Result charge |
| ---: | ---: |
| 10 | $0.06 |
| 100 | $0.60 |
| 500 | $3.00 |

You are charged only for rows successfully saved under the `comment` event. The Actor respects the maximum run cost configured by the user and stops gracefully when that limit is reached.

### Ready-to-run examples

- [Monitor new Reddit comments and replies](https://apify.com/newbs/reddit-comment-scraper/examples/monitor-new-reddit-comments-and-replies?fpr=nmao3)
- [Analyze Reddit product feedback](https://apify.com/newbs/reddit-comment-scraper/examples/analyze-reddit-product-feedback?fpr=nmao3)
- [Find SaaS pain points on Reddit](https://apify.com/newbs/reddit-comment-scraper/examples/find-saas-pain-points-on-reddit?fpr=nmao3)
- [Export comments for sentiment analysis](https://apify.com/newbs/reddit-comment-scraper/examples/export-reddit-comments-for-sentiment-analysis?fpr=nmao3)
- [Analyze game launch feedback](https://apify.com/newbs/reddit-comment-scraper/examples/analyze-game-launch-feedback-reddit?fpr=nmao3)
- [Collect Reddit AMA questions](https://apify.com/newbs/reddit-comment-scraper/examples/collect-reddit-ama-questions?fpr=nmao3)
- [Research competitor discussions](https://apify.com/newbs/reddit-comment-scraper/examples/research-competitor-discussions-on-reddit?fpr=nmao3)
- [Extract customer complaints](https://apify.com/newbs/reddit-comment-scraper/examples/summarize-customer-complaints-from-reddit?fpr=nmao3)
- [Build a Reddit dataset for AI](https://apify.com/newbs/reddit-comment-scraper/examples/build-reddit-thread-dataset-for-ai?fpr=nmao3)

### API

JavaScript:

```javascript
import { ApifyClient } from "apify-client";

const apifyClient = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await apifyClient.actor("newbs/reddit-comment-scraper").call({
  postUrls: [
    "https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"
  ],
  maxComments: 10,
  includeReplies: true,
  maxCommentDepth: 20,
  sortBy: "top"
}, { maxTotalChargeUsd: 1 });

const { items } = await apifyClient.dataset(run.defaultDatasetId).listItems();
```

Synchronous HTTP API:

```text
POST https://api.apify.com/v2/acts/newbs~reddit-comment-scraper/run-sync-get-dataset-items
```

Send the JSON input as the request body with `Authorization: Bearer YOUR_APIFY_TOKEN`. For larger runs, use the asynchronous run endpoint and retrieve the dataset after completion.

Python:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("newbs/reddit-comment-scraper").call(run_input={
    "postUrls": ["https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"],
    "maxComments": 10,
    "includeReplies": True,
})
for comment in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(comment["commentText"])
```

### Automation and AI

#### Apify MCP

Select this Actor in Apify's hosted MCP server or use:

```text
https://mcp.apify.com?tools=newbs/reddit-comment-scraper
```

The input, output, and dataset schemas let AI agents discover the tool and understand its result fields. Optional MCP output connectors can send a compact run summary and dataset link to an authenticated destination without exposing destination credentials to the Actor.

### Use with n8n

Use the official Apify node and choose **Run an Actor and Get Dataset**:

1. Set Actor ID to `newbs/reddit-comment-scraper`.
2. Pass the same JSON input shown above.
3. Send returned rows to Google Sheets, Slack, Notion, Airtable, a database, or an AI node.

Start from the [monitoring example](https://apify.com/newbs/reddit-comment-scraper/examples/monitor-new-reddit-comments-and-replies) for recurring runs, or the [sentiment analysis example](https://apify.com/newbs/reddit-comment-scraper/examples/export-reddit-comments-for-sentiment-analysis) for a one-time export. The same input fields work in the official Apify n8n node.

Download a starter workflow and import its JSON into n8n. Select your Apify credentials and replace the sample URL before running:

- [Clean comment export](https://api.apify.com/v2/key-value-stores/PFoOrwBEciq6Tkg4J/records/n8n-workflows-reddit-comments-clean-export)
- [Find pain-point keywords](https://api.apify.com/v2/key-value-stores/PFoOrwBEciq6Tkg4J/records/n8n-workflows-reddit-pain-point-keywords)
- [Calculate thread metrics](https://api.apify.com/v2/key-value-stores/PFoOrwBEciq6Tkg4J/records/n8n-workflows-reddit-thread-metrics)

### Reliability and limitations

- Public Reddit posts only; private, quarantined, age-gated, or removed content may be unavailable.
- Deleted and removed comment bodies are skipped. Accessible replies beneath those comments are retained; their parent ID may refer to a row absent from the export.
- Collection tries JSON with bounded comment expansion, then static HTML, JSON within an established browser session, and browser page expansion. If expansion fails, recovered comments are preserved. Reddit can still withhold comments; a result limit is a cap, not a guarantee of that many available rows.
- `maxCommentDepth` and `maxComments` intentionally limit the saved result set.
- Residential proxy traffic costs more than datacenter traffic but currently gives the best Reddit success rate.

### Frequently asked questions

#### Can I export more than 500 comments?

Set `maxComments` up to 5,000 per post. The Actor follows available JSON continuation IDs in batches of up to 100 and uses browser expansion when needed. Actual coverage depends on what Reddit exposes, reply depth, runtime and your spending limit.

#### Why did I get fewer comments than requested?

Check the **Run summary**. Comments may be deleted, filtered by depth or time, already saved by your monitor, or inaccessible. A `partial` result preserves available comments when further collection fails. Run-level failure is reported when all requested posts fail.

#### Can I search Reddit or scrape an entire subreddit?

This Actor accepts direct post URLs. Use another discovery step to find posts, then send their URLs here for comment extraction.

#### How do I prevent duplicate charges?

Duplicate comment IDs and alternate URLs for the same post are removed within a run. For repeated runs, enable `onlyNewComments`, keep the same `monitoringKey` and post URL, and follow the monitoring history limits above.

### Support

For a failed or empty source, first open the run's **Run summary** output. It identifies the affected URL and explains whether the post was empty, unavailable, blocked, or stopped by a spending limit.

If the problem persists, open an issue on the Actor page and include the run ID and a public example URL. Do not include API tokens or proxy credentials.

### Changelog

#### September 15, 2026

- Added HTTP continuation requests, static HTML collection, and structured JSON collection within browser sessions.
- Preserved accessible replies below deleted parents and recovered comments after failed expansion.
- Applied reply-depth filtering before result limits and deduplicated alternate post URLs.
- Batched dataset writes while retaining spending-limit checks and matching comment charges.
- Fixed monitoring that could discard unseen comments after a timestamp cutoff.
- Added clearer partial/failure reporting and runnable Python and JavaScript examples.
- Added a verified Chrome installation to the container build and updated Browserslist to 4.28.9.

#### September 1, 2026

- Added persistent `onlyNewComments` monitoring with per-thread deduplication.
- Added `sinceTimestamp`, isolated monitoring keys, and a separate scan limit for busy threads.
- Added `no-new-comments` run summaries with scanned, new, and skipped row counts.
- Switched the fast collector to Reddit's working structured endpoint to avoid browser startup on common runs.
- Upgraded the runtime to Node 22, Crawlee 3.18, and Puppeteer 25.
- Reduced the first-run default from 25 to 10 comments for tighter cost control.
- Added a ready-to-run Reddit comment monitoring task and updated the n8n Slack monitor workflow.

#### July 2026

- Added HTTP-first collection that skips browser startup when possible.
- Kept automatic browser fallback for blocked or incomplete JSON responses.
- Added canonical support for reddit.com variants and redd.it links.
- Added comment score, permalink, parent ID, original-poster flag, post text, and collection source.
- Added maximum reply depth.
- Added a visible per-post run summary for empty and failed sources.
- Reduced the first-run default from 500 to 25 comments for clearer cost control.

# Actor input Schema

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

Paste direct public post URLs from Reddit, old.reddit.com or redd.it. Alternate links to the same post are processed once per run. Subreddit and search pages are not supported.

## `onlyNewComments` (type: `boolean`):

Save only comment IDs not remembered from earlier runs with the same Monitoring Key. Unseen comments beyond the result limit remain eligible next time. Use sortBy=new for monitoring and sinceTimestamp to exclude older history.

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

Stable name that isolates one monitor from another. Keep the same key across scheduled runs. Change it to start a fresh monitoring history.

## `sinceTimestamp` (type: `string`):

Optional ISO 8601 timestamp. Comments older than this time are skipped and never charged. Example: 2026-09-01T00:00:00.000Z.

## `monitoringScanLimit` (type: `integer`):

How many recent comments to inspect when monitoring or filtering by time. This can be higher than Maximum Comments so already-seen rows do not hide new replies.

## `maxComments` (type: `integer`):

Maximum saved comments per post, including replies. This caps pay-per-event result charges. Start with 10, then increase after checking the output.

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

Collect nested replies and preserve their parent-child thread structure. Disable this to collect top-level comments only.

## `maxCommentDepth` (type: `integer`):

Deepest reply level to save. Use 0 for top-level comments only, 1 for direct replies, or 20 for all available levels.

## `sortBy` (type: `string`):

How to sort comments before collection. This affects which comments are collected when using maxComments limit.

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

Maximum number of Reddit posts to process at the same time. Increase for faster runs, lower it if Reddit blocks requests.

## `proxy` (type: `object`):

Residential proxies provide the best Reddit success rate. Keep the default unless you have tested another proxy configuration.

## `mcpOutputConnectors` (type: `array`):

Optional Apify MCP connectors used after scraping to send a compact run summary and dataset link to an external tool such as Slack, Notion, GitHub, or another MCP-compatible destination.

## `mcpToolName` (type: `string`):

Optional exact MCP tool name to call on each selected output connector. Leave empty to auto-select the first output-writing tool exposed by the connector.

## `mcpToolArguments` (type: `object`):

Optional JSON object merged into the MCP tool call. Use this for required destination fields such as channel, channel_id, database_id, repository, or page_id.

## `mcpMessageTemplate` (type: `string`):

Optional message template sent to MCP output tools. Supported tokens: {{rowsPushed}}, {{postsProcessed}}, {{datasetUrl}}, {{datasetApiUrl}}, {{runUrl}}, {{postUrls}}, {{sortBy}}, {{includeReplies}}.

## `failOnMcpDeliveryError` (type: `boolean`):

When enabled, the run fails if connector delivery fails. Keep disabled to preserve scraped dataset results even if a destination tool needs different arguments.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"
  ],
  "onlyNewComments": false,
  "monitoringKey": "default",
  "monitoringScanLimit": 100,
  "maxComments": 10,
  "includeReplies": true,
  "maxCommentDepth": 20,
  "sortBy": "top",
  "maxConcurrency": 2,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "mcpOutputConnectors": [],
  "mcpToolArguments": {},
  "failOnMcpDeliveryError": false
}
```

# Actor output Schema

## `comments` (type: `string`):

Default dataset items. Each row contains one Reddit comment or reply with post metadata and thread-position fields.

## `runSummary` (type: `string`):

Per-post status, scanned/new/skipped row counts, monitoring state, collection source, duration, and explanations for empty or failed sources.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "postUrls": [
        "https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"
    ],
    "monitoringKey": "default",
    "monitoringScanLimit": 100,
    "maxComments": 10,
    "maxCommentDepth": 20,
    "sortBy": "top",
    "maxConcurrency": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("newbs/reddit-comment-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "postUrls": ["https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"],
    "monitoringKey": "default",
    "monitoringScanLimit": 100,
    "maxComments": 10,
    "maxCommentDepth": 20,
    "sortBy": "top",
    "maxConcurrency": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("newbs/reddit-comment-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "postUrls": [
    "https://www.reddit.com/r/AskReddit/comments/ovihp9/what_city_would_you_never_ever_ever_live_in/"
  ],
  "monitoringKey": "default",
  "monitoringScanLimit": 100,
  "maxComments": 10,
  "maxCommentDepth": 20,
  "sortBy": "top",
  "maxConcurrency": 2
}' |
apify call newbs/reddit-comment-scraper --silent --output-dataset

```

## MCP server setup

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