# Reddit Scraper (`apify/reddit-scraper`) Actor

Scrape Reddit posts, comments, communities, and user profiles without a login or API key. Search any subreddit or keyword to see what people say about a brand or topic, with full comment threads and the scores that show what landed.

- **URL**: https://apify.com/apify/reddit-scraper.md
- **Developed by:** [Apify](https://apify.com/apify) (Apify)
- **Categories:** Social media
- **Stats:** 89 total users, 59 monthly users, 43.9% runs succeeded, 4 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $2.50 / 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.
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

Scrape Reddit posts, comments, communities, and user profiles at scale without a login or API keys, for market research, social listening, and LLM training data.

### What does Reddit Scraper do?

Reddit Scraper extracts structured data in four modes: posts, comments, communities, and users. Point it at subreddit URLs, permalinks, user pages, or search URLs and pick a mode. No login, no API keys, no rate limits to juggle.

- 📋 **Posts mode** for titles, text, scores, upvote ratio, flairs, media
- 💬 **Comments mode** for full threads with replies, depth, parent chain
- 🏠 **Communities mode** for subscriber counts, rules, icons, banners
- 👤 **Users mode** for karma, account age, verification flags
- 🔍 **Search-driven discovery** of what to scrape
- 🔁 **Residential proxy rotation** and retries built in

### What data can you extract from Reddit?

| Post data            | Community info        | User details        |
| -------------------- | --------------------- | ------------------- |
| Title, body, flair   | Name and URL          | Username, URL       |
| Score, upvote ratio  | Subscriber count      | Karma breakdown     |
| Comment count, dates | Description, rules    | Account age         |
| Media, thumbnails    | NSFW and access flags | Verified, mod flags |

### Can I use it for market research, sentiment analysis, and lead generation?

Yes. Pull a subreddit's posts to map a category, a comment tree for sentiment work, community sizes for market sizing, or active users for audience discovery.

Accepted inputs: subreddit URLs like `/r/python`, post and comment permalinks, user pages like `/user/spez`, search URLs, or plain names.

### Why use Reddit Scraper?

| What you need         | Doing it yourself                         | Reddit Scraper                           |
| --------------------- | ----------------------------------------- | ---------------------------------------- |
| Access                | Register an app, manage OAuth credentials | None, no login or keys                   |
| Reliability           | Handle throttling and retries yourself    | Rotation and retries built in            |
| Four entity types     | Stitch several endpoints together         | One Actor, one mode switch               |
| Whole comment threads | Paginate nested children by hand          | Full threads with depth and parent chain |
| Ready-to-use data     | Normalize raw payloads first              | Flat records, ready to export            |
| Delivery              | Build scheduling and webhooks yourself    | Schedules, webhooks, integrations        |

### What can you do with the data after scraping?

**Market and product research.** Track what customers say about a product or competitor across niche communities. Weekly runs suit category mapping.

**Trend monitoring.** Watch a subreddit's new or rising feeds and pipe results to Slack, Sheets, or a database. Hourly for fast communities, daily otherwise.

**Sentiment and social listening.** Pull full comment trees into NLP models, weighted by score.

**Audience research and RAG.** Snapshot subscriber counts month over month, profile active users, or drop structured text into embeddings pipelines.

Run search mode with a low result cap first, then scrape only the communities it surfaces.

### How to use Reddit Scraper

1. Sign in to Apify Console and open the Actor.
2. Pick a **Scrape mode**: posts, comments, communities, or users.
3. Paste **Start URLs**, or fill in names, usernames, or queries.
4. Set volume limits such as max posts per community.
5. Click **Save & Start**, then download from **Storage**.

### How much will it cost?

Reddit Scraper is **pay per result**. You pay for each item in the dataset: a post, a comment, a community, or a user, plus a small Actor start fee per run. Compute and proxy traffic are included. Current prices are on the Pricing tab.

Each source is scraped on its own, so a post or comment reached through two inputs, say its post URL and its own permalink, lands in the dataset twice and is charged twice.

Some of what you ask for returns nothing: a deleted community, a search with no hits, a post with no comments. Each of those gets one item explaining why, priced below a real result.

You get one of those per thing you asked for: per community, username, post URL or query. Never one per page of a listing, and never for a post found inside a community you asked about. Input rejected before any request, such as a link that is not a Reddit URL, costs nothing.

Three levers move the total:

- `maxPostsPerCommunity` and `maxCommentsPerPost` left empty mean scrape everything.
- `maxCommentDepth` stops the crawl at the depth you analyze.
- A low `maxSearchResultsPerQuery` keeps discovery cheap.

### ⬇️ Input

**Scrape mode** is required. Each mode needs at least one source: URLs, names, or queries.

| Field                      | Type    | Description                                                              |
| -------------------------- | ------- | ------------------------------------------------------------------------ |
| `scrapeMode`               | string  | `posts`, `comments`, `communities`, `users`. Default: `posts`. Required. |
| `startUrls`                | array   | Reddit URLs. Meaning depends on the mode.                                |
| `includeNsfw`              | boolean | Include adult content. Default: false.                                   |
| `searchQueries`            | array   | Queries to find what to scrape.                                          |
| `communityNames`           | array   | Names like `python` or `r/webdev`.                                       |
| `communityQueries`         | array   | Queries scoped to those communities.                                     |
| `usernames`                | array   | Like `spez` or `u/AutoModerator`.                                        |
| `includeCommunityRules`    | boolean | Get rules with the details. Default: false.                              |
| `includeCommentReplies`    | boolean | Comment permalinks only. Pulls the thread. Default: false.               |
| `maxCommentDepth`          | integer | Depth from top-level comments. Empty means all.                          |
| `maxPostsPerCommunity`     | integer | Posts per community. Empty means all.                                    |
| `maxCommentsPerPost`       | integer | Comments per post. Empty means all.                                      |
| `maxPostsPerUser`          | integer | Posts per user. Empty means all.                                         |
| `maxCommentsPerUser`       | integer | Comments per user. Empty means all.                                      |
| `maxSearchResultsPerQuery` | integer | Results per query. Empty means all.                                      |

Sort and time window are set per mode via `communitySort`, `commentSort`, `userSort`, and `searchSort`, each with a time filter from `hour` to `all`.

```json
{
    "scrapeMode": "posts",
    "startUrls": [{ "url": "https://www.reddit.com/r/python" }],
    "includeNsfw": false,
    "maxPostsPerCommunity": 25,
    "communitySort": "hot"
}
```

### ⬆️ Output

Results land in the dataset and export as JSON, CSV, Excel, HTML, or XML. Each mode writes its own record shape.

Posts:

```json
{
    "id": "1v8nkjz",
    "title": "Nothing quite like a good Nolan twist.",
    "authorName": "Arch_Lancer17",
    "communityName": "TheOdysseyMovie",
    "score": 4127,
    "commentCount": 98,
    "createdAt": "2026-07-28T04:21:17.000Z",
    "flairText": "HUMOUR | Χιούμορ",
    "isNsfw": false
}
```

Comments:

```json
{
    "id": "p07c4tq",
    "body": "He definitely telegraphed it with Troy soldiers being all in white and ...",
    "authorName": "TheJuiceBoxS",
    "postId": "1v8nkjz",
    "parentCommentId": null,
    "depth": 0,
    "score": 190,
    "createdAt": "2026-07-28T04:39:55.000Z"
}
```

Communities:

```json
{
    "id": "d6xzz7",
    "name": "TheOdysseyMovie",
    "title": "Christopher Nolan's The Odyssey",
    "subscriberCount": 22558,
    "rules": []
}
```

Users:

```json
{
    "username": "i_was_a_person_once",
    "totalKarma": 351487,
    "linkKarma": 554,
    "commentKarma": 350933,
    "createdAt": "2018-02-16T17:13:52.000Z",
    "isVerified": true,
    "isSuspended": false
}
```

#### When there is nothing to return

If something you asked for produced no result, the dataset gets one item explaining why.

```json
{
    "url": "https://www.reddit.com/r/thisdoesnotexist123",
    "reasonCode": "not-found",
    "reasonDescription": "Community r/thisdoesnotexist123 does not exist or was deleted"
}
```

| `reasonCode`   | What it means                                                                                                                               |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `not-found`    | It doesn't exist, or it was deleted.                                                                                                        |
| `empty`        | Reddit served it, but nothing came out of it: a community with no posts or only NSFW posts, a search with no hits, a post with no comments. |
| `nsfw-skipped` | The community (communities mode) or post you asked for is adult content and **Include NSFW** is off.                                        |
| `unavailable`  | Reddit won't serve it: private, banned, quarantined, or gated.                                                                              |

The `url` is the exact page that came up empty, so two queries on the same community stay apart. To keep only real results, drop every item that has a `reasonCode`.

These are the items the pricing section covers: one per thing you asked for, priced below a real result.

### How to run it via the Apify API

```bash
curl -X POST "https://api.apify.com/v2/acts/tri_angle~reddit-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"scrapeMode":"posts","startUrls":[{"url":"https://www.reddit.com/r/python"}],"maxPostsPerCommunity":25}'
```

Use the token from your Apify Integrations page. The `apify-client` packages wrap the same endpoints.

### Troubleshooting

| Issue                            | Solution                                                                            |
| -------------------------------- | ----------------------------------------------------------------------------------- |
| Blocked-request error            | Rotation and retries are built in, not configurable. Retry, then use the Issues tab |
| Permalink returned one comment   | The default. Enable Include replies for the thread                                  |
| Deep comment came back empty     | Leave `maxCommentDepth` empty from a permalink, since depth counts from top-level   |
| Time window had no effect        | Sort and time filter only interact for top and controversial                        |
| NSFW content missing             | Set `includeNsfw` to true                                                           |
| Some sources produced no results | Look for items with a `reasonCode` field, they say what happened to each one        |

### Limitations

- Deleted users and users that never existed are indistinguishable, because Reddit answers the same for both.
- Posts inside private, banned, or gated communities are not served. In communities mode you still get the community record; in posts or comments mode you get an `unavailable` item.
- Restricted communities and suspended users return partial records. A community limited to Reddit Premium members comes back with `type` set to `gold_only` and none of the restriction flags set.
- Proxy groups, concurrency, and retries are fixed, not inputs.
- A comment more than 8 levels deep, scraped from its own permalink, comes back with `depth` empty, as do its replies. Scrape the post URL to get every depth.

### What else can you scrape from social media?

- [Instagram Scraper](https://apify.com/apify/instagram-scraper) for posts, profiles, and hashtags
- [Facebook Posts Scraper](https://apify.com/apify/facebook-posts-scraper) for page and group posts
- [TikTok Scraper](https://apify.com/clockworks/tiktok-scraper) for videos, profiles, and hashtags

### FAQ

#### Can I scrape Reddit data behind a login?

No. Only public content is read. Private and gated communities return the community record, not the posts inside.

#### Can I get historical Reddit data?

Yes, within what Reddit still serves. Use `top` or `controversial` sort with a `year` or `all` time filter.

#### What happens to deleted, private, or banned content?

If Reddit still serves the data, you get a result. If not, you get an item with `reasonCode` and `reasonDescription` explaining why, and the run finishes anyway. Deleted posts and comments return `body` as `[deleted]` or `[removed]`, suspended users are flagged `isSuspended`, and restricted communities carry `isPrivate`, `isBanned`, `isQuarantined`, or `isGated`.

#### Can I use it with integrations like Zapier, Make, or n8n?

Yes. Every Apify Actor supports Schedules, webhooks, and the Apify integrations catalog: Zapier, Make, n8n, Slack, Google Sheets, LangChain.

#### Can I use Reddit Scraper with the Apify API?

Yes. See the API section above, or the API tab for snippets.

#### Can I use Reddit Scraper through an MCP server?

Yes. Every Apify Actor is reachable through the Apify MCP server, so an MCP-capable agent can run it as a tool.

#### Is it legal to scrape Reddit data?

Scraping public Reddit content is generally legal. Personal data is protected by GDPR, so don't scrape or store it without a legitimate reason. See our post on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/), and consult a lawyer if unsure.

### Your feedback

Missing a field or hitting a bug? Open the Issues tab. Custom work is available through [Apify's custom solutions](https://apify.com/custom-solutions) team.

#### Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Reddit, Inc. or any of its subsidiaries.

# Actor input Schema

## `scrapeMode` (type: `string`):

Select what type of data to scrape from Reddit.

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

Reddit URLs to scrape - community, post, user, or search URLs depending on the selected scrape mode. In comments mode, a comment permalink scrapes just that single comment.

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

Include adult (18+) content in results. When disabled, NSFW posts and communities are skipped even when passed directly as start URLs. A skipped post URL, or a skipped community in communities mode, gets an item with the "nsfw-skipped" reason; in posts or comments mode a community whose listing holds only NSFW posts gets an "empty" item.

## `communityNames` (type: `array`):

Community names (e.g. "python", "r/webdev").

## `communityQueries` (type: `array`):

Search queries scoped to the specified communities. Uses Reddit's built-in community search.

## `communitySort` (type: `string`):

Sort order for community post listings.

## `communityTimeFilter` (type: `string`):

Time window for "Top" or "Controversial" sort.

## `maxPostsPerCommunity` (type: `integer`):

Maximum posts to scrape from each community. In comments mode these are the posts whose comments get scraped. Posts skipped as NSFW never use up the limit, and neither do posts with no comments in comments mode. Applies to each community query separately. Leave empty to scrape all available.

## `includeCommunityRules` (type: `boolean`):

Get community rules alongside community details.

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

Sort order for comments.

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

Maximum nesting depth, counted from the post's top-level comments (0 = top-level only, 1 = one level of replies, etc.). Leave empty to scrape all levels. It's also recommended to leave empty when scraping from comment URL, since a deeply nested comment can fall outside the limit.

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

Maximum comments to scrape per post. Only comments that pass your filters count, so comments below "Max depth" never use up the limit. Leave empty to scrape all available.

## `includeCommentReplies` (type: `boolean`):

Only applies when a start URL points to a specific comment. Enable to also scrape that comment's full reply thread, otherwise only the single comment will be scraped. It has no effect when scraping from post, community, or user (those already include replies - use Max depth to limit how deep).

## `usernames` (type: `array`):

Usernames (e.g. "spez", "u/AutoModerator").

## `userSort` (type: `string`):

Sort order for user post and comment listings.

## `userTimeFilter` (type: `string`):

Time window for "Top" or "Controversial" sort.

## `maxPostsPerUser` (type: `integer`):

Maximum posts to scrape per user. Only posts that pass your filters count, so posts skipped as NSFW never use up the limit. Leave empty to scrape all available.

## `maxCommentsPerUser` (type: `integer`):

Maximum comments to scrape per user. Leave empty to scrape all available.

## `searchQueries` (type: `array`):

Search queries to find posts, communities, or users to scrape.

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

Sort order for search results.

## `searchTimeFilter` (type: `string`):

Time window for search results.

## `maxSearchResultsPerQuery` (type: `integer`):

Maximum results to scrape per search query. Leave empty to scrape all available.

## Actor input object example

```json
{
  "scrapeMode": "posts",
  "startUrls": [
    {
      "url": "https://www.reddit.com/r/python"
    }
  ],
  "includeNsfw": false,
  "communitySort": "hot",
  "communityTimeFilter": "all",
  "includeCommunityRules": false,
  "commentSort": "confidence",
  "includeCommentReplies": false,
  "userSort": "new",
  "userTimeFilter": "all",
  "searchSort": "relevance",
  "searchTimeFilter": "all"
}
```

# Actor output Schema

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

Default dataset items - one per scraped post, comment, community, or user, plus one per source that produced no result.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.reddit.com/r/python"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("apify/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 = { "startUrls": [{ "url": "https://www.reddit.com/r/python" }] }

# Run the Actor and wait for it to finish
run = client.actor("apify/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 '{
  "startUrls": [
    {
      "url": "https://www.reddit.com/r/python"
    }
  ]
}' |
apify call apify/reddit-scraper --silent --output-dataset

```

## MCP server setup

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