# Reddit Scraper — Keyword & Subreddit Monitor (`leadsbrary/reddit-keyword-monitor`) Actor

Reddit scraper that monitors keywords and subreddits: returns post title, body, author, date, URL, matched keywords and optional comments as JSON, CSV or Excel. From $1.00 per 1,000 results.

- **URL**: https://apify.com/leadsbrary/reddit-keyword-monitor.md
- **Developed by:** [Alexandre Manguis](https://apify.com/leadsbrary) (community)
- **Categories:** Social media, Lead generation, AI
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 — Keyword & Subreddit Monitor

This **Reddit scraper** monitors keywords and subreddits and returns new posts as clean JSON, CSV or Excel: title, body, author, date, URL, matched keywords and a ready-to-embed `text` field. Optionally it attaches the first comments of each post. No Reddit account, login or API key is needed.

### What does it do?

Give the Actor keywords, subreddits, or both. It reads Reddit's public Atom/RSS feeds, pages through them, removes duplicates (a post matching several keywords is returned once, with all matched keywords listed) and stores one dataset row per post.

- Keywords only: Reddit-wide search for each keyword.
- Subreddits only: the newest posts of each subreddit (or hot/top if you choose that sort).
- Keywords + subreddits: search restricted to those subreddits.
- Schedule it with a time window (`maxAgeHours` or `postedAfter`) to get only what is new since the last run.

### Who is it for / use cases

- **Brand and competitor monitoring:** get alerted to every new mention of your product or a rival's.
- **Lead generation:** find people asking for a tool, a recommendation or a solution you sell.
- **Market and product research:** collect real user discussions about a topic over time.
- **AI / RAG pipelines:** each row has a `text` field (title + body, plus comments if enabled) and a stable `id` and `url` for citation.
- **Community managers:** track new posts in the subreddits you moderate or follow.

### Features

- Search by keyword (Reddit search syntax such as `"exact phrase"` works), by subreddit, or both.
- Sort by newest, relevance, top, most comments or hot, with a time window.
- Monitoring mode: `maxAgeHours` or `postedAfter` for scheduled runs.
- Optional comments per post (`includeComments`, up to 100 per post).
- Accepts subreddit names, `r/name` or full subreddit URLs.
- Deduplicated across keywords, with `matchedKeywords` per post.
- Results are saved to the dataset as they are collected; export as JSON, CSV, Excel, XML or HTML, or read through the API.

#### Known limits (please read)

Reddit's public feeds do not include votes, comment counts or flairs. The fields `score`, `numComments` and `flair` exist in the output but are always `null` (measured fill rate 0%), and `isNsfw` is always `false` because the feeds exclude NSFW posts by default. If you need vote counts, this Actor is not the right tool. Only posts are returned (no user profiles). A single query is capped at about 250 posts.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `keywords` | array of strings | — | Search terms. Provide keywords and/or subreddits. |
| `subreddits` | array of strings | — | Names, `r/name` or URLs. |
| `sort` | `new`, `relevance`, `top`, `comments`, `hot` | `new` | Sort order. |
| `timeFilter` | `hour`, `day`, `week`, `month`, `year`, `all` | `week` | Time window when sort is not `new`. |
| `maxAgeHours` | integer | — | Only posts from the last N hours. |
| `postedAfter` | ISO date-time | — | Only posts after this moment (overrides `maxAgeHours`). |
| `includeComments` | boolean | `false` | Attach the first comments of each post (one extra request per post). |
| `maxCommentsPerPost` | integer 1–100 | `10` | Comments attached per post. |
| `maxResults` | integer 1–10000 | `50` | Maximum posts in total; each post is one billed result. |
| `proxyConfiguration` | object | Apify Residential | Reddit rate-limits per IP; the Actor uses a fresh IP per request. |

Empty input (no keyword and no subreddit) fails with the message `Invalid input: Provide at least one keyword or one subreddit.`

Example input:

```json
{
  "keywords": ["web scraping"],
  "subreddits": ["webscraping"],
  "sort": "new",
  "maxAgeHours": 24,
  "maxResults": 20
}
```

### Output

Real item from a production run (long body shortened):

```json
{
  "type": "post",
  "id": "1wwjnov",
  "url": "https://www.reddit.com/r/webscraping/comments/1wwjnov/local_clicktocsv_chrome_extension_no_cloud_no/",
  "title": "Local click-to-CSV Chrome extension (no cloud, no account)",
  "body": "I kept writing one-off scripts just to grab a table off a page. …",
  "linkUrl": null,
  "subreddit": "webscraping",
  "author": "IngenuityHuge5998",
  "createdAt": "2026-10-03T10:10:25.000Z",
  "score": null,
  "numComments": null,
  "flair": null,
  "isNsfw": false,
  "matchedKeywords": ["web scraping"],
  "source": "search",
  "comments": null,
  "text": "Local click-to-CSV Chrome extension (no cloud, no account)\n\nI kept writing one-off scripts …",
  "scrapedAt": "2026-10-03T23:02:27.775Z"
}
```

#### Output fields & fill rates

Measured on a 30-item production run (keyword search):

| Field | Fill rate | Notes |
|---|---|---|
| `id`, `url`, `title`, `type` | 100% | Post id, permalink, title. |
| `createdAt`, `scrapedAt` | 100% | ISO timestamps. |
| `subreddit`, `author` | 100% | |
| `text` | 100% | Title + body (+ comments when enabled). |
| `matchedKeywords`, `source` | 100% | |
| `isNsfw` | 100% | Always `false` (NSFW excluded by the feeds). |
| `body` | 96.7% | Empty for link-only posts. |
| `comments` | 46.7% | Only filled when `includeComments` is on: `{id, author, body, createdAt}`. |
| `linkUrl` | 30% | External link of link posts. |
| `score`, `numComments`, `flair` | 0% | Not available in Reddit's public feeds; always `null`. |

#### Examples of each mode (production runs)

- **Keywords + subreddits, small run:** 5 posts returned, all with title, URL, author and date.
- **Keywords only (30 posts):** see the fill-rate table above.
- **Subreddits only** (`{"subreddits":["webscraping","r/datascience","https://www.reddit.com/r/SaaS/"],"sort":"hot","maxResults":15}`): 15 posts, `source` = `subreddit`, `matchedKeywords` empty (`[]`), `body` 93.3%, `linkUrl` 26.7%. All three name formats were accepted.
- **Monitoring** (`{"keywords":["web scraping"],"subreddits":["webscraping"],"sort":"new","maxAgeHours":72,"maxResults":10}`): 2 posts, only those inside the 72-hour window. A narrow window can legitimately return few or no posts.
- **Empty input:** fails immediately with a clear message, without charge for results.

### How to use via API

Replace `<TOKEN>` with your Apify API token.

**curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/<USERNAME>~reddit-keyword-monitor/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"keywords":["web scraping"],"sort":"new","maxAgeHours":24,"maxResults":20}'
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<TOKEN>' });
const run = await client.actor('<USERNAME>/reddit-keyword-monitor').call({
    keywords: ['web scraping'],
    subreddits: ['webscraping'],
    sort: 'new',
    includeComments: true,
    maxResults: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length);
```

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<TOKEN>")
run = client.actor("<USERNAME>/reddit-keyword-monitor").call(run_input={
    "keywords": ["web scraping"],
    "subreddits": ["webscraping"],
    "sort": "new",
    "includeComments": True,
    "maxResults": 20,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items))
```

For monitoring, create an Apify Schedule (for example hourly) with `maxAgeHours` slightly above the interval, and connect a webhook or integration to your alerts.

### Pricing

Pay per result: one result = one post row. Platform usage is billed separately by Apify and is mostly residential proxy traffic: about 107 MB per 1,000 posts, roughly $0.86 per 1,000 posts at Apify's $8/GB residential rate (estimate; higher with `includeComments`).

| Apify plan | Price per 1,000 results |
|---|---|
| Free | $1.50 |
| Bronze | $1.30 |
| Silver | $1.15 |
| Gold and above | $1.00 |

### Troubleshooting

- **Run fails with "Provide at least one keyword or one subreddit":** fill in `keywords` or `subreddits`.
- **Fewer results than `maxResults`:** the query has fewer matching posts, the time window is narrow, or the roughly 250-post cap per query was reached. Add keywords or subreddits, or widen the window.
- **A subreddit returns nothing:** it may not exist, be private or be banned; the Actor logs a warning and continues.
- **Empty or blocked responses:** Reddit rate-limits per IP. Keep the default residential proxy configuration; the Actor retries on a new IP.
- **`score` / `numComments` are null:** expected, see Known limits.

### FAQ

**Do I need a Reddit account or API key?** No. Only public feeds are read.

**Can I get vote counts or comment counts?** No, Reddit's public feeds do not expose them.

**Does it scrape comments?** Yes, optionally: the first N comments per post, without scores.

**Can I monitor continuously?** Yes, use an Apify Schedule with `maxAgeHours` or `postedAfter`.

**Is scraping Reddit legal?** The Actor collects only publicly visible data. Post authors are public usernames; handle personal data in line with GDPR and Reddit's terms, which are your responsibility as the user.

### Keywords

reddit scraper, reddit keyword monitor, reddit monitoring, subreddit scraper, reddit posts scraper, reddit comments scraper, reddit search scraper, reddit brand monitoring, reddit lead generation, reddit data for RAG, social listening, reddit API alternative

### Hashtags

\#reddit #redditscraper #keywordmonitoring #sociallistening #brandmonitoring #leadgeneration #rag #llm #subreddit #apify

# Changelog

This Actor's version history is a separate document: https://apify.com/leadsbrary/reddit-keyword-monitor/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

Search terms (Reddit search syntax allowed, e.g. "exact phrase"). Each keyword is searched separately; posts matching several keywords are returned once. Provide keywords and/or subreddits.

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

Subreddit names (webscraping, r/webscraping or a full URL). With keywords: search restricted to these subreddits. Without keywords: the newest posts of each subreddit.

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

'new' is the monitoring default. Other options use the time window below.

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

Reddit time window, used when Sort is not 'new'.

## `maxAgeHours` (type: `integer`):

Monitoring mode for scheduled runs: skip posts older than this many hours.

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

e.g. 2026-10-01T00:00:00Z. Takes precedence over 'Only posts from the last N hours'.

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

Attach the first comments of each post (one extra request per post).

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

Used when 'Include comments' is on.

## `maxResults` (type: `integer`):

Maximum posts across all keywords/subreddits (each post is one billed result).

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

Reddit rate-limits feed requests per IP; the Actor uses a fresh IP per request. Residential proxy recommended.

## Actor input object example

```json
{
  "keywords": [
    "web scraping"
  ],
  "subreddits": [
    "webscraping"
  ],
  "sort": "new",
  "timeFilter": "week",
  "includeComments": false,
  "maxCommentsPerPost": 10,
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (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 = {
    "keywords": [
        "web scraping"
    ],
    "subreddits": [
        "webscraping"
    ],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("leadsbrary/reddit-keyword-monitor").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 = {
    "keywords": ["web scraping"],
    "subreddits": ["webscraping"],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("leadsbrary/reddit-keyword-monitor").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 '{
  "keywords": [
    "web scraping"
  ],
  "subreddits": [
    "webscraping"
  ],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call leadsbrary/reddit-keyword-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,leadsbrary/reddit-keyword-monitor"
        }
    }
}
```

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/XZYHV8JtRfx56hF0t/builds/O5Ga93O4PdCcbOk3X/openapi.json
