# Reddit Pro Scraper — Posts, Full Comment Trees & Monitoring (`dami0089/reddit-pro-scraper-posts-comments`) Actor

Posts, árboles de comentarios completos, subreddits y usuarios de Reddit vía API oficial: 50% más barato, con monitor y markdown para IA.

- **URL**: https://apify.com/dami0089/reddit-pro-scraper-posts-comments.md
- **Developed by:** [Damian Oliva](https://apify.com/dami0089) (community)
- **Categories:** Social media, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 result items

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 Pro Scraper — Posts, Full Comment Trees & Monitoring

Scrape **public Reddit data** through the **official Reddit API**: subreddit feeds, global search,
user histories, **complete comment trees** (100% expanded), single-post details, r/popular and
community info — with **incremental monitoring** and **AI-ready markdown**, at half the typical
per-item price.

### What it does

- **7 scrape modes**: `subreddit` feed, `search` (global or within one subreddit), `user_posts`
  (a user's posts + comments + profile card), `post_comments` (a post with its full comment tree),
  `post_details` (one post), `popular` (r/popular), `subreddit_info` (community profile).
- **Full comment trees**: `morechildren` placeholders are expanded recursively until the tree is
  complete or your `maxCommentsPerPost` cap is hit. When the cap cuts the tree, the post is
  flagged `commentsTruncated: true` — you always know whether you got everything.
- **Monitor mode**: schedule the actor and get **only new items** on each run. Seen IDs persist
  in the key-value store per source, so daily tracking costs you only the delta.
- **Markdown for AI** (`outputFormat: markdown|both`): every post gets a clean markdown rendering
  (title, meta, body, top comments threaded) plus a `tokensEstimate` (~chars/4). The markdown
  itself is **never billed** — only the result item.
- **Filters**: time window (`timeRange`), minimum score, flair text, NSFW on/off.
- **Official API first, archive fallback**: uses Reddit's official JSON/OAuth API (bring your own
  Reddit app credentials for the live OAuth path), and automatically falls back to the public
  Reddit archive when official endpoints are unreachable from the current network.

### Use cases

- Brand & reputation monitoring (track subreddits daily with `monitorMode`).
- Voice-of-customer research: full complaint/praise threads, not just top-level comments.
- Training data for LLMs: markdown + token estimates, thread-ordered comments with depth.
- Lead discovery: search niche subreddits for buying-intent keywords.
- Community stats: subscribers, creation date, descriptions via `subreddit_info`.

### How to use

1. Pick a **mode**.
2. Fill the required field for that mode (`subreddit`, `query`, `username` or `postUrl`).
3. Set `maxItems` — the hard cap on billed result rows (controls spend).
4. Run. Results land in the default dataset; each row is charged as one `result-item` event.

#### The 7 modes with examples

| Mode | Required input | Example |
|---|---|---|
| `subreddit` | `subreddit: technology`, `sort: hot` | Latest hot posts of r/technology |
| `search` | `query: "mechanical keyboard"` | Global search (add `subreddit` to restrict) |
| `user_posts` | `username: spez` | Profile card + posts + comments of u/spez |
| `post_comments` | `postUrl: <post URL or ID>` | Full comment tree of one post |
| `post_details` | `postUrl: <post URL or ID>` | Just the post (add `includeComments` for top comments) |
| `popular` | — | r/popular feed |
| `subreddit_info` | `subreddit: technology` | Community profile (subscribers, description…) |

Extra knobs: `sort` (hot/new/top/rising/controversial/relevance/comments), `timeRange`
(hour/day/week/month/year/all), `minScore`, `flairFilter`, `includeNsfw`, `includeComments`,
`maxCommentsPerPost` (0 = no comments), `monitorMode`, `proxyConfiguration`,
`redditClientId`/`redditClientSecret` (your own Reddit script-app credentials for the live
OAuth path — never logged).

#### Example input

```json
{
  "maxItems": 10,
  "mode": "subreddit",
  "sort": "hot",
  "subreddit": "technology"
}
```

A full-tree example:

```json
{
  "mode": "post_comments",
  "postUrl": "https://www.reddit.com/r/technology/comments/1wyva7w/metas_ai_mascot_is_stealing_domo_from_2012/",
  "maxCommentsPerPost": 200,
  "maxItems": 500,
  "outputFormat": "both"
}
```

#### Example output (one dataset item)

```json
{
  "id": "t3_1wyva7w",
  "type": "post",
  "subreddit": "technology",
  "title": "Metas AI mascot is stealing Domo from 2012",
  "selftext": null,
  "author": "goatedirish",
  "score": 1,
  "upvoteRatio": 1,
  "numComments": 0,
  "createdAt": "2026-10-06T06:16:23.000Z",
  "url": "https://mashable.com/tech/why-companies-use-cute-mascots-meta-jolly",
  "permalink": "https://www.reddit.com/r/technology/comments/1wyva7w/metas_ai_mascot_is_stealing_domo_from_2012/",
  "flair": "Artificial Intelligence",
  "isNsfw": false,
  "mediaUrls": ["https://external-preview.redd.it/DAtdt8Et3aSW07tvw_Oj_n8knD85ItJFT_dopqf5LIo.jpeg?..."],
  "parentId": null,
  "depth": null,
  "body": null,
  "commentsTruncated": false,
  "markdown": "# Metas AI mascot is stealing Domo from 2012\n\nr/technology · u/goatedirish · ...",
  "tokensEstimate": 186
}
```

Comment rows carry `body`, `parentId` (`t3_` post or `t1_` comment) and `depth` (0 = top-level reply),
so you can rebuild the exact thread. `subreddit` rows carry subscribers in `score`; `user` rows
carry total karma in `score`. Fields that don't apply to a row type are `null` — never invented.

### Pricing

| Event | Price |
|---|---|
| `result-item` — one post, comment, subreddit or user saved | **US$ 0.001** |

The markdown rendering and token estimate are **free** (included in the item, never billed separately).

- 100 posts ≈ **US$ 0.10**
- 1,000 posts ≈ **US$ 1.00**
- 1 post + its 200 comments ≈ **US$ 0.20**
- Daily monitor of a subreddit: you pay only for **new** items each run.

`maxItems` is a hard cap: the actor stops before exceeding what your budget allows
(`calculateMaxEventChargeCountWithinLimit` + `eventChargeLimitReached` are honored).

### Official API vs plain scraping

This actor talks to **Reddit's official API** (OAuth when you provide your own free Reddit
script-app credentials; public JSON endpoints otherwise) instead of parsing HTML pages. That
means stable field names, real scores/ratios/flairs, and proper rate-limit handling (paced
requests, exponential backoff on 429/5xx). When the official path is unreachable from the
current network, the actor transparently falls back to the public Reddit archive API rather
than failing your run — the run summary records which source was used. Before buying any
Reddit actor in the Store, compare: price per row, whether comment trees are fully expanded
or top-level only, and whether incremental monitoring is included.

