# Reddit Scraper - Posts, Comments, Subreddits & Users (`clover_folktale/reddit-scraper`) Actor

Scrape Reddit posts by keyword, the hot, new or top posts of any subreddit, the comments under any post, and any user's posts and comments. Get score, upvote ratio, comment count, flair and author user ID. No login, cookies or API keys needed. Export to JSON, CSV or Excel.

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

## Pricing

from $3.00 / 1,000 results

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

Reddit Scraper returns clean, flat JSON from Reddit. It covers posts by keyword, the posts of any subreddit (hot, new, top or most comments), the comments under any post, and the post and comment history of any user. It is built for researchers, marketers, analysts and AI or data teams who need Reddit text with clean metadata. No Reddit account, API keys, proxies or cookies are needed.

Pricing is pay-per-event: $0.003 per post or comment returned, plus a small start fee per run ($0.005 on paid Apify plans). The full price list is in the "How much does it cost?" section below.

### What data can you get?

#### Modes

| Mode | Give it | You get |
|---|---|---|
| `search` | a keyword (optional: sort, time range) | posts matching the keyword across Reddit |
| `subreddit` | subreddit names or links (optional: keyword, sort, time range) | the hot, newest, top or most-commented posts of each subreddit, optionally only those matching a keyword |
| `comments` | post links, redd.it links or post IDs (optional: comment sort) | the comments under each post, with depth and parent comment |
| `userPosts` | usernames or profile links (optional: sort) | the posts each user has written, newest first by default |
| `userComments` | usernames or profile links (optional: sort) | the comments each user has written, with the title of the post they were written under |

#### Fields

Every item has `"type": "post"` or `"type": "comment"`. Posts and comments share some fields; others are only on one item type.

| Field | Item type | What it contains |
|---|---|---|
| `type` | post, comment | Record type: `post` or `comment` |
| `title` | post | Post title |
| `text` | post, comment | Post body or comment text in Markdown |
| `score` | post, comment | Net votes; `null` when Reddit hides the score |
| `upvoteRatio` | post | Share of upvotes, for example 0.89 |
| `commentCount` | post | Number of comments on the post |
| `subreddit` | post | Subreddit name; a post on a user's own profile has `u_<name>` |
| `flair` | post | Post flair text |
| `createdAt` | post, comment | Creation time, ISO 8601 UTC |
| `url` | post, comment | Link to the post or comment on reddit.com |
| `author` | post, comment | Public username; `null` when the account is deleted |
| `authorId` | post, comment | Author's Reddit user ID (the part after `t2_`); `null` when the account is deleted |
| `authorAvatar` | post, comment | Author's avatar image URL; `null` when the account is deleted |
| `authorAccountType` | post, comment | Author's account type, for example `USER`; `null` when the account is deleted |
| `postId` | post, comment | Post ID (the part after `t3_`); on comments, the post they belong to |
| `commentId` | comment | Comment ID |
| `parentCommentId` | comment | ID of the comment this one replies to; `null` for top-level comments |
| `depth` | comment | Nesting level of a comment, 0 = top level |
| `postTitle` | comment (`userComments` mode) | Title of the post the comment was written under |
| `linkUrl` | post | Target of a link post; `null` for text posts |
| `imageUrl` | post | Preview image of a link or image post |
| `isSelfPost` | post | `true` for text (self) posts |
| `isNsfw` | post | NSFW flag |
| `isLocked` | post | Whether the post is locked |
| `isStickied` | post, comment | Whether the item is stickied |

Public author profiles come with posts and comments: username, user ID, avatar and account type, for post authors and commenters alike (see "Tips and limits" for the `userComments` exception).

### How to use Reddit Scraper

1. Open Reddit Scraper on Apify and click **Try for free** (or **Start** if you already use it).
2. Choose a **Mode**: search posts by keyword, subreddit posts, comments of posts, posts of users, or comments of users.
3. Fill in the inputs for that mode: a keyword, subreddit names, post links or usernames. Pick a sort order and time range if you need them.
4. Set **Max results** to the total number of items you want for the run.
5. Click **Start**. The run stops as soon as it reaches `maxResults`.
6. Open the dataset and export it as JSON, CSV, Excel or another format, or read it through the Apify API.

An empty input `{}` works too: it searches posts for "python".

### Input

