# Reddit Post Comments Scraper — Thread, Depth, Karma (`foxlabs/reddit-post-comments-scraper`) Actor

Every comment of any public Reddit post, not just the first page: the actor walks Reddit's own more-comments loaders down the thread. Every row carries score, depth, parent, text, author, exact time and permalink. Pick the thread order, cap the depth, add author karma. No login, pay per comment.

- **URL**: https://apify.com/foxlabs/reddit-post-comments-scraper.md
- **Developed by:** [Berkan Kaplan](https://apify.com/foxlabs) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 2 monthly users, 64.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 comments

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Reddit Post Comments Scraper — Full Thread with Depth & Karma 🚀

**foXLabs Reddit series:** [Search](https://apify.com/foxlabs/reddit-search-scraper) · [Subreddit Posts](https://apify.com/foxlabs/reddit-subreddit-posts-scraper) · [Post Details](https://apify.com/foxlabs/reddit-post-details-scraper) · [User](https://apify.com/foxlabs/reddit-user-scraper)

🎉 The comments of any public Reddit post, as Reddit shows them to a signed-out visitor: every comment with its **text, author, exact time, permalink, score, depth, the parent it answers and the OP/moderator marks** — the Actor walks Reddit's own "more comments" loaders, so a reply from the bottom of the tree is as complete as the top comment (measured: **1,500 comments of a 3,503-comment thread, those fields 100 % filled**). **Each author's karma and account age** on request. The post's own row comes first on request. Authors can be stable codes for name-free analyses. No login, no cookies of yours, no CAPTCHA solving.

### 🔍 What is the Reddit Post Comments Scraper — and when should you use it?

Give this Actor Reddit post URLs and it returns their comments as clean rows — the whole tree in the order you choose, each row with its thread depth, the parent it answers, its score and its text.

**Use it when you need:** the comments of a post as data — the top of the thread with its structure and scores, and the breadth of the thread for sentiment or text mining; author karma per comment on request.

**Use something else when:** you want the post records only → [Post Details](https://apify.com/foxlabs/reddit-post-details-scraper); to discover posts → [Search](https://apify.com/foxlabs/reddit-search-scraper) / [Subreddit Posts](https://apify.com/foxlabs/reddit-subreddit-posts-scraper).

### 🤖 Use with AI agents

**Already on the Apify MCP server?** Ask for this Actor by name: `foxlabs/reddit-post-comments-scraper`. An agent can discover it, run it and read the dataset over MCP.

**Real-time Standby API.** The Reddit family ships Standby endpoints so an agent can fetch on demand; this Actor delivers full threads in batch and the family's Standby mode is prepared for live use (same events).

Otherwise paste this into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```
I want a Reddit post's full comment thread using the Apify Actor
`foxlabs/reddit-post-comments-scraper`.

Input: `postUrls` is a list of post URLs/ids; `commentSort` is confidence/top/new/controversial/old/qa;
`includePost` adds the post row; `hideAuthors` returns codes; `minCommentScore`/`maxDepth` filter.
Each comment row has text, author, time, permalink, score, depth and the parent it answers.

Start with:
{ "postUrls": ["https://www.reddit.com/r/Python/comments/1x2j7z3/"], "maxCommentsPerPost": 500 }

Ask me which thread to read, run the Actor, then summarise the discussion.
```

The machine-readable API, MCP config and OpenAPI definition live at `apify.com/foxlabs/reddit-post-comments-scraper.md`.

### 📋 Overview

Everything you need to turn a Reddit thread into clean, structured data — the whole tree with its scores, depths and parents — in one Actor, with no login, cookies or CAPTCHA solving.

**Why teams pick this Actor:**

- ✅ **The whole thread, every row complete** — the Actor walks Reddit's own "more comments" loaders, so a comment from the bottom of the tree carries exactly what one from the top does. Measured 2026-10-17 on a 3,503-comment thread in r/AskReddit: **1,500 comments in one run, `score`, `text`, `author`, `createdAt`, `depth`, `parentId` and `url` 100 % filled, every id unique** (depths 0–3: 736 / 446 / 218 / 100).
- 🌳 **Structure preserved** — `depth`, `parentId`, `isSubmitter`, `distinguished`, `collapsed`, `removedBy`.
- 👤 **Author karma** — link/comment karma and the cake day per comment with `includeAuthorInfo` (one profile-page read per author, off unless asked).
- 🕵️ **Name-free mode** — `hideAuthors` returns a stable 16-char code.
- 💰 **Pay only for results** — `comment`/`post` events per row; filtered-out and status rows free.
- 🤖 **Agent-ready** — MCP + prepared Standby.

### ✨ Features

- 🔍 **Full thread by URL** — URL, `t3_` name or id.
- 💬 **Every comment** — text, score, controversiality, awards, exact/edit time, flags.
- 🧵 **Thread order** — `confidence` (best), `top`, `new`, `controversial`, `old`, `qa`.
- 📌 **Post row** — the post itself first with `includePost`.
- 🧹 **Filters** — `minCommentScore`, `maxDepth`; `onlyNewComments` for thread watching.

### 🎬 Quick Start

```bash
curl -X POST "https://api.apify.com/v2/acts/foxlabs~reddit-post-comments-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"postUrls": ["https://www.reddit.com/r/Python/comments/1x2j7z3/"], "maxCommentsPerPost": 500}'
```

### 🚀 Getting Started (3 steps)

1. **Paste your posts** — one per line: URL, `t3_` name or id.
2. **Pick order & cap** — `commentSort`, `maxCommentsPerPost`; `hideAuthors` for privacy.
3. **Run and export** — get a clean dataset as JSON, CSV or Excel.

### 📥 Input

| Field | Meaning |
|---|---|
| `postUrls` | one per line: a post URL, `t3_` name or id; share links (`…/s/…`) not accepted. |
| `maxCommentsPerPost` | comments per post in thread order (default 500). |
| `maxComments` | comment rows in the whole run (default 100,000). |
| `commentSort` | `confidence` (best, default), `top`, `new`, `controversial`, `old`, `qa`. |
| `includePost` | the post's own row first (default on; charged as a `post`). |
| `minCommentScore`, `maxDepth` | keep only comments at/above a score or up to a depth; the rest are skipped and not charged. |
| `includeAuthorInfo` | the author's karma and cake day — one profile-page read per author (default off). |
| `hideAuthors` | replace user names with stable codes (default off). |
| `onlyNewComments`, `listName` | remember delivered comments and skip them next time. |
| `proxyConfiguration` | nothing to change for normal use. |

```json
{ "postUrls": ["https://www.reddit.com/r/Python/comments/1x2j7z3/"], "maxCommentsPerPost": 2000, "commentSort": "top", "includePost": true }
```

### 📤 Output

One row per comment (`type: "comment"`); the post as a `type: "post"` row first with `includePost`.

| Field | What it is |
|---|---|
| `commentId`, `fullname`, `url`, `postId`, `postTitle`, `subreddit` | ids and address, the post it belongs to |
| `parentId`, `parentIsPost`, `depth` | tree position (0 = top-level) |
| `author`, `authorFlair`, `authorPremium`, `authorDeleted` | who wrote it — a stable code with `hideAuthors` |
| `text`, `score`, `controversiality`, `awardCount` | the comment and its numbers |
| `createdAt`, `editedAt` | exact times (UTC) |
| `isSubmitter`, `distinguished`, `stickied`, `locked`, `collapsed`, `removedBy` | flags |
| `authorInfo` | link/comment karma, account creation date, avatar (null for deleted) |
| `position`, `input`, `scrapedAt`, `type`, `error` | place; input line; row type / free status row |

A line that brings no thread gets a **free status row**: not a post, no such post (deleted/never existed), a private/quarantined/Premium-only subreddit, no comments, or a post named twice.

### 💼 Use cases

**1. Community sentiment** — read an entire discussion, not just the top comments.
*Input:* the post, `commentSort: top`. *Output:* every comment + author karma. *Use:* gauge reaction in depth.

**2. Thread watching** — collect only-new comments as a discussion grows.
*Input:* the post, `onlyNewComments` + `commentSort: new`, scheduled. *Output:* new comments each run. *Use:* a live thread feed.

**3. Research datasets** — structured comment trees for analysis, name-free.
*Input:* posts, `hideAuthors` on. *Output:* comments with depth + codes. *Use:* NLP/analysis within policy.

### 🔗 Integration

**JavaScript / Node.js**

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('foxlabs/reddit-post-comments-scraper').call({
  postUrls: ['https://www.reddit.com/r/Python/comments/1x2j7z3/'], maxCommentsPerPost: 500,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

**Python**

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('foxlabs/reddit-post-comments-scraper').call(
    run_input={'postUrls': ['https://www.reddit.com/r/Python/comments/1x2j7z3/'], 'maxCommentsPerPost': 500}
)
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)
```

Written for `apify-client` 3 for Python, where `call()` returns a run object; with version 1 or 2 it returns a dict — write `run['defaultDatasetId']` there.

**Automation (n8n / Zapier / Make):** schedule → HTTP request to the Actor API with your `postUrls` → handle the JSON dataset → push to a sheet, CRM or dashboard.

### 📊 Pricing

Pay per event: **`comment`** per delivered comment row (the author's record rides along free), **`post`** for the post's own row with `includePost`. Status rows are free; filtered-out comments aren't written or charged; a run Reddit doesn't answer ends FAILED and charges nothing; no start fee. [View current pricing.](https://apify.com/foxlabs/reddit-post-comments-scraper)

### ❓ FAQ

**Do I need a Reddit account, login or API key?** No — a signed-out guest token, no account, no cookies, no CAPTCHA solving.

**Does it get the whole thread?** Yes — it resolves "more comments" stubs (100 ids a request) up to `maxCommentsPerPost` or the end. Deleted/removed/collapsed comments in Reddit's count aren't delivered; the run's last word says how many weren't reached.

**Can I hide commenter names?** Yes — `hideAuthors` returns a stable 16-char code.

**Can I export to CSV / Excel / JSON?** Yes — directly from the Apify dataset.

**Are share links accepted?** No (`…/s/…`) — use the full post URL, `t3_` name or id.

### 🐛 Troubleshooting

- **Fewer comments than the post's count** — the count includes deleted/removed/collapsed comments; the run says how many weren't reached.
- **A line returns a status row** — not a post, no such post, private/Premium-only subreddit, no comments, or named twice (free).
- **Big threads are slow** — read stub by stub (100 a request); set `maxCommentsPerPost` to what you need.

**How it reads Reddit:** opens a listing as a signed-out visitor, takes the guest token, and calls Reddit's JSON API — the thread in one answer (up to 500, 10 levels), then "more comments" stubs packed 100 ids a request. Residential-only token (measured 7/7 residential, 0/8 datacenter) → Apify Proxy residential by default; four addresses rotate.

### ⚠️ Trademark

Independent, third-party tool. Reddit is a trademark of Reddit, Inc.; this Actor is not affiliated with, endorsed by or connected to Reddit. The mark is used here for identification only.

### ⚖️ Is it legal to scrape this data?

It reads only what Reddit shows anyone who is not signed in. Comment rows carry user names (public pseudonyms) and publicly posted text; `hideAuthors` replaces names with codes. You are responsible for using the data lawfully (GDPR, CCPA, Reddit's User Agreement). Nothing is stored outside your own Apify datasets. See Apify's blog post on the legality of web scraping.

### 🤝 Support & contact

- 🌐 **Website:** [data.foxlabs.com.tr](https://data.foxlabs.com.tr)
- 📧 **Email:** info@foxlabs.com.tr
- 🐛 **Issues:** open a ticket in the Actor's **Issues** tab — the run's `SOURCE_REPORT` record holds what was seen, read, delivered and why the run stopped.
- 🧰 **More clean data actors:** [Fox Labs on Apify](https://apify.com/foxlabs)

### Changelog

#### 0.3.0 — 2026-10-17

The full comment tree is back. Reddit's own web client loads the rest of a thread through hidden "more comments"
loaders, and each one is a **POST carrying its own cursor**: asked that way they answer with 4–100 further
comments, every one of them complete (score, depth, parent, body), plus the loaders of the level below.
Build 0.2 asked them as GETs — which answer "page not found" — and fell back to the thread's feed, whose rows have
no score, depth or parent. Measured 2026-10-17: **1,500 comments of a 3,503-comment thread, all of those fields
100 % filled**, 267 requests, 2 MB on the wire. `commentSort` now really sets the thread's order (the page
honours it and the loaders carry it on), and `maxDepth` stops the walk instead of filtering afterwards, so the
budget buys comments you keep. A thread with more to give says so in the run's last word instead of calling the
rest "deleted". `editedAt`, `controversiality`, `collapsed`, `locked`, `stickied`, `authorFlair` and
`authorPremium` remain `null` (Reddit's HTML does not carry them). Field names, the dataset shape and the prices
are unchanged.

#### 0.2.0 — 2026-10-17

Reddit closed its JSON API to signed-out visitors on 16 October 2026, so a thread came from its page (the post and
its first 25 comments, complete with score, depth and parent) plus the thread's own feed, whose rows said `null`
for `score`, `depth` and `parentId`. Superseded by 0.3.0.

#### 0.1.0 — 2026-10-10

- First release: full comment trees with depth, parent, flags, removed/deleted state and author karma; "more comments" stubs packed 100 ids a request; the post's own row; score and depth filters; author codes; only-new lists; free status rows; Standby API prepared.

# Changelog

This Actor's version history is a separate document: https://apify.com/foxlabs/reddit-post-comments-scraper/changelog.md

# Actor input Schema

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

One post per line: its address (https://www.reddit.com/r/python/comments/1x2jj5d/…, old.reddit.com or redd.it/1x2jj5d), its full name (t3_1x2jj5d) or its id (1x2jj5d). Share links (…/s/…) are not accepted. A post written twice is read once.

## `maxCommentsPerPost` (type: `integer`):

How many comments to deliver for each post, in the thread's order. The post's page carries its first 25; the Actor then walks Reddit's own "more comments" loaders (4–100 comments a request) until this number is reached or the thread ends. Measured: 1,500 comments of a 3,503-comment thread, score, depth and parent filled on every row.

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

The run stops when this many comment rows have been delivered. You are charged only for delivered rows.

## `commentSort` (type: `string`):

The order Reddit arranges the thread in: best (Reddit's default), top (highest score), new, controversial, old, Q\&A.

## `includePost` (type: `boolean`):

On (default): the post's own row (type "post": title, text, score, upvote ratio, comment count, media, …) comes first, charged as a post. Off: comments only.

## `minCommentScore` (type: `integer`):

Deliver only comments whose score is at least this (negative numbers allowed). Every comment carries a score, so this applies to the whole thread. Leave empty for every comment.

## `maxDepth` (type: `integer`):

Deliver only comments up to this depth: 0 = top-level comments only, 1 = their direct replies too, and so on. The walk stops there as well, so the budget is not spent on replies you filter out. Leave empty for the whole tree (Reddit's own tree folds at ten levels).

## `includeAuthorInfo` (type: `boolean`):

One request per 100 authors adds each comment's author record (link and comment karma, account creation date, avatar) as authorInfo. A deleted author gets null.

## `hideAuthors` (type: `boolean`):

Off (default): rows carry Reddit's public user names. On: each author is replaced by a stable 16-character code (the same author gets the same code in every run of your account), so you can count and link comments by author without storing names.

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

Remember delivered comments under the list name below and skip them in later runs. Schedule the same posts and each run brings only the comments it has not delivered before — a thread watcher.

## `listName` (type: `string`):

Name of the memory used by "Only comments not delivered before" (looked at only when that is on). Letters, digits and hyphens (a hyphen not first or last), up to 40 characters; capitals are read as lower case.

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

Nothing to change for normal use: the Actor reads Reddit through Apify Proxy residential addresses, the only kind Reddit hands its guest token to (measured: residential 7 of 7 sessions, datacenter 0 of 8). Set a proxy here to send every request through it instead; a setting the platform refuses ends the run before anything is read.

## Actor input object example

```json
{
  "postUrls": [
    "https://www.reddit.com/r/Python/comments/1x2j7z3/"
  ],
  "maxCommentsPerPost": 200,
  "maxComments": 100000,
  "commentSort": "confidence",
  "includePost": true,
  "includeAuthorInfo": false,
  "hideAuthors": false,
  "onlyNewComments": false,
  "listName": "default",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "postUrls": [
        "https://www.reddit.com/r/Python/comments/1x2j7z3/"
    ],
    "maxCommentsPerPost": 200,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

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

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

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

```

## Python example

```python
from apify_client import ApifyClient

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

# Prepare the Actor input
run_input = {
    "postUrls": ["https://www.reddit.com/r/Python/comments/1x2j7z3/"],
    "maxCommentsPerPost": 200,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "postUrls": [
    "https://www.reddit.com/r/Python/comments/1x2j7z3/"
  ],
  "maxCommentsPerPost": 200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call foxlabs/reddit-post-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,foxlabs/reddit-post-comments-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/clHdsWJcPccP39CVw/builds/N7x3iHV6tgwdG7PdH/openapi.json
