# Reddit Subreddit Feed Scraper - Posts by Sort Order (`thenetaji/reddit-subreddit-feed-scraper`) Actor

Reads any subreddit's post listing in Best, Hot, New, Top, Rising, or Controversial order and returns one row per post: id, permalink, title, author, score, upvote ratio, comment count, flair, post type, and creation time. Paging is automatic, and a run resumes where an earlier one stopped.

- **URL**: https://apify.com/thenetaji/reddit-subreddit-feed-scraper.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 $1.70 / 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 Subreddit Feed Scraper

The Actor reads one subreddit's post listing and saves a structured record for every post it
returns. The listing is read in one of six orders (`best`, `hot`, `new`, `top`, `rising`,
`controversial`), paged automatically until the requested number of posts is reached, and can be
resumed in a later run from the point the previous one stopped. It covers post listings only;
comment trees, user profiles, and subreddit rules are not part of its output. No Reddit account,
application, or API credential is involved.

### Accepted input

| Field | Required | Default | Notes |
| --- | --- | --- | --- |
| `subreddit` | yes | — | A bare name (`AskReddit`), a prefixed name (`r/AskReddit`), or a copied reddit.com link. A link is reduced to the subreddit it names; any sort or time already in that link is discarded in favour of the fields below. |
| `sort` | no | `best` | One of `best`, `hot`, `new`, `top`, `rising`, `controversial`. |
| `time` | no | — | One of `HOUR`, `DAY`, `WEEK`, `MONTH`, `YEAR`, `ALL`. Read only by `top` and `controversial`. |
| `maxItems` | no | `100` | Total posts to save across the whole run. `0` removes the bound. |
| `after` | no | — | A resume point from an earlier run: a cursor, or the id of a post already collected. |

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

### Response fields

Each saved record carries: `id`, `fullname`, `permalink`, `url`, `title`, `subreddit`,
`subreddit_prefixed`, `subreddit_id`, `author`, `author_id`, `author_icon`, `created_at`, `score`,
`upvote_ratio`, `comment_count`, `award_count`, `domain`, `content_url`, `post_type`, `flair`,
`flair_url`, `thumbnail`, `media`, `text`, `nsfw`, `spoiler`, `locked`, `archived`, and `language`.

`id` is the post id as it appears in a permalink; `fullname` is the same id carrying Reddit's `t3_`
prefix, which is the form the `after` field accepts. `permalink` is the path Reddit states for the
post, beginning with `/r/`, and `url` is that same address in absolute form; `content_url` is where
the post itself points, which is the outbound link on a link post. `created_at` is an ISO 8601
timestamp in UTC.
`score`, `upvote_ratio`, `comment_count`, and `award_count` are values at the moment the listing was
read, and a second run over the same posts will differ from the first.

```json
{
  "id": "1abcdef",
  "fullname": "t3_1abcdef",
  "permalink": "/r/dataisbeautiful/comments/1abcdef/example_title/",
  "url": "https://www.reddit.com/r/dataisbeautiful/comments/1abcdef/example_title/",
  "content_url": "https://i.redd.it/example.jpeg",
  "title": "Example title",
  "subreddit": "dataisbeautiful",
  "subreddit_prefixed": "r/dataisbeautiful",
  "author": "example_user",
  "created_at": "2026-08-14T09:41:07.000Z",
  "score": 1842,
  "upvote_ratio": 0.94,
  "comment_count": 317,
  "post_type": "image",
  "domain": "i.redd.it",
  "flair": "OC",
  "nsfw": null
}
```

### Sort orders and the time window

All six orders were checked against the same subreddit, and each returned a distinct ordering rather
than a repackaging of one result set; `sort` is worth setting deliberately instead of leaving on the
`best` default.

Only `top` and `controversial` read `time`. Setting it alongside any other order has no effect, so
the Actor does not send it in that case and writes a line in the run log saying so. Where `time`
does apply, it steers Reddit's ranking rather than acting as a date filter, and the ages of the
returned posts do not always fall strictly inside the named period; a run sorted by `top` with
`time` set to `WEEK` returned posts considerably older than seven days. When an exact date range
matters, filter the saved records on `created_at` rather than relying on `time` to do it.

### Pagination, limits, and resuming

`maxItems` bounds the number of posts saved, not the number of requests made; paging is settled
before a response is returned, so a run asking for 150 posts is answered with up to 150 posts rather
than a first page of 25 and a stack of follow-up work. A run that receives fewer posts than it asked
for has
reached the end of what the listing will serve, not a short page, and it stops there rather than
retrying. Setting `maxItems` to `0` removes the bound and the run continues until the listing
reports the end of the feed.

The continuation point is derived from the last post returned rather than being an opaque session
token, which is what makes it durable: a run ends by writing the value to use next into the run log,
and passing that value as `after` in a later run continues the same listing from that post. This
holds across separate runs and across days, so a subreddit can be collected in scheduled instalments
instead of one long run. The vote-ranked orders reorder themselves as votes arrive, so resuming one
of them continues from a position in a listing that may have moved in the meantime; `new` is the
stable choice when instalments have to join up exactly.

### Fields that are frequently absent

`media`, `text`, and `nsfw` are the three fields most often empty, and they are empty for ordinary
reasons rather than as a failure. `text` carries the body of a self post and is empty for link,
image, and video posts, which have no body. `media` is populated only when the listing itself
carries the attachment, which link posts do not. In one run over a link-heavy subreddit, all 24
returned posts had `media`, `text`, and `nsfw` empty at once.

`nsfw` has three states, and the third one matters. `true` means Reddit reported the over-18 mark,
`false` means Reddit reported its absence, and `null` means the listing reported nothing either way.
A `null` is an absence of information, not a statement that the post is safe for work. The Actor
offers no NSFW filter for the same reason: filtering on a field that is frequently unknown would
produce a result set that looks filtered without being filtered. Records can be filtered downstream
on `nsfw === true`, provided the `null` cases are treated as unknown rather than as safe.

### Failures and partial results

A subreddit value that cannot be reduced to a community name is rejected before any request is made,
with a message naming what was received. A request that fails ends the run; posts already saved
remain in the dataset, and the run log holds the resume point, so a failed long run is continued
rather than restarted. Fields absent from the listing are returned as `null` rather than omitted, so
the column set is the same in every record.

### Cost

Charging is per post saved to the dataset, plus the platform's one-off Actor start event. A run that
saves nothing is charged for nothing beyond that start event, and a post is charged when it is
saved, never when it is merely requested. Setting `maxItems` is therefore the direct control on what
a run costs.

### Related Actors

- **Reddit Post Details Scraper** — the full record for one post found here, including the body text
  and media a listing does not carry.
- **Reddit Comment Tree Scraper** — a post's comments, flat, with the depth and parent needed to
  rebuild the thread.
- **Reddit Subreddit Details Scraper** — the community itself: description, age, activity, and rules.
- **Reddit Scraper - All In One** — the same read alongside the other eight, chosen at run time.

### Support

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

# Actor input Schema

## `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.

## `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
{
  "subreddit": "AskReddit",
  "sort": "best",
  "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 = {
    "subreddit": "AskReddit",
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("thenetaji/reddit-subreddit-feed-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 = {
    "subreddit": "AskReddit",
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("thenetaji/reddit-subreddit-feed-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 '{
  "subreddit": "AskReddit",
  "maxItems": 25
}' |
apify call thenetaji/reddit-subreddit-feed-scraper --silent --output-dataset

```

## MCP server setup

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