| Field | Type | Required | What it does | Default |
|---|---|---|---|---|
| `mode` | string | required | `search`, `subreddit`, `comments`, `userPosts` or `userComments` | `search` |
| `keyword` | string | optional | Search keyword. In `search` mode it falls back to "python" when empty. In `subreddit` mode it narrows the subreddit's posts to those matching it. | none |
| `sort` | string | optional | Sort for `search`: `relevance`, `hot`, `top`, `new`, `comments` | `relevance` |
| `subredditSort` | string | optional | Sort for `subreddit`: `hot`, `new`, `top`, `comments`. Top works with the time range. | `hot` |
| `timeRange` | string | optional | For `search` and `subreddit`: `all`, `year`, `month`, `week`, `day`, `hour`. Most useful with Top. | `all` |
| `subreddits` | array of strings | for `subreddit` | Subreddit names (`python`), `r/python`, or subreddit links | none (prefill: `python`) |
| `posts` | array of strings | for `comments` | Post links (`https://www.reddit.com/r/<subreddit>/comments/<id>/...`), redd.it links, or post IDs | none |
| `commentSort` | string | optional | Order of top-level comments: `best`, `top`, `new`, `controversial`, `old` | `best` |
| `users` | array of strings | for `userPosts`, `userComments` | Usernames (`spez`), `u/spez`, or `reddit.com/user/<name>` links | none (prefill: `spez`) |
| `userSort` | string | optional | Order of each user's posts or comments: `new`, `top`, `hot`, `controversial` | `new` |
| `maxResults` | integer | optional | Maximum number of items in total for the run (1 to 5,000). You are charged per item returned. | 20 |

`maxResults` is the total across all subreddits, posts or users in the run; a run stops as soon as it is reached.

#### Search posts by keyword

```json
{
  "mode": "search",
  "keyword": "web scraping",
  "sort": "new",
  "timeRange": "week",
  "maxResults": 50
}
```

#### Top posts of subreddits

```json
{
  "mode": "subreddit",
  "subreddits": ["python", "r/learnpython"],
  "subredditSort": "top",
  "timeRange": "month",
  "maxResults": 100
}
```

#### Comments of a post

```json
{
  "mode": "comments",
  "posts": ["https://www.reddit.com/r/Python/comments/1wwv97o/my_python_magic_is_gone/"],
  "commentSort": "top",
  "maxResults": 100
}
```

#### Posts of users

```json
{
  "mode": "userPosts",
  "users": ["spez", "u/kn0thing"],
  "userSort": "top",
  "maxResults": 50
}
```

#### Comments of users

```json
{
  "mode": "userComments",
  "users": ["spez"],
  "userSort": "new",
  "maxResults": 50
}
```

### Output example

The values below are illustrative samples.

#### Post (modes `search`, `subreddit`, `userPosts`)

```json
{
  "type": "post",
  "postId": "1abc23d",
  "url": "https://www.reddit.com/r/Python/comments/1abc23d/example_post_title/",
  "title": "Example post title",
  "text": "I've been coding for a long time ...",
  "subreddit": "Python",
  "author": "example_user",
  "authorId": "1a2b3c4d5e",
  "authorAvatar": "https://www.redditstatic.com/avatars/defaults/v2/avatar_default_0.png",
  "authorAccountType": "USER",
  "score": 820,
  "upvoteRatio": 0.89,
  "commentCount": 286,
  "createdAt": "2026-10-03T19:08:43Z",
  "flair": "Discussion",
  "linkUrl": null,
  "imageUrl": null,
  "isSelfPost": true,
  "isNsfw": false,
  "isLocked": false,
  "isStickied": false
}
```

#### Comment (mode `comments`)

```json
{
  "type": "comment",
  "commentId": "k9x8y7z",
  "postId": "1abc23d",
  "parentCommentId": "k9x1a2b",
  "text": "Same here. Try building something small just for fun.",
  "author": "sample_commenter",
  "authorId": "9z8y7x6w5v",
  "authorAvatar": "https://www.redditstatic.com/avatars/defaults/v2/avatar_default_3.png",
  "authorAccountType": "USER",
  "score": 41,
  "depth": 1,
  "createdAt": "2026-10-03T21:15:02Z",
  "isStickied": false,
  "url": "https://www.reddit.com/r/Python/comments/1abc23d/example_post_title/k9x8y7z/"
}
```

#### Comment (mode `userComments`)

`userComments` items are comments with the same fields plus `postTitle`. `depth`, `parentCommentId`, `isStickied`, `authorId`, `authorAvatar` and `authorAccountType` are always empty here.

```json
{
  "type": "comment",
  "commentId": "m1n2o3p",
  "postId": "1def45g",
  "postTitle": "Example discussion thread",
  "parentCommentId": null,
  "text": "Thanks for the feedback, we are looking into it.",
  "author": "example_user",
  "authorId": null,
  "authorAvatar": null,
  "authorAccountType": null,
  "score": 15,
  "depth": null,
  "createdAt": "2026-10-05T08:30:00Z",
  "isStickied": null,
  "url": "https://www.reddit.com/comments/1def45g/_/m1n2o3p/"
}
```

