# Reddit Scraper & API: Posts, Comment Trees, Search, Monitoring (`quarra/reddit-scraper`) Actor

Scrape Reddit posts, complete comment trees, searches, subreddits and users without login or API key. Whole threads as Markdown for LLMs, comment search, strict keyword matching and new-only monitoring. Errors and filtered posts are not charged.

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

## Pricing

from $1.19 / 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

**Reddit Scraper** collects **Reddit posts and complete comment threads without login, cookies or API key**. Give it
subreddits, search queries, post URLs or usernames, and get posts, **every comment with its exact parent and depth**,
user profiles and post or comment history, as JSON, CSV or Excel, or through the Apify API. It works as a **Reddit API
alternative** for anyone who needs the whole conversation and wants to know when something went wrong.

Errors, duplicates and filtered posts are not charged, and a run that collects nothing costs only the start ($0.005 per GB of memory, 1 GB by default).

### What you get

- **Complete comment trees**: on a 1,650-comment thread, **263 of 263** recent comments down to depth 12, each with
  `parentId`, `depth` and `rootCommentId`, so the thread can be rebuilt in a spreadsheet.
- **Whole threads as Markdown for LLMs** (`outputFormat: threadMarkdown`): one record per post with its comment tree,
  7.2 times fewer characters than the same thread as JSON records, at the same price.
- **Only what is new** (`onlyNew`): schedule the Actor and each run returns and charges only posts and comments that
  earlier runs did not return.
- **Search that contains your words**: strict search keeps only posts with every word of your query, as whole words;
  rejected posts are not charged. Comment search finds comments anywhere on Reddit or in one subreddit.
- **Media decoded** on posts and comments: gallery images in order, MP4/HLS/DASH video URLs, polls, flair,
  edited and deleted status.

### How to scrape Reddit

1. Add subreddits (`technology`, `r/LocalLLaMA`), search queries, post URLs or usernames.
2. Choose a sort and a time range, and whether to include comments.
3. Optionally filter by date, flair, post type, keywords to exclude, or turn on strict search.
4. Run, then export the dataset, or call it from the API, Make, Zapier, n8n or an AI agent through MCP.
5. To monitor, turn on "Only new since the last run" and add a schedule in Apify Console.

### Input examples

The 50 best posts of a subreddit this week, each with its discussion as Markdown, for an LLM:

```json
{
  "subreddits": ["LocalLLaMA"],
  "sort": "top",
  "timeFilter": "week",
  "maxPostsPerSource": 50,
  "includeComments": true,
  "maxCommentsPerPost": 200,
  "outputFormat": "threadMarkdown"
}
```

Latest posts of two subreddits from the past 7 days, questions only, without giveaways:

```json
{
  "subreddits": ["selfhosted", "homelab"],
  "sort": "new",
  "postedAfter": "7 days",
  "maxPostsPerSource": 500,
  "flairs": ["Need Help"],
  "excludeKeywords": ["giveaway", "\"discount code\""]
}
```

### Output example

A real comment from our benchmark thread, with the author replaced (some fields left out):

```json
{
  "type": "comment",
  "id": "pd0smho",
  "url": "https://www.reddit.com/r/technology/comments/1wu4lnz/palantir_ceo_alex_karp_quietly_purchased_37000/pd0smho/",
  "postId": "1wu4lnz",
  "postTitle": "Palantir CEO Alex Karp quietly purchased 37,000 acres of forests in Sweden—and locals found out when hunters lost leases to use the property",
  "parentId": "t1_pd02xdu",
  "parentType": "comment",
  "rootCommentId": "pczzr78",
  "depth": 3,
  "subreddit": "technology",
  "author": "example_user",
  "body": "Not a Swede, but don’t want him there either. ",
  "createdAt": "2026-09-30T15:31:09Z",
  "score": 920,
  "scorePerHour": 8.72,
  "isDeletedOrRemoved": false,
  "scrapedAt": "2026-10-05T00:58:22Z"
}
```

The same kind of data as one Markdown record (`threadMarkdown`, the 2012 Obama AMA, shortened, commenters replaced):

