# Reddit Scraper (`macrocosmos/reddit-scraper`) Actor

Scrape Reddit data, via URL, subreddit, keyword, username.

- **URL**: https://apify.com/macrocosmos/reddit-scraper.md
- **Developed by:** [Macrocosmos](https://apify.com/macrocosmos) (community)
- **Categories:** AI, Agents
- **Features:** Limited permissions
- **Stats:** 1,106 total users, 75 monthly users, 100.0% runs succeeded, 54 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

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

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

![Reddit Scraper](https://www.redditstatic.com/shreddit/assets/favicon/192x192.png)

The fastest, most affordable way to get full-fidelity Reddit data — **no API key required**.
Posts and comments with raw markdown bodies, exact parent linkage, and live scores, fresh within
minutes. One simple schema, zero setup, flat **$0.50 per 1,000 items**.

### Why this actor

| Option | What it takes |
|---|---|
| Scraping APIs | Per-request pricing that grows with your volume |
| **This actor** | **$0.50 per 1,000 posts/comments — flat, nothing to configure, start in minutes** |

- **Full fidelity** — raw markdown body (not rendered HTML), exact `parentId` for comments,
  `score` / `upvote_ratio` / `num_comments`, `isNsfw`, media URLs
- **Fresh data** — new posts and comments within minutes; live-path results carry *current*
  scores, not day-old snapshots
- **No credentials required** — no Reddit account, no API app, no proxy config
- **Resilient by design** — multiple independent data sources behind one schema; if one is down,
  another serves. You get data or an explicit signal, never a silent empty result
- **Honest failure modes** — a deleted post returns an empty dataset; a source outage returns an
  explicit `archive_unavailable` item. You can always tell them apart

### 📋 What Data Can You Extract?

Each Reddit post/comment includes:

| Field | Description |
|-------|-------------|
| `url` | Permanent Reddit URL |
| `id` | Reddit unique identifier (t3\_/t1\_ prefixed) |
| `title` | Post title (posts only) |
| `body` | Text content — raw markdown |
| `username` | Author username |
| `communityName` | Subreddit name (e.g., r/python) |
| `dataType` | Content type: "post" or "comment" |
| `parentId` | Parent post/comment id (exact, for comments) |
| `score` | Upvotes minus downvotes |
| `upvote_ratio` | Ratio of upvotes (0-1) |
| `num_comments` | Number of comments (posts only) |
| `createdAt` | ISO 8601 timestamp |
| `isNsfw` | NSFW flag |
| `media` | Array of image/video URLs (if present) |

### 🎯 Use Cases

- **Market Research** — Monitor discussions about products, brands, or topics
- **Sentiment Analysis** — Analyze community opinions and trends
- **AI Training Data** — Raw markdown text with thread structure, ready for pipelines
- **Content Aggregation** — Collect posts for newsletters or content curation
- **Trend Detection** — Track emerging topics and viral content within minutes

### 💡 Input Configuration

#### Subreddit Scraping

```json
{
  "subreddits": ["python", "MachineLearning", "datascience"],
  "limit": 25,
  "sort": "new"
}
```

**Parameters:**

- `subreddits` (array, required) - List of subreddit names (without r/ prefix)
- `limit` (number, optional) - Posts per subreddit (1-100, default: 10)
- `sort` (string, optional) - Sort order: "new", "hot", "top" (default: "new"). Only "new" is exact; "hot" and "top" return the newest posts.
- `keyword` (string, optional) - Only posts whose title or text contains this keyword, newest first

#### Single URL Scraping

Scrape a specific post or comment by URL — the fastest, cheapest mode:

```json
{
  "url": "https://www.reddit.com/r/python/comments/abc123/title/"
}
```

**Parameters:**

- `url` (string, required) - Full Reddit post or comment URL
- `liveFallback` (boolean, optional, default false) - If primary sources can't serve the item,
  scrape it from Reddit's live public feeds. Degraded data (plain-text body, no scores), so it's
  opt-in. Off: outages return an `archive_unavailable` error item instead.

### 📊 Output Example

```json
[
  {
    "url": "https://www.reddit.com/r/bittensor_/comments/1or4vcv/james_altucher_on_bittensor/",
    "id": "t3_1or4vcv",
    "title": "James Altucher on Bittensor: The Only Tech That Matters Since Bitcoin",
    "body": "# Who Is James Altucher\n\nJames Altucher is not a typical crypto influencer...",
    "username": "Internal-Patience533",
    "communityName": "r/bittensor_",
    "dataType": "post",
    "parentId": null,
    "score": 29,
    "upvote_ratio": 1.0,
    "num_comments": 3,
    "createdAt": "2025-11-07T20:10:31Z",
    "isNsfw": false,
    "media": ["https://i.redd.it/2iyvqtsu6wzf1.png"]
  }
]
```

### 🔧 Advanced Usage

#### Keyword Filtering

```json
{
  "subreddits": ["technology"],
  "keyword": "artificial intelligence",
  "limit": 50,
  "sort": "top"
}
```

#### Multiple Subreddits

```json
{
  "subreddits": ["python", "javascript", "golang", "rust"],
  "limit": 20,
  "sort": "hot"
}
```

### 📈 Reliability

One input schema, several independent sources behind it — the actor picks the best available
per request and you never manage any of it:

- **Primary**: high-throughput archive sources with rate-limit backoff and proxy rescue
- **Live path**: direct fetches that return current scores and minute-fresh content
- **Continuity**: public Atom feeds keep subreddit scraping alive even during full outages
  (`liveFallback` enables the same for single-URL mode)
- **Signals**: `archive_unavailable` items mean "our sources are down", empty datasets mean
  "the post is really gone" — automated pipelines can act on each correctly

### ❓ Common Questions

**Q: Do I need a Reddit account or API key?**
A: No. Everything is handled by the actor.

**Q: How fresh is the data?**
A: Minutes for posts and comments. Live-path results include current scores; archive-served
results can carry scores that lag up to ~36 hours for very fresh items.

**Q: Can I scrape comments?**
A: Yes — full comment objects with exact `parentId`, via direct URL.

**Q: Can I scrape private subreddits?**
A: No, only public subreddits and posts.

**Q: What does it cost?**
A: $0.50 per 1,000 posts/comments, flat. No proxies to buy, no accounts to manage, no surprise
per-request fees.

### 🛠 Self-hosting: optional full-fidelity fallback

Running your own fork? Set a **secret** environment variable `REDDIT_SESSION_COOKIE` with the
`reddit_session` cookie of a dedicated Reddit account (DevTools → Application → Cookies).
Anonymous reddit.com is bot-walled, but a normal logged-in session is not — and the cookie works
from any IP. With it set, the actor gains a full-fidelity live path (raw markdown, exact
parent_id, live scores) that engages only when the archives can't serve an item. Use a dedicated
account, not a personal one: Reddit may suspend accounts used for scraping. When unset, behavior
is unchanged.

***

**Built with ❤️ by Macrocosmos**

# Actor input Schema

## `url` (type: `string`):

Scrape a single Reddit post URL (if provided, subreddits will be ignored)

## `liveFallback` (type: `boolean`):

When the archives are down or incomplete, scrape the item from Reddit's live Atom feeds (fresh proxy IP per request, ~11 KB billed). Degraded data: no scores, plain-text body, comment parentId unknown. Off: outages return an archive_unavailable error item instead.

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

List of subreddit names to scrape (without r/ prefix)

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

Only posts whose title or text contains this keyword. Results are newest first.

## `limit` (type: `integer`):

Maximum number of posts to scrape per subreddit

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

How to sort posts. Only 'new' is exact; 'hot', 'top' and 'relevance' return the newest posts.

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

Not needed. The actor picks its own proxy when it needs one, so this setting is ignored.

## Actor input object example

```json
{
  "url": "",
  "liveFallback": false,
  "subreddits": [
    "python",
    "bittensor_"
  ],
  "keyword": "",
  "limit": 25,
  "sort": "new",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Complete dataset with all Reddit posts and comments

# 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 = {
    "url": "",
    "liveFallback": false,
    "subreddits": [
        "python",
        "bittensor_"
    ],
    "keyword": "",
    "limit": 25,
    "sort": "new",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("macrocosmos/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 = {
    "url": "",
    "liveFallback": False,
    "subreddits": [
        "python",
        "bittensor_",
    ],
    "keyword": "",
    "limit": 25,
    "sort": "new",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("macrocosmos/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 '{
  "url": "",
  "liveFallback": false,
  "subreddits": [
    "python",
    "bittensor_"
  ],
  "keyword": "",
  "limit": 25,
  "sort": "new",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call macrocosmos/reddit-scraper --silent --output-dataset

```

## MCP server setup

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