### Limits

- Reddit's quota (~100 req/min) is absorbed with pacing + retries; very large `maxItems` runs
  simply take longer.
- Private, banned, quarantined or removed content returns no rows (never billed) — the log says why.
- The archive fallback lags live Reddit by hours/days and its author lookup can be slow; for
  fresh `user_posts` results, provide `redditClientId`/`redditClientSecret` to use the live
  OAuth path.
- `maxCommentsPerPost` caps at 2000; `maxItems` caps at 5000 per run.

### FAQ

**Is this legal?** Yes — only public data, no login bypass, no CAPTCHA solving, no paywalls.
Provide your own Reddit app credentials and you use Reddit's sanctioned API with your own quota.

**Do I need Reddit credentials?** No. They are optional and unlock the live OAuth path
(freshest data, highest reliability). Without them the actor uses public endpoints + archive fallback.

**Why 0 items?** The source is likely empty (private/banned subreddit, removed post, a search
with no matches) or `monitorMode` found nothing new. Check the log lines — the cause is stated.
Monitor runs with no new content correctly return 0 items and cost nothing.

**Which proxy should I use?** The default Apify proxy works for most runs. For heavy runs, switch
the `proxyConfiguration` to residential proxies. Local runs without a proxy fall back to the
archive automatically.

**Common errors**: `Invalid input: "subreddit" is required…` (missing field for the mode);
`could not find a post ID in "postUrl"` (paste the full post URL); charge-limit warnings mean
your max-spend was reached and the run stopped early by design.

### Integrations

