# Reddit Subreddit Posts Scraper (`apt_marble/reddit-subreddit-posts-scraper`) Actor

Scrape any subreddit into clean, structured data: title, full text, author, score, upvote ratio, comments, flair, awards, dates, links and every image, gallery and video URL. Sort by new, hot, top, rising or controversial, and filter by date, score, comments, flair or keyword. No account needed.

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

## Pricing

$0.45 / 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.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Subreddit Posts Scraper

Turn any list of subreddits into a clean, structured dataset of posts. Give it
`r/webdev`, `r/datascience` and `r/smallbusiness`, choose a sort (new, hot, top,
rising or controversial), and get back every post with its title, full self-text,
author, score, upvote ratio, comment count, flair, awards, creation date,
permalink, outbound link and every attached image, gallery or video URL. Filter
by date, score, comment count, flair or keyword before anything is saved, so the
dataset you pay for is the dataset you actually wanted. No Reddit account, no
login, no cookies, no browser extension — just a list of subreddits.

### What you can do with it

- **Track a niche.** Pull everything posted in your industry's subreddits each
  morning and feed it into a newsletter, a Slack digest or a spreadsheet.
- **Find customers and complaints.** Filter for posts containing "alternative
  to", "recommendation" or a competitor's name and read demand as it appears.
- **Research content that works.** Pull `top` of the year from ten subreddits,
  sort by score, and see exactly which titles, formats and flairs earn upvotes.
- **Build a training or analysis corpus.** Self-text posts come through with the
  complete body, so you get real writing, not truncated previews.
- **Monitor hiring and deal flow.** Filter `r/forhire`-style subreddits by flair
  and keyword to catch only the posts that match your services.
- **Feed a dashboard.** Run it on a schedule with a `24h` date filter and append
  a fresh slice of a community to your warehouse every day.

### What you get

One row per post. Abridged example:

```json
{
  "id": "1v9adp0",
  "fullId": "t3_1v9adp0",
  "type": "post",
  "title": "Five Languages, One Pyramid, Zero Practical Value",
  "url": "https://www.reddit.com/r/programming/comments/1v9adp0/five_languages_one_pyramid_zero_practical_value/",
  "permalink": "/r/programming/comments/1v9adp0/five_languages_one_pyramid_zero_practical_value/",
  "subreddit": "programming",
  "subredditSubscribers": 6942111,
  "author": "Refresh98370",
  "authorFlair": null,
  "body": null,
  "linkUrl": "https://example.dev/five-languages-one-pyramid",
  "domain": "example.dev",
  "score": 1,
  "upvoteRatio": 1,
  "numComments": 0,
  "totalAwards": 0,
  "flair": null,
  "createdAt": "2026-07-28T20:35:11.000Z",
  "isSelfPost": false,
  "isVideo": false,
  "isGallery": false,
  "over18": false,
  "stickied": false,
  "locked": false,
  "thumbnail": null,
  "media": [],
  "queriedSubreddit": "programming",
  "listingSort": "new",
  "listingTimeRange": null,
  "listingRank": 1,
  "scrapedAt": "2026-07-28T20:35:20.682Z"
}
```

Posts with media carry a `media` array — a gallery post returns every image in
order with its dimensions and captions, and a Reddit-hosted video returns the
direct MP4 plus the DASH and HLS stream URLs, the duration and whether it has an
audio track.

### Input reference

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `subreddits` | list of strings | — (required) | Subreddits to scrape. `python`, `r/python`, `/r/python/` and full subreddit or post URLs all work. `all` and `popular` read Reddit's site-wide feeds. |
| `sort` | select | `new` | `new`, `hot`, `top`, `rising` or `controversial`. |
| `time` | select | `all` | Time window for `top` and `controversial`: `hour`, `day`, `week`, `month`, `year`, `all`. Ignored by the other sorts. |
| `maxPostsPerSubreddit` | integer | `100` | How many posts to save per subreddit, up to 1,000. |
| `postedAfter` | string | empty | Keep only posts newer than this. Accepts a date (`2026-01-31`), a timestamp, or a relative window such as `24h`, `7d`, `4w`. |
| `minScore` | integer | empty | Keep only posts with at least this score. |
| `minComments` | integer | empty | Keep only posts with at least this many comments. |
| `flairFilter` | list of strings | empty | Keep only posts whose flair matches one of these. Case-insensitive; a partial match counts. |
| `keywordFilter` | list of strings | empty | Keep only posts whose title or body contains one of these words or phrases. Case-insensitive. |
| `includeNsfw` | boolean | `true` | Set to false to drop posts marked 18+. |
| `skipStickied` | boolean | `true` | Skips the moderator-pinned posts at the top of a subreddit. |
| `includeMedia` | boolean | `true` | Adds the `media` array with direct image, gallery and video URLs. |
| `maxConcurrency` | integer | `4` | How many subreddits are read at the same time. |
| `proxyCountry` | select | `us` | Country to appear to browse from. |

