# Reddit Data Scraper: Posts, Comments, Users, Monitoring (`actorforgehq/reddit-data-scraper`) Actor

Scrape Reddit posts, comment trees, search results and user history as clean JSON. HTTP-level, no browser, honest documented rate limits.

- **URL**: https://apify.com/actorforgehq/reddit-data-scraper.md
- **Developed by:** [ActorForge](https://apify.com/actorforgehq) (community)
- **Categories:** Social media, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.90 / 1,000 posts

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Reddit Data Scraper: Posts, Comments, Users, Monitoring

Scrape **Reddit** as clean JSON: subreddit feeds (hot / new / top / rising), full comment threads,
keyword search, and — the part most scrapers get wrong — **user post & comment history** and
**date-range filtering**. HTTP-level, no browser: no page rendering, no scroll timeouts, no
browser-crash class of failures. Built-in polite pacing that Reddit tolerates, measured before a
single line of this Actor was written.

### What you get

The dataset contains **two kinds of item**, tagged by a `type` field: posts and comments.
Comments link back to their post via `postId`, and to their parent comment via `parentId`,
so you can rebuild the whole thread tree.

**Post:**

```json
{
  "type": "post",
  "id": "1mk2qwe",
  "subreddit": "explainlikeimfive",
  "author": "curious_user",
  "title": "ELI5: Why does ice float on water?",
  "score": 1543,
  "numComments": 214,
  "url": "https://i.redd.it/example.jpg",
  "permalink": "https://old.reddit.com/r/explainlikeimfive/comments/1mk2qwe/eli5_why_does_ice_float_on_water/",
  "domain": "i.redd.it",
  "createdUtc": "2026-08-07T14:32:05.000Z",
  "nsfw": false,
  "spoiler": false,
  "stickied": false,
  "flair": "Physics"
}
```

`selfText` (the full body of a text post) is included when the post is fetched via its comment
page — feed rows on Reddit do not carry the body, and we do not pretend they do. Posts coming
from **search** results carry a leaner field set (no `nsfw`/`spoiler`/`stickied`/`domain`),
because Reddit's search markup simply does not include them.

**Comment:**

```json
{
  "type": "comment",
  "id": "n8x1abc",
  "postId": "1mk2qwe",
  "subreddit": "explainlikeimfive",
  "author": "helpful_redditor",
  "score": 87,
  "body": "Water is one of the few substances that expands when it freezes...",
  "createdUtc": "2026-08-07T15:01:44.000Z",
  "permalink": "https://old.reddit.com/r/explainlikeimfive/comments/1mk2qwe/eli5_why_does_ice_float_on_water/n8x1abc/",
  "depth": 2,
  "parentId": "t1_n8wzdef"
}
```

Two honesty details worth knowing before you buy:

- When Reddit hides a comment's score, `score` is **absent** — we do not substitute a fake `0`.
- Deleted authors come through as `[deleted]`, exactly as Reddit shows them.

### What it can scrape

| Mode | Input | What comes out |
|---|---|---|
| **Subreddit feeds** | `subreddits` + `listingSort` (hot/new/top/rising) | Posts, paginated up to Reddit's own ~1,000-post feed ceiling |
| **Comment threads** | a post URL in `startUrls` | The post itself (with `selfText`) plus its comment tree with depths and parent links |
| **Search** | `searches`, optionally scoped with `searchCommunityName` | Matching posts, newest first — global or within one subreddit |
| **User history** | `users` | The user's public posts and comments, mixed, paginated |
| **Monitoring** | any of the above on an Apify Schedule | Frequent small runs cost exactly what they scrape — there is **no per-run start fee** |

Date filters (`postedAfter` / `postedBefore` for posts, `commentedAfter` / `commentedBefore` for
comments) apply to every mode.

### Use cases

- **Brand & keyword monitoring.** Run a search or a subreddit feed on a schedule. Because
  billing has no start fee, a 25-post check costs 25 × $0.0019 = **$0.0475 — every time, with
  no per-run surcharge**. Many scrapers in this niche charge a start fee per run (sometimes
  multiplied by memory GB), which quietly dominates the bill in exactly this scenario.
- **User research.** Pull a redditor's public post and comment history in one run — a mode that
  is notoriously unreliable across this niche.
- **Period analysis & backtesting.** `postedAfter` + `postedBefore` give you a real date window,
  not just Reddit's "past week / past month" presets.
- **Community research.** Feed sorts (hot/new/top/rising) with time filters, NSFW filtering
  off by default and flair captured per post.
- **LLM & dataset building.** Clean, typed JSON with stable ids, ISO timestamps and thread
  structure (`postId`, `parentId`, `depth`) — ready to reassemble into conversation trees.

### Input

| Field | Type | Description |
|---|---|---|
| `startUrls` | array | Reddit URLs of any supported kind: subreddit feed, post, user page, or search page. Mode is detected from each URL. |
| `subreddits` | string\[] | Subreddit names without `r/`, e.g. `["programming"]`. |
| `listingSort` | string | `hot` (default), `new`, `top`, `rising`. |
| `time` | string | Time window for `top` listings and search: `hour`, `day`, `week`, `month`, `year`, `all` (default). |
| `searches` | string\[] | Search queries. Alias: `searchTerms` — inputs written for other popular Reddit scrapers work unchanged. |
| `searchCommunityName` | string | Restrict search to one subreddit. Alias: `withinCommunity`. |
| `users` | string\[] | Usernames without `u/` — scrapes their public post/comment history. |
| `postedAfter` / `postedBefore` | string | ISO date bounds for posts. Applied **after** fetching (see Limits). |
| `commentedAfter` / `commentedBefore` | string | ISO date bounds for comments. |
| `includeNSFW` | boolean | Default `false` — NSFW posts are skipped unless you opt in. |
| `maxItems` | integer | Max items per subreddit / search query / user history (default 100, hard cap 1,000 — Reddit's own feed ceiling). Does not limit comment threads: a post URL always delivers the post plus its fetched comment page of up to 500 comments (see Limits). |
| `proxyConfiguration` | object | Defaults to Apify residential proxies; keep it that way for stable results. |

### How to use it

1. Click **Try for free** / **Start** on this page.
2. Enter subreddit names, search queries, usernames — or paste Reddit URLs directly into
   **Start URLs** (feeds, posts, user pages and search pages are all recognized).
3. Optionally set the sort, the time window, date bounds and **Max items**.
4. Run it. Posts and comments land in the dataset as separate typed rows; export as JSON, CSV,
   Excel, or pull them over the API.

To run it on a schedule, use Apify **Schedules** — this Actor's pricing has no per-run start
fee, so scheduled monitoring costs the same per item as one big run. To call it from code, use
the [Apify API](https://docs.apify.com/api/v2) or an official client.

### Rate-limit etiquette (built in, with numbers)

This Actor is deliberately polite to Reddit's servers, and the numbers are fixed in code, not
left to chance:

- **At most 10 requests per minute per IP** — a hard 6-second spacing between requests.
- On an HTTP `429`, the Actor **backs off** (3 s, then 6 s, then 9 s), rotates to a fresh proxy
  session, and retries up to 3 times. It never hammers a throttled endpoint.
- One comment page fetch retrieves up to 500 comments, so large threads cost few requests.

This pacing was measured before release: at 10 requests/minute, 100 consecutive requests
completed without a single refusal. The Actor stays inside what Reddit's own throttling
tolerates, by design — it imposes no undue burden on the target servers.

### Limits (honest)

- **~1,000 posts per feed is Reddit's ceiling, not ours.** Reddit serves at most about 1,000
  posts for any listing, and no scraper can page past that. `maxItems` is capped there.
- **Date filters do not reduce the number of requests.** Reddit has no server-side date-range
  API, so `postedAfter`/`postedBefore` filter items **after** fetching. When a date bound is set,
  items whose timestamp cannot be read are dropped rather than guessed.
- **Very deep comment branches may be incomplete.** A thread is fetched as one page of up to 500
  comments (sorted by top); branches Reddit collapses behind "load more comments" are not
  expanded in this version.
- **User-history comments arrive flat.** On a profile page Reddit does not expose thread
  position, so those comments have `depth: 0` and no `parentId`. Comments scraped from a post's
  own page carry the full tree structure.
- **Search rows carry fewer fields** than feed rows — Reddit's search markup omits NSFW/spoiler
  flags and media domains, and we output what is actually there instead of guessing.
- **A non-existent subreddit or user fails that task** (after retries) rather than silently
  returning nothing — you will see it in the run log instead of wondering where your data went.
- **No login, no captcha solving.** The Actor reads only pages Reddit serves publicly to a
  logged-out visitor. If Reddit answers with a challenge page, the Actor reports an error and
  retries on a fresh IP — it will fail honestly rather than fabricate data.
- If more than 5% of tasks in a run fail, the run log says so loudly; a run in which every
  fetch failed is marked **failed**, not "succeeded with 0 items". (A run whose filters
  legitimately match nothing — say, a strict date window — still succeeds, with an empty
  dataset and an empty bill.)

### Pricing

Pay-per-event, two events, nothing else:

| Event | Rate |
|---|---|
| `post-scraped` | **$1.90 per 1,000** ($0.0019 each) |
| `comment-scraped` | **$0.75 per 1,000** ($0.00075 each) |
| Run start | **free — there is no start event** |

Comments cost less than half a post because they are cheaper to fetch (hundreds arrive on one
page) — most competitors bill a comment at the full post price.

**What you get for $1:** ~526 posts, or ~1,333 comments, or any mix. Platform usage (compute,
proxy) is charged to us, not to you — the per-item price above is the whole bill. There is no
subscription, no minimum charge and no per-gigabyte start fee, so billing is strictly
proportional to data delivered: autonomous AI agents can call this Actor through the **Apify
MCP server** and pay per item. Rates shown as of the last README update; the Store page stays
authoritative.

### FAQ

**Do I need a Reddit account or an API key?**
No. The Actor reads only publicly available pages, never logs in, and does not solve captchas
or circumvent access controls.

**Why is there no start fee? What's the catch?**
No catch — it is a deliberate design choice. Start fees (especially per-GB ones) punish the
monitoring scenario: frequent small runs. We want scheduled monitoring to be priced exactly like
one big run, per item delivered.

**Why HTTP-level instead of a browser?**
Browser-based scrapers render and scroll pages, which makes them slow, expensive and prone to
timeouts — timeouts that some vendors' public run statistics show by the tens of thousands per
month. Fetching Reddit's server-rendered HTML avoids that entire failure class and keeps the
price low.

**I'm migrating from another Reddit scraper — do I have to rewrite my input?**
Probably not. The common field names are accepted directly (`searchTerms`, `withinCommunity`),
and `startUrls` takes the same URL-list format other actors use.

**Can I get every comment of a huge thread?**
Up to 500 comments per thread page, with full tree structure. Branches Reddit hides behind
"load more comments" are not expanded in this version — if you need exhaustive multi-thousand
comment threads, this Actor will give you the top 500 by rank, honestly labeled as such.

**Are NSFW posts included?**
Only if you set `includeNSFW: true`. The default is off.

**Where is my data stored?**
In your run's dataset on your Apify account, under your control. The Actor keeps no copy of
scraped data outside your run and sends nothing to any third party.

### Other Actors by ActorForge

- [Lazada Reviews Scraper](https://apify.com/actorforgehq/lazada-reviews-scraper) — product
  reviews, per-aspect ratings and buyer media from all six Lazada marketplaces.
- [Wildberries Scraper](https://apify.com/actorforgehq/wildberries-scraper) — products, prices
  and reviews from Wildberries as clean, schema-validated JSON.
- [Avito Real Estate Scraper](https://apify.com/actorforgehq/avito-real-estate-scraper) — full
  property inventory from Avito with freshness stamps.

Missing a Reddit surface you need? Open an issue from the Actor's page and tell us.

### Legal

This is an **unofficial** scraper. It is not affiliated with, endorsed by, or connected to
Reddit, Inc. in any way, and it does not use Reddit's developer API. It reads only pages that
Reddit serves publicly to any logged-out visitor — no login, no credentials, no captcha solving,
no circumvention of access controls. Website terms of service are a contractual matter between a
website and its visitors, not criminal law; you are responsible for ensuring that your use of
the collected data complies with the laws that apply to you and with Reddit's terms. Post and
comment content belongs to its authors.

### Personal data

Reddit is a pseudonymous platform: the `author` field contains the public username a person
chose to publish under, not their real identity. This Actor collects no emails, no real names,
no private messages, and performs no deanonymization — it stores exactly what any visitor sees
on a public page. Scraped data lives only in your own Apify dataset and is not retained by us
outside your run. If the data you collect contains personal data under the laws of your
jurisdiction (for example the GDPR), you act as its controller: it is your responsibility to
have a legal basis for processing and to honor data-subject requests, including deletion.

### Changelog

See the repository `CHANGELOG.md`.

# Actor input Schema

## `startUrls` (type: `array`):

Direct Reddit links: a subreddit listing (https://www.reddit.com/r/programming/ or .../top), a post (.../comments/<id>/...), a user profile (https://www.reddit.com/user/<name>/), or a search results page. The kind of source is detected from the link itself.

## `subreddits` (type: `array`):

Subreddit names (without r/) to list, using the sort order and time filter below.

## `listingSort` (type: `string`):

Sort order for subreddit listings.

## `time` (type: `string`):

Applies to "Top" listings and to search. Ignored otherwise.

## `searches` (type: `array`):

Keyword queries to run against Reddit's search. Combine with "Restrict search to subreddit" to scope a query to one community. Alias: searchTerms.

## `searchCommunityName` (type: `string`):

When set, every query in "Search keywords" is scoped to this one subreddit instead of searching all of Reddit. Alias: withinCommunity.

## `users` (type: `array`):

Usernames (without u/) whose post and comment history to pull.

## `postedAfter` (type: `string`):

Keep only posts submitted on or after this date. Applied as a filter after fetching — it does not reduce the number of requests made.

## `postedBefore` (type: `string`):

Keep only posts submitted on or before this date.

## `commentedAfter` (type: `string`):

Keep only comments made on or after this date.

## `commentedBefore` (type: `string`):

Keep only comments made on or before this date.

## `includeNSFW` (type: `boolean`):

Off by default: NSFW posts are skipped unless you explicitly turn this on.

## `maxItems` (type: `integer`):

How many items to keep per subreddit / search query / user (posts and comments counted together for users). Reddit's own listings stop paginating around 1,000 items regardless of this setting.

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

Residential proxies are the default and the supported configuration: old.reddit.com throttles by exit IP (kb-measured ≤10 requests/min per IP before a temporary 429), and the run rotates IPs on that signal automatically.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.reddit.com/r/programming/"
    }
  ],
  "subreddits": [
    "programming"
  ],
  "listingSort": "hot",
  "time": "all",
  "searches": [
    "large language models"
  ],
  "searchCommunityName": "programming",
  "users": [
    "spez"
  ],
  "postedAfter": "2026-01-01",
  "postedBefore": "2026-06-01",
  "commentedAfter": "2026-01-01",
  "commentedBefore": "2026-06-01",
  "includeNSFW": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `posts` (type: `string`):

One row per scraped post: title, author, score, comment count, flair, NSFW/stickied flags and (on comment-tree fetches) the full self-text.

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

Individual comments: body, score, depth in the thread, and the fullname of the immediate parent. Join back to posts by postId.

# 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 = {
    "subreddits": [
        "programming"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("actorforgehq/reddit-data-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 = { "subreddits": ["programming"] }

# Run the Actor and wait for it to finish
run = client.actor("actorforgehq/reddit-data-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 '{
  "subreddits": [
    "programming"
  ]
}' |
apify call actorforgehq/reddit-data-scraper --silent --output-dataset

```

## MCP server setup

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