```json
{
  "type": "thread",
  "id": "z1c9z",
  "title": "I am Barack Obama, President of the United States -- AMA",
  "numComments": 22719,
  "commentsIncluded": 300,
  "threadComplete": false,
  "markdown": "# I am Barack Obama, President of the United States -- AMA\nr/IAmA · u/PresidentObama · 216183 points · 22719 comments · 2012-08-29\n[…]\n- u/example1 (2025, 2012-08-30): > By the way, if you want to know what I think about this whole reddit experience - NOT BAD!\n  - u/example2 (154, 2012-08-31): He's the president, he knows everything... Like Jesus.\n[…]"
}
```

Field names stay the same between runs: a value Reddit does not provide is `null`, not missing. Each failed input
gets a free `error` record with its reason in plain English.

### Compared with two of the most used Reddit scrapers

Measured on Apify on October 5, 2026 on real threads; Free plan prices from each Store page and features as described
in each Actor's README on October 9, 2026. Both are good tools; other scrapers update often, so these figures are dated.

| | This Actor | Alternative A | Alternative B |
|---|---|---|---|
| Recent comments of a 1,650-comment thread | 263/263, depth 0 to 12 | 245/263, depth 9 max | 224/263, depth 9 max |
| Full thread, price | about $1.57 | about $2.33 | about $3.14 |
| Price per 1,000 comments, Free plan | $1.00 | $1.49 | $2.00 |
| Price per 1,000 posts, Free plan | $1.50 | $1.49 | $2.00 |
| Run start (1 GB, the default) | $0.005 | none | $0.02 |
| Whole thread as one Markdown record | yes | not described | not described |
| Built-in "only new since last run" | yes | deduplicate on stable keys yourself | deduplicate on stable keys yourself |
| Comment search by keyword | yes | not described | yes |

On a real thread, comments are nearly all of the bill, which is why the gap grows with discussion size.

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

You pay per result. Platform costs are included.

| Apify plan | Posts | Comments | User or community profiles |
|---|---|---|---|
| Free | $1.50 / 1,000 | $1.00 / 1,000 | $1.50 / 1,000 |
| Starter (Bronze) | $1.39 / 1,000 | $0.93 / 1,000 | $1.39 / 1,000 |
| Scale (Silver) | $1.29 / 1,000 | $0.87 / 1,000 | $1.29 / 1,000 |
| Business (Gold) and above | $1.19 / 1,000 | $0.80 / 1,000 | $1.19 / 1,000 |

Plus the start: $0.005 per GB of run memory ($0.005 at the default 1 GB). The Markdown format is charged the same way (one post, plus one comment per comment in the
record). In monitoring mode you only pay for what is new. 1,000 posts with all their comments (about 50,000
comments) come to about $51.50 on the Free plan and $41.20 on Business. You can set a maximum charge per run; the
Actor stops at that cap and keeps what it collected.

### Use cases

- **Brand and product monitoring**: posts and comments that name your product, on a schedule, only what is new.
- **LLM and AI agent input**: whole threads as compact Markdown, with a typed output schema an agent can read first.
- **Market and audience research**: what a community asks about, complains about and recommends.
- **AI and NLP datasets** with the reply structure intact, for sentiment analysis, topic modeling or summarization.
- **Finding the people who matter** in a niche, with their history, karma and activity.
- **Academic work** that needs a reproducible collection and a record of what could not be retrieved.

### Limits

- Reddit lists about 1,000 posts per subreddit sort and about 250 per search. The "Go beyond Reddit's listing cap"
  option combines sorts and time ranges (3,000 unique posts from one subreddit in our tests), but a subreddit's full
  history since its creation is not reachable.
- Reddit does not serve deleted comments that have no replies; they are counted in the run summary, not returned.
- Quarantined communities are visible to logged-in accounts only. The Actor reports them and does not log in.
- Strict search checks words, not relevance; quotes around a phrase fix most false matches.

### FAQ

#### Is there a free Reddit API?

Reddit's official Data API requires an approved app, and commercial use is paid. On September 30, 2026, Reddit
announced that it stops accepting new API access requests on October 31, 2026 and closes the remaining public access
in March 2027, asking apps to move to its Developer Platform. This Actor reads what anyone can see on Reddit without
logging in: no app, no key, no account.

#### Is scraping Reddit legal?

