# Reddit Scraper - All In One (`thenetaji/reddit-scraper-all-in-one`) Actor

Nine Reddit reads in one Actor: a subreddit feed, the popular feed, keyword search, an account's activity and comment history, a post's comment tree, a single post, a community record, and an account profile. The mode is chosen at run time and each one fills in its own section.

- **URL**: https://apify.com/thenetaji/reddit-scraper-all-in-one.md
- **Developed by:** [The Netaji](https://apify.com/thenetaji) (community)
- **Categories:** Social media, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.55 / 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Reddit Scraper - All In One

The Actor performs any one of nine Reddit reads, chosen at run time from a dropdown: a subreddit's
post feed, the popular feed, a keyword search, an account's activity, an account's comment history,
a post's comment tree, one post's full record, one community's record, and one account's profile.
Each mode fills in its own section of the form and writes to the same dataset. No Reddit account,
application, or API credential is involved.

Each of the nine is also published as a focused Actor with the same behaviour and a form containing
only its own fields. This one exists for work that switches between modes, or that is driven from a
script where one Actor and one dataset is simpler than nine.

### Choosing a mode

`scraperType` is the only required field. Every other field belongs to one of the sections below,
and a mode reads only the fields of the sections that concern it; the rest are ignored, so leaving
them empty is correct rather than merely tolerated. Each mode raises its own error naming the
identifier it needs, so a missing username on a profile run says so.

| `scraperType` | What it saves | Fields it reads |
| --- | --- | --- |
| `subredditPosts` | Posts of one community, in a chosen order | `subreddit`, `sort`, `time`, `maxItems`, `after` |
| `popularPosts` | Posts of the cross-community popular listing | `maxItems`, `after` |
| `search` | Results for a keyword, in one of five corpora | `q`, `searchType`, `maxItems`, `cursor` |
| `userPosts` | One account's posts and comments together | `username`, `include`, `maxItems`, `after` |
| `userComments` | One account's comments | `username`, `maxItems`, `after` |
| `postComments` | One post's comment tree, flat, with depth and parent | `post_id`, `subreddit`, `commentSort`, `maxItems` |
| `postDetails` | One post's full record | `post_id`, `subreddit` |
| `subredditInfo` | One community's record and rules | `subreddit` |
| `userProfile` | One account's profile | `username` |

```json
{
  "scraperType": "subredditPosts",
  "subreddit": "r/dataisbeautiful",
  "sort": "top",
  "time": "MONTH",
  "maxItems": 50
}
```

```json
{
  "scraperType": "postComments",
  "post_id": "https://www.reddit.com/r/technology/comments/1vqcqpz/example_title/",
  "commentSort": "top",
  "maxItems": 200
}
```

### The sections of the form

- **Subreddit** — `subreddit`, `sort`, `time`. The sort order and the time window apply to the
  subreddit feed only; `subredditInfo`, `postComments`, and `postDetails` read the community name
  and nothing else from this section.
- **Post** — `post_id`, `commentSort`. Pasting a post's link supplies the community as well, so the
  Subreddit field above can stay empty for the two post modes.
- **Account** — `username`, `include`. `include` is read by `userPosts` alone.
- **Search** — `q`, `searchType`, `cursor`.
- **Limits and resuming** — `maxItems`, `after`. The four single-record modes save one row each and
  read neither.

### What lands in the dataset

The dataset holds the union of every mode's columns, and a run fills in the ones its mode returns.
Rows from the mixed and search modes carry `kind`, which states whether the row is a post, a
comment, a community, or an account; the modes that return a single shape omit it.

Post rows carry `id`, `fullname`, `permalink`, `url`, `title`, `subreddit`, `subreddit_prefixed`,
`author`, `created_at`, `score`, `upvote_ratio`, `comment_count`, `post_type`, `flair`, `media`,
`text`, and `nsfw`, among others. Comment rows carry `body`, `depth`, `parent_fullname`, `position`,
and `is_deleted`. Community rows carry `name`, `description`, `weekly_active_users`, and `rules`.
Account rows carry `karma`, `post_karma`, `comment_karma`, and `contributions`. The full list per
mode is in the focused Actor for that mode.

### Behaviour worth knowing before choosing a mode

Each mode carries the behaviour of the source it reads, and four of those behaviours change what a
result means:

- **`popularPosts` samples as much as it pages.** Two reads a moment apart return overlapping but
  not identical sets, so the run counts distinct posts and `maxItems` bounds posts saved rather than
  rows fetched. There is no fixed order to return to, and a second run will not reproduce the first.
- **`userPosts` reads one interleaved feed.** Reddit publishes an account's posts and comments as a
  single stream with no filter of its own, so `include: "posts"` is applied after the feed has been
  read. An active account runs roughly one post to ten comments, so a filtered run reads a lot of
  feed per saved row and can finish below `maxItems` while the account still has more. For comments
  specifically, `userComments` reads a dedicated feed and does not behave this way.
- **`postComments` returns part of a tree.** Reddit serves a comment tree in branches, and a run
  saves the branches it reached. Every comment row carries `tree_complete`, `unfollowed_branches`,
  `truncated_threads`, and Reddit's own `total_comments`, so a partial result cannot read as a
  complete one. `unfollowed_branches` is what a larger `maxItems` would reach; `truncated_threads`
  counts sub-threads that need their own run.
- **`search` is one request and publishes no continuation.** Reddit ranks search results rather than
  paging them by id, so `maxItems` is the only control on depth and its ceiling is 200. The `people`
  corpus in particular returns one short page and then ends; a small result there is the corpus, not
  a shortfall.

The subreddit feed's six sort orders were each checked against the same community and returned
genuinely different sets rather than one set reordered, so `sort` is worth setting deliberately.
`time` is read by `top` and `controversial` only, and steers Reddit's ranking rather than acting as a
date filter — a run sorted by `top` with `time` set to `WEEK` returned posts considerably older than
seven days. Where an exact date range matters, filter the saved rows on `created_at`.

### The nsfw column

`nsfw` has three states across every mode. `true` and `false` are Reddit's report; `null` means the
source said nothing either way, and is an absence of information rather than a statement that the
record is safe for work. On most post types the mark is simply not stated, so `null` is the common
case. No NSFW filter is offered on this Actor or on any of the nine, because filtering on a field
that is frequently unknown produces a result set that looks filtered without being filtered. Rows
can be filtered downstream on `nsfw === true`, provided `null` is treated as unknown rather than as
safe.

### Failures and partial results

An identifier that cannot be understood is rejected before any request is made, with a message
naming what was received. A request that fails ends the run; rows already saved remain in the
dataset, and the modes that page write their continuation point into the run log so a failed long
run is continued rather than restarted. A lookup that finds nothing ends the run cleanly with an
empty dataset rather than failing. Fields absent from the source are returned as `null` rather than
omitted, so the column set is the same in every row of a run.

### Cost

Charging is per row saved to the dataset, plus the platform's one-off Actor start event, at one rate
regardless of mode. The four single-record modes therefore cost less here than on their focused
Actors, where the rate reflects a whole run's work going into one row; the feed modes cost slightly
more here than on theirs. A run that saves nothing is charged for nothing beyond the start event.

### Related Actors

The nine focused Actors, each with the same behaviour and only its own fields on the form: **Reddit
Subreddit Feed Scraper**, **Reddit Popular Feed Scraper**, **Reddit Keyword Search Scraper**,
**Reddit User Activity Scraper**, **Reddit User Comment History Scraper**, **Reddit Comment Tree
Scraper**, **Reddit Post Details Scraper**, **Reddit Subreddit Details Scraper**, and **Reddit
Account Profile Scraper**.

### Support

Questions, bug reports, and requests for a field that is not here yet: thenetaji@proton.me.

# Actor input Schema

## `scraperType` (type: `string`):

Choose the dataset for this run, then fill in the section for that mode below.

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

The subreddit to read. A bare name (AskReddit), a prefixed name (r/AskReddit), or a pasted reddit.com URL are all accepted; a URL is reduced to the subreddit it names, and any sort or time in that URL is ignored in favour of the fields below.

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

The listing order to read the subreddit in. Each order returns a different set of posts, not a reordering of one set.

## `time` (type: `string`):

The period the Top and Controversial sorts rank within. It is ignored by Best, Hot, New, and Rising. Leave it empty to let the listing apply its own window.

## `post_id` (type: `string`):

The post to read. A base36 post id (1vqcqpz), a t3\_ fullname, or a pasted permalink are all accepted. A permalink is the safest form: the post id and the subreddit are read out of the same string and cannot contradict each other, and it makes the Subreddit field unnecessary.

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

The order the comment tree is read in. Leave it empty to take Reddit's own default order, which is the one reddit.com applies to a thread nobody has re-sorted.

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

The account to read. A bare name (spez), a prefixed name (u/spez), or a pasted reddit.com/user/ URL are all accepted; a URL is reduced to the account it names.

## `include` (type: `string`):

Which half of the account's activity to keep. Reddit serves posts and comments as one interleaved feed with no filter of its own, so Posts only and Comments only are applied after the feed has been read: those runs read more of the feed per saved record and can finish below Max results even on an active account.

## `q` (type: `string`):

The words to search Reddit for. Passed through as typed; quotes, operators, and punctuation are treated exactly as reddit.com's own search box treats them.

## `searchType` (type: `string`):

Which corpus to search. Each returns a different record shape: posts and media return post records, communities return subreddit records, comments return comment records, and people return account records.

## `cursor` (type: `string`):

A search continuation token, if one is already held from elsewhere. Search results are ranked rather than paged by id, so a run of this Actor cannot publish a token that resumes exactly where it stopped and does not print one; raise Max results to go deeper instead. Leave it empty in normal use.

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

The maximum number of records to save. A value of 0 removes the bound and the run continues until the source reports it has no more to give.

## `after` (type: `string`):

A continuation point from an earlier run: the value the run log prints when it stops, or the id of a record already collected. The feed continues after that record instead of starting at the top. Leave it empty to start at the top.

## Actor input object example

```json
{
  "scraperType": "subredditPosts",
  "subreddit": "AskReddit",
  "sort": "best",
  "post_id": "https://www.reddit.com/r/technology/comments/1vqcqpz/example_title/",
  "username": "spez",
  "include": "all",
  "q": "mechanical keyboard",
  "searchType": "posts",
  "maxItems": 25,
  "after": "t3_1abcdef"
}
```

# Actor output Schema

## `dataset` (type: `string`):

All records scraped by this run

# 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 = {
    "scraperType": "subredditPosts",
    "subreddit": "AskReddit",
    "post_id": "https://www.reddit.com/r/technology/comments/1vqcqpz/example_title/",
    "username": "spez",
    "q": "mechanical keyboard",
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("thenetaji/reddit-scraper-all-in-one").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 = {
    "scraperType": "subredditPosts",
    "subreddit": "AskReddit",
    "post_id": "https://www.reddit.com/r/technology/comments/1vqcqpz/example_title/",
    "username": "spez",
    "q": "mechanical keyboard",
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("thenetaji/reddit-scraper-all-in-one").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 '{
  "scraperType": "subredditPosts",
  "subreddit": "AskReddit",
  "post_id": "https://www.reddit.com/r/technology/comments/1vqcqpz/example_title/",
  "username": "spez",
  "q": "mechanical keyboard",
  "maxItems": 25
}' |
apify call thenetaji/reddit-scraper-all-in-one --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thenetaji/reddit-scraper-all-in-one"
        }
    }
}

```

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/h5M6iHgC3IrzsBU8O/builds/YUm0S9msshBDyLGNu/openapi.json
