# Reddit Scraper & API - Posts, Comments & Search (`acebuilds/reddit-scraper`) Actor

Scrape Reddit posts, comments, subreddits, users and search results — scores, upvote ratio, comment counts, flair, media and full comment threads. No login or API key. Date cutoff for cheap monitoring runs. Pay per result.

- **URL**: https://apify.com/acebuilds/reddit-scraper.md
- **Developed by:** [Ace](https://apify.com/acebuilds) (community)
- **Categories:** Social media, Lead generation, AI
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 post scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Scraper do?

**Reddit Scraper** extracts posts and comments from [Reddit](https://www.reddit.com): any **subreddit** (hot, new, top, rising, controversial), **Reddit search** results, **user profiles** (posts and comments) and individual **post URLs with their full comment threads**. For every post you get the title, text, author, subreddit, **score**, **upvote ratio**, **comment count**, flair, post type, linked URL or image, NSFW flag and creation time. For every comment you get the text, author, score, **reply depth**, parent ID and the post it belongs to.

No Reddit account, no API key, no app approval. Use it as a **Reddit API** alternative: schedule it for **brand and keyword monitoring**, pull discussions for **market research** and **AI/LLM training data**, or export a subreddit to CSV.

### Why scrape Reddit?

Reddit is where people ask for recommendations, complain about products and compare tools — in public, in their own words. Use the data to:

- 🔔 **Monitor your brand, competitors or keywords** — schedule a run on *New* with "Posted after: 24 hours" and only pay for what's new
- 🧪 **Market and product research** — what people love and hate about a product category, straight from the threads
- 🎯 **Find leads and content ideas** — questions people ask in your niche, sorted by score
- 🤖 **Build AI/LLM datasets** — clean plain-text posts and comment threads with reply structure (depth + parentId)
- 📊 **Track subreddit activity** — score, comment count and upvote ratio over time

### How much does it cost to scrape Reddit?

You pay **per post or comment delivered** — never for blocked requests, retries, duplicates or rows removed by your filters.

| Event | Price (free plan → Gold plan) |
|---|---|
| Post | **$1.50 → $1.20 per 1,000 posts** |
| Comment | **$0.50 → $0.40 per 1,000 comments** |

No start fee. 100 posts with 50 comments each (5,100 rows) cost about $2.65 on the free plan. Deleted-comment placeholders are skipped, not billed. Your *maximum cost per run* setting is respected exactly: the run stops before it would go over.

### How to scrape Reddit

1. Click **Try for free**.
2. Enter **Subreddits** (`python`, `r/smallbusiness`), **Search terms**, or paste any **Reddit URLs** (subreddit, post, user or search links).
3. Pick a sort, set **Max posts per source**, and turn on **Include comments** if you want the threads.
4. Click **Start** and download your data as JSON, CSV, Excel or HTML.

#### Input example — monitor a keyword

```json
{
    "searches": ["standing desk"],
    "searchSort": "new",
    "postedAfter": "24 hours",
    "includeComments": true,
    "maxCommentsPerPost": 50
}
```

#### Input example — a subreddit's top posts this week, with comments

```json
{
    "subreddits": ["smallbusiness", "Entrepreneur"],
    "subredditSort": "top",
    "subredditTime": "week",
    "maxPostsPerSource": 100,
    "includeComments": true,
    "maxCommentsPerPost": 100,
    "maxCommentDepth": 2
}
```

#### Input example — specific threads and users

```json
{
    "startUrls": [
        { "url": "https://www.reddit.com/r/AskReddit/comments/1xcwkya/" },
        { "url": "https://www.reddit.com/user/spez/comments/" }
    ],
    "maxCommentsPerPost": 500
}
```

### What data can you extract from Reddit?

Every row has `dataType`: `post` or `comment`.

**Posts**

| Field | Example |
|---|---|
| `title`, `body`, `bodyHtml` | "Tried decouple, Dynaconf, pydantic-settings…", plain text + HTML |
| `author`, `authorId` | BattleRemote3157, t2_ewn6cu80w |
| `subreddit`, `subredditId` | Python, t5_2qh0y |
| `score`, `upvoteRatio`, `numComments` | 389, 0.987, 41 |
| `flair`, `postType`, `awardCount` | News, text, 1 |
| `linkUrl`, `domain` | https://i.redd.it/….jpeg, i.redd.it |
| `over18`, `spoiler`, `stickied`, `isCrosspost` | false |
| `createdAt`, `url`, `id`, `fullname` | 2026-10-21T13:52:24.930Z, permalink, 1xbnrhi, t3_1xbnrhi |

**Comments**

| Field | Example |
|---|---|
| `body`, `bodyHtml`, `mediaUrls` | "Fresh Prince of Bel-Air", images/GIFs in the comment |
| `author`, `score`, `createdAt` | FullCircleDC, 3965 |
| `depth`, `isTopLevel`, `parentId` | 0, true, t3_1xcwkya |
| `postId`, `postTitle`, `postUrl`, `subreddit` | the post the comment belongs to |

#### Output example (abridged)

```json
[
    {
        "dataType": "post",
        "id": "1xbnrhi",
        "title": "litellm 1.107.0 on PyPI is compromised",
        "author": "BattleRemote3157",
        "subreddit": "Python",
        "score": 389,
        "upvoteRatio": 0.987,
        "numComments": 41,
        "flair": "News",
        "postType": "multi_media",
        "createdAt": "2026-10-21T13:52:24.930Z",
        "url": "https://www.reddit.com/r/Python/comments/1xbnrhi/litellm_11070_on_pypi_is_compromised/"
    },
    {
        "dataType": "comment",
        "id": "19rfr1194cckj",
        "body": "litellm again....!",
        "author": "Nice_Mix_1021",
        "score": 169,
        "depth": 0,
        "parentId": "t3_1xbnrhi",
        "postId": "1xbnrhi",
        "postTitle": "litellm 1.107.0 on PyPI is compromised",
        "createdAt": "2026-10-21T14:01:11.424Z"
    }
]
```

### Features

- **Pay only for new posts**: with *New* sorting and **Posted after** (`"24 hours"`, `"7 days"` or a date), the scraper stops paging once it reaches older posts — scheduled monitoring runs stay cheap
- **Full comment threads**: "load more comments" branches are expanded, and comments come back **in reading order** (each reply right after its parent) with depth and parentId — easy to rebuild the tree
- **Deduplicated**: a post or comment found by several sources is delivered and billed once per run
- **Free filters**: minimum score, must-contain keywords, skip NSFW, max reply depth
- **Any mix of inputs** in one run: subreddits, searches, users and post URLs
- **Explains short runs**: a missing, private or banned subreddit, blocked requests or over-tight filters are reported in the log and the `OUTPUT` record instead of a silent empty dataset

### FAQ

#### Do I need a Reddit account or API key?

No. The scraper reads the same public pages a logged-out visitor sees. It uses residential proxies, which Reddit requires — the default setting works out of the box.

#### Why don't search results have post text?

Reddit's search page shows titles, scores and comment counts, not the post body. Turn on **Include comments** to get the discussion, or scrape the subreddit feed, which includes the full text.

#### How many posts can I get from one subreddit?

Each Reddit feed ends after a limited number of posts (historically about 1,000 per feed and sort). *Top* lists with a short time range end much sooner — Reddit itself lists only about 25–30 posts for a busy subreddit's top of the week, and about 100 for the month. Use *Hot* or *New*, a longer time range, or searches to get more.

#### Can it scrape private or quarantined subreddits?

No — those need a logged-in account. The run tells you when a subreddit is private, banned or doesn't exist.

#### Is it legal to scrape Reddit?

The scraper only collects content that is publicly visible without logging in. Reddit content can contain personal data (usernames, posts people wrote) — make sure your use complies with the GDPR and other laws in your jurisdiction, and with Reddit's terms for your use case. Consult a lawyer if unsure.

#### Can I use it via API or integrate it?

Yes — run it via the [Apify API](https://docs.apify.com/api/v2), schedule it, or connect it to Make, Zapier, Google Sheets, Slack and others through Apify integrations.

#### Need a field that's missing?

Open an issue on the **Issues** tab — feature requests are answered quickly.

# Actor input Schema

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

Subreddit names to scrape, one per line, with or without "r/". Example: "python", "r/smallbusiness".

## `subredditSort` (type: `string`):

Which feed to read from each subreddit. Use "New" with "Posted after" for monitoring.

## `subredditTime` (type: `string`):

Time window when the subreddit sort is Top or Controversial.

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

Search Reddit posts for these terms, one per line. Each term runs as its own search. Example: "standing desk", "best CRM for startups". Search results carry title, author, subreddit, score, comment count and date — Reddit's search page doesn't show post text; turn on comments to get the discussion.

## `searchSubreddit` (type: `string`):

Limit the searches to one subreddit, e.g. "smallbusiness". Leave empty to search all of Reddit.

## `searchSort` (type: `string`):

Order of search results. Use "New" with "Posted after" for brand or keyword monitoring.

## `searchTime` (type: `string`):

Only return search results from this time window.

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

Any mix of subreddit, post, user or search URLs. Examples: https://www.reddit.com/r/python/top/?t=week · https://www.reddit.com/r/python/comments/abc123/ · https://www.reddit.com/user/spez/ · https://www.reddit.com/search/?q=apify

## `maxPostsPerSource` (type: `integer`):

Stop each subreddit, search, or user after this many posts. Reddit itself serves at most ~1,000 posts per feed.

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

Hard cap on posts + comments for the whole run. 0 = no cap.

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

Also scrape the comments of every post found. Post URLs in "Reddit URLs" always include comments.

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

Stop each thread after this many comments (in thread order, top-sorted). Up to 500.

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

1 = top-level comments only, 2 = plus direct replies, … 0 = all depths.

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

Only keep results newer than this. A date (2026-10-01) or an age ("24 hours", "7 days"). On New-sorted feeds the scraper stops paging once it passes this point, so you don't pay for old posts.

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

Skip posts with fewer upvotes than this.

## `keywords` (type: `array`):

Keep only posts whose title or text contains at least one of these words (case-insensitive).

## `skipNsfw` (type: `boolean`):

Drop posts marked 18+.

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

How many sources to scrape at once, each on its own proxy session.

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

Residential proxies are required — Reddit blocks datacenter IPs. The default works out of the box.

## Actor input object example

```json
{
  "subreddits": [
    "python"
  ],
  "subredditSort": "hot",
  "subredditTime": "week",
  "searchSort": "relevance",
  "searchTime": "all",
  "maxPostsPerSource": 25,
  "maxItems": 0,
  "includeComments": false,
  "maxCommentsPerPost": 100,
  "maxCommentDepth": 0,
  "skipNsfw": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "subreddits": [
        "python"
    ],
    "maxPostsPerSource": 25,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("acebuilds/reddit-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": ["python"],
    "maxPostsPerSource": 25,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("acebuilds/reddit-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": [
    "python"
  ],
  "maxPostsPerSource": 25,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call acebuilds/reddit-scraper --silent --output-dataset

```

## MCP server setup

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