### Output fields

| Field | Type | Description |
| --- | --- | --- |
| `id` / `fullId` | string | Reddit post id (`1v9adp0`) and its full name (`t3_1v9adp0`). |
| `title` | string | Post title. |
| `url` | string | Permanent link to the post on Reddit. |
| `permalink` | string | Path-only version of the same link. |
| `subreddit` | string | Subreddit the post lives in. |
| `subredditId` / `subredditSubscribers` | string / number | Subreddit id and subscriber count at scrape time. |
| `author` / `authorId` / `authorFlair` | string | Poster's username, account id and flair. |
| `body` / `bodyHtml` | string | Full self-text of a text post (null for link posts). |
| `linkUrl` / `domain` | string | Outbound link of a link post and its domain. |
| `score` / `upvoteRatio` | number | Net upvotes and the share of votes that were upvotes. |
| `numComments` / `numCrossposts` | number | Comment and crosspost counts. |
| `totalAwards` | number | Awards received. |
| `flair` | string | Link flair text. |
| `createdAt` / `editedAt` | date | When the post was published, and edited if it was. |
| `isSelfPost` / `isVideo` / `isGallery` / `isCrosspost` / `isOriginalContent` | boolean | Post type flags. |
| `over18` / `spoiler` / `locked` / `stickied` / `archived` | boolean | Moderation and status flags. |
| `distinguished` / `removedBy` | string | Moderator/admin distinction, and why a post was removed if it was. |
| `thumbnail` | string | Thumbnail image URL when Reddit generated one. |
| `media` | array | Direct image, gallery, GIF and video URLs, with dimensions, duration, and the DASH/HLS streams for Reddit-hosted video. |
| `queriedSubreddit` / `listingSort` / `listingTimeRange` / `listingRank` | string / number | Which of your inputs produced this row and where it sat in that listing. |
| `scrapedAt` | date | When the run collected the post. |

### Pricing

This actor is **pay per event**. There is exactly one event: a **dataset item** —
one charge for each post saved to your dataset. Nothing else is billed.

Posts that fail your filters are never saved, so they are never charged: reading
1,000 posts to find the 40 that match your keyword costs 40 items, not 1,000.
Subreddits that turn out to be private, restricted or missing cost nothing. If
you set a maximum cost for a run, the actor stops cleanly as soon as that budget
is spent rather than overshooting it.

### Limits and what this actor cannot do

Honest limits, all verified against Reddit's live API:

- **About 1,000 posts per listing.** Reddit stops any single listing cursor at
  roughly 1,000 records — page 10 comes back short and the cursor ends. That is
  Reddit's limit, not the actor's, and no tool can page past it. To go deeper
  than 1,000 posts in one community, split the job: run `top` with several
  different time ranges (`year`, `month`, `week`), which are separate cursors and
  return different sets of posts.
- **Filters are applied after fetching.** Reddit's listings accept only a sort
  and a time range, so score, comment, flair, keyword and date filters are
  applied by the actor as posts arrive. When a filter is set the actor keeps
  reading (up to the 1,000-post ceiling) until it has found the number of posts
  you asked for.
- **No "users online now".** Reddit's API no longer exposes the live active-user
  count, so it is not in the output. Subscriber counts are.
- **Private, Premium-only, quarantined and banned subreddits cannot be read.**
  They are reported in the run log and skipped; the rest of your list still runs.
- **A misspelled or removed subreddit is reported as unavailable.** Reddit
  answers a "page not found" page for names that do not exist rather than an
  empty result, so check the spelling if a subreddit comes back with nothing.
- **No moderator-only data.** Mod lists, mod queues, removal reasons beyond the
  public `removedBy` category, and anything else that requires moderator
  permissions are not available.
- **Comments are not included.** Each row is a post plus its comment *count*. Use
  the companion Reddit Comments Scraper for full threads.
- **Vote counts are Reddit's fuzzed numbers.** Reddit deliberately adds noise to
  scores; `view_count` is always empty on its API and is therefore not reported.
- **Edited posts** report the edit timestamp only when Reddit records one.

### FAQ

**Do I need a Reddit account or API credentials?**
No. Nothing to create, connect or paste — you give it subreddit names and run it.

**Does it need cookies, a login or a browser session?**
No. It reads Reddit's own public JSON API, so there is no login step and nothing
to keep alive between runs.