The Actor collects what anyone can see on Reddit without logging in. In hiQ v. LinkedIn, the Ninth Circuit held
that scraping publicly accessible pages likely does not violate the US anti-hacking law (CFAA). The results can still contain personal data (usernames, posts)
covered by the GDPR and similar laws. Reddit's terms and privacy law apply to how you use the data. Collect what you
need for a legitimate purpose, and ask a lawyer if you are unsure.

#### How do I get only new posts every day?

Turn on "Only new since the last run", then create a schedule in Apify Console (daily or hourly). Add an integration
(e-mail, Slack, webhook) to be told when a run returns something.

#### Which output format should I give an AI agent?

`threadMarkdown` when it has to read discussions, the default when it has to compute on fields (scores, dates,
authors).

#### How fast is it?

50 posts of a subreddit in 4.7 to 6.0 seconds of run time on Apify, start included. A 1,650-comment thread in under
a minute.

#### Can I get more than 1,000 posts from a subreddit?

Yes. Turn on "Go beyond Reddit's listing cap", and add date filters if you need a precise window.

#### Why did my run return nothing?

The status message, the free `error` records and the `OUTPUT` record give the reason for each input: not found,
banned, private, quarantined, nothing in your date window, nothing matching strict search. Such a run ends as
Succeeded and costs only the start ($0.005 at the default 1 GB of memory).

#### Something broke, or a field is missing?

Open an issue in the Issues tab. We reply within two business days.

### More data tools from Quarra