- **API**: standard Apify dataset API (`/v3/actor-runs/{id}/dataset/items?view=overview`).
- **Make / Zapier**: use the Apify modules, trigger on dataset items.
- **MCP / LLMs**: the dataset schema (`overview` view) exposes typed fields; `outputFormat:
  both` gives you ready-to-embed markdown with token estimates per post.

### Support

Open an issue on the actor's GitHub repo (link on the Store page) with the run ID, the input
JSON (redact your credentials) and the relevant log lines.

# Actor input Schema

## `mode` (type: `string`):

What to scrape: subreddit feed, global search, user posts+comments, full comment tree of a post, post details, r/popular, or community info.

## `subreddit` (type: `string`):

Subreddit name without r/ (modes: subreddit, subreddit_info). E.g. technology

## `query` (type: `string`):

Keyword to search across Reddit (mode: search).

## `username` (type: `string`):

Username without u/ (mode: user_posts). Returns their posts and comments.

## `postUrl` (type: `string`):

Full Reddit post URL or bare post ID (modes: post_comments, post_details).

## `sort` (type: `string`):

Feed sort order. relevance/comments apply to search; comments sorts comments by score.

## `timeRange` (type: `string`):

Window for top/controversial sorts and date filtering (hour, day, week, month, year, all).

## `minScore` (type: `integer`):

Skip posts/comments below this score. 0 disables the filter.

## `flairFilter` (type: `string`):

Only keep posts whose flair contains this text (case-insensitive). Empty disables.

## `includeNsfw` (type: `boolean`):

When off, NSFW (over_18) posts are skipped.

## `includeComments` (type: `boolean`):

Attach top comments to each post. Each comment counts as a billed result item.

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

Cap of comments fetched per post. When reached, the post is flagged commentsTruncated=true.

## `outputFormat` (type: `string`):

items = structured rows only; markdown = add a markdown rendering + token estimate to each item (free); both = same as markdown.

## `monitorMode` (type: `boolean`):

On scheduled runs, only output items not seen in previous runs (state kept in the default key-value store).

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

Hard cap on total result items. Controls spend (US$ 0.001 per result item).

## `redditClientId` (type: `string`):

Client ID of your own Reddit script-type app. When set together with the secret, the actor uses the live official OAuth API instead of public endpoints.

## `redditClientSecret` (type: `string`):

Secret of your own Reddit script-type app. Never logged; used only for the OAuth token exchange.

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

Proxy for requests to Reddit. Residential proxies are recommended for large runs.

## Actor input object example

```json
{
  "mode": "subreddit",
  "subreddit": "technology",
  "query": "artificial intelligence",
  "sort": "hot",
  "timeRange": "week",
  "minScore": 0,
  "includeNsfw": true,
  "includeComments": false,
  "maxCommentsPerPost": 50,
  "outputFormat": "items",
  "monitorMode": false,
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Scraped Reddit posts, comments, subreddits or users (table view of the default dataset).

# 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 = {
    "mode": "subreddit",
    "subreddit": "technology",
    "query": "artificial intelligence",
    "sort": "hot",
    "timeRange": "week",
    "minScore": 0,
    "includeNsfw": true,
    "includeComments": false,
    "maxCommentsPerPost": 50,
    "outputFormat": "items",
    "monitorMode": false,
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami0089/reddit-pro-scraper-posts-comments").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 = {
    "mode": "subreddit",
    "subreddit": "technology",
    "query": "artificial intelligence",
    "sort": "hot",
    "timeRange": "week",
    "minScore": 0,
    "includeNsfw": True,
    "includeComments": False,
    "maxCommentsPerPost": 50,
    "outputFormat": "items",
    "monitorMode": False,
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("dami0089/reddit-pro-scraper-posts-comments").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 '{
  "mode": "subreddit",
  "subreddit": "technology",
  "query": "artificial intelligence",
  "sort": "hot",
  "timeRange": "week",
  "minScore": 0,
  "includeNsfw": true,
  "includeComments": false,
  "maxCommentsPerPost": 50,
  "outputFormat": "items",
  "monitorMode": false,
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call dami0089/reddit-pro-scraper-posts-comments --silent --output-dataset

```

## MCP server setup

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

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/0GJTaAbtClrjTAOMY/builds/yea7XHmchm1qTWVDZ/openapi.json