### How much does it cost?

Reddit Scraper uses pay-per-event pricing. You pay a start fee for each run and a fee for each post or comment returned.

| Charge event | Free Apify plan | Paid Apify plans (Bronze and above) |
|---|---|---|
| Run start (once per run) | $0.02 | $0.005 |
| Result (each post or comment returned) | $0.003 | $0.003 |

Worked examples:

- **100 results on a paid plan:** $0.005 + 100 × $0.003 = **$0.305**.
- **1,000 results on a paid plan:** $0.005 + 1,000 × $0.003 = **$3.005**.
- **20 results on the free plan:** $0.02 + 20 × $0.003 = **$0.08**.

On the free Apify plan, a run returns at most 20 results in total; any paid Apify plan removes the limit. On the free Apify plan each account can run this Actor up to 3 times per 24 hours and 10 times per 7 days, within a small lifetime free allowance shared across all our Actors, and all free accounts share a daily free budget. When any of these limits is reached, the run stops before fetching anything and nothing is charged.

The run-start fee is charged when the first request to the data source succeeds, even if that request returns nothing. It is not charged when the data source fails from the start or rejects the IDs, or when the spending limit cannot cover it. You never pay for more than `maxResults` items, and items that were not delivered are never charged. The run stops by itself if your spending limit is reached.

### Use cases

- **Market and product research:** collect what people say about a product, a competitor or a problem, in their own words, with score and comment count to see what gets attention.
- **Brand and trend monitoring:** pull new posts about a topic every day with `sort: new`, or the top posts of a subreddit this week with `subredditSort: top` and `timeRange: week`.
- **Lead and idea discovery:** find the questions people ask in niche communities by searching a keyword inside specific subreddits.
- **Discussion analysis:** export full comment threads with `depth` and `parentCommentId` to rebuild who replied to whom.
- **User activity research:** list the posts or comments a public user has written, with the subreddit or post title for each.
- **AI and data projects:** Reddit text in Markdown with clean metadata for LLM training sets, sentiment analysis and summaries.

### Integrations and API

You can start runs from your own code through the Apify API, schedule runs (for example daily monitoring of a keyword or subreddit), and send results to other tools with Apify integrations and webhooks. Results are stored in an Apify dataset that you can download as JSON, CSV, Excel and other formats.