| Actor | What it does |
|---|---|
| [Threads Scraper](https://apify.com/quarra/threads-scraper) | Full post history with view counts, replies, profiles and keyword search on Threads |
| [Google Trends Scraper](https://apify.com/quarra/google-trends-scraper) | Interest over time, by region, related queries and the full Trending now list |

# Actor input Schema

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

Subreddit names (technology, r/technology), URLs, or several joined by + (pics+homelab, one listing). Posts are listed with the sort and time range below.

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

Keywords searched on Reddit, one query per line, as typed in Reddit's search box. Quotes keep a phrase together ("home assistant"); Strict search below enforces every word.

## `commentSearchQueries` (type: `array`):

Find COMMENTS containing your keywords, anywhere on Reddit (or in the subreddit above), one query per line: each comment with its text, score, date, parentId and its post's title and URL. Strict search and excluded keywords apply to the comment's text. Reddit's comment search ignores dates except with Search sort New: use New with a time range or date window to monitor.

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

Optional. Restrict every search query and comment search to one subreddit (selfhosted, r/selfhosted or its URL).

## `strictSearch` (type: `boolean`):

Reddit's search returns loosely related posts (for home assistant, 17 of the top 100 contain it). When on, a post is kept only if its title or text contains EVERY word of the query, as whole words (ai never matches said; case and accents ignored). "Quotes" require a phrase, -word excludes, OR and parentheses group alternatives. Other sorts of the same time range are read to reach your limit. Rejected posts are never charged (counted in OUTPUT as filteredOut).

## `strictMatchIn` (type: `string`):

Where the words of a strict search and the excluded keywords must (or must not) appear.

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

Reddit usernames (spez, u/spez, @spez) or profile URLs: profile card plus post and comment history.

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

Any Reddit URL, one per line (plain strings; {"url": …} objects are accepted too). A post URL, redd.it link, share link, gallery or v.redd.it link, or comment permalink returns the post and its COMPLETE comment tree. Subreddit (or just r/name, u/name), search (posts, comments, communities) and user URLs work too.

## `refreshPosts` (type: `array`):

Post URLs, redd.it links or post IDs (1abc234) to re-read without their comments: current score, comment count, flair, edited or removed status. 100 posts per request (1,000 posts = 10 requests). Only maxItems limits this list.

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

Posts per subreddit or search query, comments per comment search, posts and comments per user history. Reddit lists ~1,000 posts per subreddit sort and ~250 per search; enable 'Go beyond Reddit's listing cap' for more. With 'Only new', this is the window watched.

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

Optional hard cap for the whole run, counted in charged results (posts + comments + profiles). Respected exactly. Empty = no global cap.

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

How subreddit posts are ordered. Use Top or Controversial with a time range. For monitoring, New is the fastest and cheapest.

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

How search results are ordered. Comment searches use Relevance, Top or New (Hot and Most comments fall back to Relevance).

## `timeFilter` (type: `string`):

Used by the Top and Controversial subreddit sorts and by searches (comment search: with the New sort only).

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

Only items created after this date (2026-09-01, or relative: 7 days). Applies to posts, user history and listing URLs.

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

Only items created before this date.

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

Include posts marked NSFW (18+). Off by default.

## `excludeKeywords` (type: `array`):

Drop every post whose title or text contains one of these words or phrases, one per line (whole words, case and accents ignored; a comma belongs to the phrase, as in 10,000 views). Dropped items are not charged. Comment trees are not filtered; comments found by comment search are.

## `postTypes` (type: `array`):

Keep only these post types (mediaType). Empty = all types. Dropped posts are not charged.

## `flairs` (type: `array`):

Keep only posts with one of these flairs, written as on Reddit (Question, Help; case and accents ignored). Empty = all flairs. Dropped posts are not charged. In a search, the flair:"…" operator lets Reddit filter first.

## `deepScrape` (type: `boolean`):

When you need more posts than Reddit lists (~1,000 per subreddit sort, ~250 per search), combine extra sorts and time ranges and keep unique posts only. Posts outside the chosen sort may be added: use the date filters for a precise window.

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

For every post found in subreddits, searches, user histories and listing URLs, also scrape its complete comment tree (each comment has parentId and depth). Post URLs always include their comments.

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

Empty = the complete thread, even with tens of thousands of comments. 0 returns the post only. With Only new, each run returns up to this many comments of a thread that earlier runs did not return.

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

Empty = all levels. 0 = top-level comments only, 1 = plus direct replies, and so on. Deeper branches are not even requested (faster).

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

Order of comments inside each thread (Best is Reddit's default).

## `commentsPostedAfter` (type: `string`):

Only comments written after this date (2026-10-01, or 12 hours), in threads and user histories. The tree is still walked, so a new reply under an old comment is found (reading stops after 10,000 comments in a row outside your dates); only matching comments are saved and charged.

## `commentsPostedBefore` (type: `string`):

Only comments written before this date.

## `includeUserProfile` (type: `boolean`):

For each user: one profile record (karma, account age, verified, followers) before their history.

## `userContent` (type: `string`):

Which part of a user's history to scrape.

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

Thread Markdown: one record per post with its whole comment tree as indented Markdown (author, score, date, text), about 7 times fewer characters than the same thread as JSON. A thread too big for one record (over ~20,000 comments) comes as numbered parts. Same price: 1 post + 1 comment per comment included. Profiles stay normal records.

## `onlyNew` (type: `boolean`):

Remember what earlier runs of the same watch returned and output only new posts and new comments (with Include comments, also comments that earlier runs did not return under posts already seen; with Max comments per post, each run adds up to that many of them per thread, oldest included). Nothing already delivered is charged again, even after a run that timed out, was aborted or overlapped another. One run per watch at a time: a second one does nothing and charges nothing. Memory: key-value store quarra-reddit-watch of your account. Set a watch name, then schedule the Actor.

## `watchName` (type: `string`):

Name of this watch's memory for 'Only new'. Recommended: runs with the same name share it even when you add or remove sources. Empty: the memory belongs to this exact set of inputs and filters, so adding a source starts a new watch that returns everything again (limits, output format and proxy don't count).

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

Connection. Keep the default (automatic). Costs are included in the price.

## Actor input object example

```json
{
  "subreddits": [
    "technology"
  ],
  "strictSearch": false,
  "strictMatchIn": "titleOrText",
  "maxPostsPerSource": 20,
  "sort": "hot",
  "searchSort": "relevance",
  "timeFilter": "all",
  "includeNsfw": false,
  "deepScrape": false,
  "includeComments": false,
  "commentSort": "confidence",
  "includeUserProfile": true,
  "userContent": "overview",
  "outputFormat": "items",
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Every record: posts, comments, profiles, communities and Markdown threads, each with a type field.

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

Posts only (type post).

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

Comments with parentId, depth and rootCommentId (type comment).

## `threads` (type: `string`):

With outputFormat threadMarkdown: one record per post with its whole comment tree as Markdown.

## `summary` (type: `string`):

Per-input status, errors, posts dropped by filters, per-thread completeness and watch statistics.

# 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": [
        "technology"
    ],
    "maxPostsPerSource": 20,
    "includeComments": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("quarra/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": ["technology"],
    "maxPostsPerSource": 20,
    "includeComments": False,
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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