**How fast is it?**
Reddit returns up to 100 posts per request, usually in well under a second, and
several subreddits are read in parallel. A 100-post pull from two subreddits
takes a handful of seconds; 1,000 posts from one subreddit is ten requests.

**Can I run it on a schedule?**
Yes. A common setup is a daily run with `postedAfter` set to `24h` and `sort` set
to `new`, which appends only the last day's posts. On a `new` sort the actor
stops a subreddit as soon as it reads past your cut-off, so scheduled runs stay
cheap.

**Can I get more than 1,000 posts from one subreddit?**
Not from a single listing — that is Reddit's ceiling. Run the same subreddit
several times with different sorts and time ranges (`top`/`year`, `top`/`month`,
`new`), and merge the results; each combination is a separate cursor with its own
1,000 records.

**Does it include NSFW subreddits and posts?**
Yes, they are returned by default, and `includeNsfw: false` drops them.

**What happens if one subreddit in my list is private or misspelled?**
It is logged and skipped, and the run continues with the rest. You are not
charged for a subreddit that returned nothing.

# Actor input Schema

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

The subreddits to scrape. Paste names (python), r/ handles (r/python) or full subreddit URLs — all three work. Use all or popular to read Reddit's site-wide feeds.

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

Which listing to read. New returns the most recent posts, Hot the ones Reddit is currently pushing, Top the highest scoring in the chosen time range, Rising the ones gaining traction right now, Controversial the most divisive.

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

Time window for the Top and Controversial sorts. Ignored by New, Hot and Rising.

## `maxPostsPerSubreddit` (type: `integer`):

How many posts to save per subreddit. Reddit itself stops any single listing at about 1,000 posts, so that is the ceiling.

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

Keep only posts published after this point. Accepts a date (2026-01-31), a full timestamp, or a relative window such as 24h, 7d or 4w. Leave empty for no date limit.

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

Keep only posts with at least this many upvotes (score = upvotes minus downvotes). Leave empty to keep every post.

## `minComments` (type: `integer`):

Keep only posts with at least this many comments. Useful for finding threads with real discussion in them.

## `flairFilter` (type: `array`):

Keep only posts whose link flair matches one of these values. Case-insensitive, and a partial match counts (Hiring matches \[Hiring] - Remote). Leave empty to keep every flair.

## `keywordFilter` (type: `array`):

Keep only posts whose title or body contains at least one of these words or phrases. Case-insensitive. Leave empty to keep every post.

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

Keep posts marked 18+. Turn this off to drop them.

## `skipStickied` (type: `boolean`):

Skip the moderator-pinned posts that sit at the top of most subreddits (rules threads, weekly megathreads). Turn this off to include them.

## `includeMedia` (type: `boolean`):

Add a media array to every post with direct image, gallery, GIF and video URLs (including the DASH and HLS streams for Reddit-hosted video).

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

How many subreddits to read at the same time. Higher is faster on long lists; 4 is a good balance.

## `proxyCountry` (type: `string`):

Country to appear to browse from. Reddit content is the same worldwide, so change this only if you want traffic to originate somewhere specific.

## Actor input object example

```json
{
  "subreddits": [
    "programming",
    "r/webdev",
    "https://www.reddit.com/r/datascience/"
  ],
  "sort": "new",
  "time": "all",
  "maxPostsPerSubreddit": 100,
  "postedAfter": "7d",
  "flairFilter": [
    "Discussion",
    "Hiring"
  ],
  "keywordFilter": [
    "hiring",
    "open source"
  ],
  "includeNsfw": true,
  "skipStickied": true,
  "includeMedia": true,
  "maxConcurrency": 4,
  "proxyCountry": "us"
}
```

# Actor output Schema

## `dataset` (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": [
        "programming",
        "webdev"
    ],
    "sort": "new",
    "time": "all",
    "maxPostsPerSubreddit": 100,
    "maxConcurrency": 4,
    "proxyCountry": "us"
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/reddit-subreddit-posts-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": [
        "programming",
        "webdev",
    ],
    "sort": "new",
    "time": "all",
    "maxPostsPerSubreddit": 100,
    "maxConcurrency": 4,
    "proxyCountry": "us",
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/reddit-subreddit-posts-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "programming",
    "webdev"
  ],
  "sort": "new",
  "time": "all",
  "maxPostsPerSubreddit": 100,
  "maxConcurrency": 4,
  "proxyCountry": "us"
}' |
apify call apt_marble/reddit-subreddit-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=apt_marble/reddit-subreddit-posts-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/gG94OzEW3FuEpmkEP/builds/8H4KqjU5RHxQWiTyk/openapi.json