Python example with `apify-client`:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("clover_folktale/reddit-scraper").call(run_input={
    "mode": "subreddit",
    "subreddits": ["python", "r/learnpython"],
    "subredditSort": "top",
    "timeRange": "month",
    "maxResults": 100,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### Tips and limits

- **Stability:** the Actor retries transient errors on its own (and empty pages in `search` and `subreddit` modes) and stops cleanly instead of failing half-way.
- **Page sizes and speed:** pages hold up to 7 posts (`search` and `subreddit` modes) or up to about 8 comments (`comments` mode, often fewer), so large runs make many requests; expect roughly 2-5 seconds per page. `userPosts` and `userComments` pages hold about 23-25 items.
- **Comments mode:** comments come in the order Reddit gives them for your sort: one top-level comment per page together with its visible replies. Replies hidden behind "load more" are not expanded. Removed and deleted comments are skipped and not charged. The post is looked up first, so an unknown post is skipped.
- **Subreddit mode:** sorts are hot, newest, top (combine with a time range) and most comments. Unknown subreddits are skipped; if too many inputs return nothing, the run stops to protect your budget.
- **User modes:** comment text in `userComments` is cut by Reddit at 300 characters. The `url` of these comments opens the comment through its post. Comments of users carry no NSFW flag, so unlike posts they are not filtered. An unknown or empty user is skipped and not charged. In `userPosts`, a post on the user's own profile has `u_<name>` as its subreddit.
- **NSFW:** NSFW posts are left out, and the comments of an NSFW post are not fetched; none of this is charged.
- **Freshness:** scores and counts are what Reddit shows at the time of the run.
- **Fields that are often empty:**
  - In `search`, `imageUrl` is empty for text-only posts and `linkUrl` is `null` for self-posts.
  - In `subreddit` and `userPosts` modes, `text` is empty for link posts, which have no body.
  - In `userComments`, `depth`, `parentCommentId`, `isStickied`, `authorId`, `authorAvatar` and `authorAccountType` are always empty.
  - `author`, `authorId`, `authorAvatar` and `authorAccountType` are `null` when the account is deleted.
  - `score` is `null` when Reddit hides the score.
- **Free plan:** a run returns at most 20 results in total; any paid Apify plan removes the limit.

### FAQ

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

No. You do not need a Reddit account, API keys, proxies or cookies. Enter a keyword, subreddit, post link or username and run.

#### Can I use it as a Reddit API alternative?

It returns public Reddit posts and comments as structured JSON without a Reddit API key, which covers many common API use cases such as search, subreddit listings, comment threads and user history. It is an independent tool and is not affiliated with Reddit.

#### Is it legal to scrape Reddit?

The Actor returns only public data: public posts, public comments and public profile data (username, user ID, avatar and account type). It does not return private data such as private messages or email addresses. You are responsible for how you use the data and for following the laws and rules that apply to you.

#### How fresh is the data?

Data is collected live when you run the Actor. Scores and counts are what Reddit shows at the time of the run.

#### Why are some fields empty?

Some fields do not exist for some items. Text posts have no `linkUrl`, link posts have no `text`, deleted accounts have no author data, and `userComments` items have no depth, parent comment or author ID/avatar. See "Tips and limits" for the full list.

#### How many results can I get?

Up to 5,000 items per run, set with `maxResults`. The limit is the total across all subreddits, posts or users in the run. On the free Apify plan a run returns at most 20 results.

#### Can I schedule runs and export the data?

Yes. You can schedule runs in Apify, start them through the API, and export each dataset as JSON, CSV, Excel and other formats.

#### A field or mode is missing. What can I do?

Open an issue from the Actor page and it will be looked at.

### More tools from the same developer

- [Threads Scraper - Posts, Replies & User Profiles, No Login](https://apify.com/clover_folktale/threads-scraper)
- [Telegram Scraper - Channel Messages, Search & Info, No Login](https://apify.com/clover_folktale/telegram-scraper)
- [YouTube Scraper - Shorts, Channel Videos & Video Search](https://apify.com/clover_folktale/youtube-scraper)
- [TikTok Scraper - Video Search, Hashtags & Author Profiles](https://apify.com/clover_folktale/tiktok-scraper)
- [Zhihu 知乎 Scraper - Answers, Articles, Comments & Users](https://apify.com/clover_folktale/zhihu-scraper)
- [Weibo 微博 Scraper - Posts, Comments, User IDs & IP Location](https://apify.com/clover_folktale/weibo-scraper)

# Actor input Schema

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

What to scrape: posts by keyword, the posts of subreddits, the comments under posts, or the posts or comments a user has written.

## `keyword` (type: `string`):

Search keyword (search mode falls back to "python" when empty). In subreddit mode it is optional and narrows the subreddit's posts to those matching it.

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

Relevance, hot, top, newest, or most comments.

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

Order of each subreddit's posts. Top works with the time range below.

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

Only posts from this period. Most useful with Top.

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

Subreddit names (python), r/python, or subreddit links.

## `posts` (type: `array`):

Post links (https://www.reddit.com/r/<subreddit>/comments/<id>/...), redd.it links, or post IDs.

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

Order of the top-level comments.

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

Usernames (spez), u/spez, or reddit.com/user/<name> links.

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

Order of each user's posts or comments.

## `maxResults` (type: `integer`):

Maximum number of items to return in total for this run. You are charged per item returned. On the free Apify plan a run returns at most 20 results in total; any paid Apify plan removes the limit.

## Actor input object example

```json
{
  "mode": "search",
  "sort": "relevance",
  "subredditSort": "hot",
  "timeRange": "all",
  "subreddits": [
    "python"
  ],
  "posts": [
    "https://www.reddit.com/r/Python/comments/1wwv97o/my_python_magic_is_gone/"
  ],
  "commentSort": "best",
  "users": [
    "spez"
  ],
  "userSort": "new",
  "maxResults": 20
}
```

# Actor output Schema

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

All scraped items (JSON, CSV, Excel via the dataset API).

# 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"
    ],
    "posts": [
        "https://www.reddit.com/r/Python/comments/1wwv97o/my_python_magic_is_gone/"
    ],
    "users": [
        "spez"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("clover_folktale/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"],
    "posts": ["https://www.reddit.com/r/Python/comments/1wwv97o/my_python_magic_is_gone/"],
    "users": ["spez"],
}

# Run the Actor and wait for it to finish
run = client.actor("clover_folktale/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"
  ],
  "posts": [
    "https://www.reddit.com/r/Python/comments/1wwv97o/my_python_magic_is_gone/"
  ],
  "users": [
    "spez"
  ]
}' |
apify call clover_folktale/reddit-scraper --silent --output-dataset

```

## MCP server setup

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