# Reddit Keyword Search (`morph_coder/reddit-keyword-search`) Actor

Search Reddit posts by keywords (one search per keyword). Returns post title, body, votes, subreddit, and URL. Optional keyword relevance filter.

- **URL**: https://apify.com/morph\_coder/reddit-keyword-search.md
- **Developed by:** [Morph Coder](https://apify.com/morph_coder) (community)
- **Categories:** Automation, Social media
- **Stats:** 12 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $3.00 / 1,000 reddit-posts

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Keyword Search

**Actor ID:** `morph_coder~reddit-search`

Search **public** Reddit posts by keywords. Each keyword runs as a separate Reddit search; matching posts are opened for full metadata (title, body, author, votes, subreddit, URL).

> **Disclaimer:** This is an **unofficial** tool. It is **not affiliated with, endorsed by, or sponsored by Reddit, Inc.** Users are responsible for complying with [Reddit's User Agreement](https://www.redditinc.com/policies/user-agreement), applicable laws, and data-protection regulations in their jurisdiction.

### What it does

Use this Actor to monitor brand mentions, track topics, or collect publicly visible Reddit posts that match your keywords — for market research, social listening, or content discovery.

- Runs **one Reddit search per keyword** (e.g. separate searches for `adidas` and `nike`)
- Visits each post page and saves structured data to a dataset
- Deduplicates posts found by multiple keywords
- Optional **keyword relevance filter** for cleaner results
- Residential proxy support (recommended for stable runs)

### Legal notice & data privacy

This Actor collects **only publicly available information** that any visitor can see on Reddit without logging in — for example post titles, public post text, subreddit names, public usernames, vote counts, and public URLs.

It does **not**:

- Access private messages, private subreddits, or content behind login walls
- Bypass authentication or technical access controls
- Collect special categories of personal data by design

**User responsibilities:** You must use this Actor lawfully and only for purposes permitted by Reddit's terms and applicable regulations (including GDPR and similar privacy laws where they apply). Do not use collected data to identify, profile, or contact individuals without a valid legal basis. You are responsible for retention, lawful processing, and honoring data-subject rights for any personal data you obtain. The Actor developer does not control how you use the output.

### Features

- Separate search per keyword with `matchedKeyword` and `searchQuery` in output
- Sort and time range (`new`, `day`, `week`, etc.)
- Optional subreddit filter
- `filterByKeywords` — save only posts where a keyword appears in title, body, or URL
- `postDateLimit` — skip posts older than a given date
- Pay per saved post (`reddit-post` or `reddit-post-filtered` events)
- Fail-fast crawling (no retries) — tune reliability via delays and proxy

### Input

| Field | Default | Description |
|-------|---------|-------------|
| `keywords` | `["adidas", "nike"]` | Keywords or phrases — **one Reddit search each** (required) |
| `sort` | `new` | `relevance`, `hot`, `top`, `new`, `comments` |
| `time` | `day` | `hour`, `day`, `week`, `month`, `year`, `all` |
| `maxPosts` | `10` | Maximum posts saved to the dataset (never exceeded) |
| `includeNSFW` | `true` | When `true`, Reddit search includes 18+ (NSFW) posts (`include_over_18=on`). Set `false` to exclude adult-marked content from search results. |
| `subreddit` | — | Limit search to one subreddit (name without `r/`, e.g. `soccer`) |
| `filterByKeywords` | `false` | When `true`, only posts containing at least one keyword in title, body, or URL are saved and charged. **Recommended for cleaner results.** |
| `postDateLimit` | — | Skip posts older than this date. ISO 8601, e.g. `2026-05-20` or `2026-05-20T00:00:00.000Z` (UTC). Leave empty to disable. |
| `proxy` | RESIDENTIAL | Apify proxy — residential recommended |
| `requestDelayMs` | `1000` | Delay before each page load (ms, ±25% jitter). Increase to 1500–3000 if you see rate limits. |
| `maxConcurrency` | `4` | Parallel browser tabs (1–10) |
| `debugMode` | `false` | Verbose logging |

#### Recommended input for Store / production

```json
{
  "keywords": ["your brand", "your product"],
  "sort": "new",
  "time": "day",
  "maxPosts": 50,
  "filterByKeywords": true,
  "includeNSFW": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Output

One dataset row per saved post:

| Field | Description |
|-------|-------------|
| `dataType` | Always `post` |
| `username` | Public Reddit username of the author |
| `authorFlair` | Author flair text, or `null` |
| `title` | Post title |
| `body` | Post text (`""` for link/image posts with no selftext) |
| `upVotes` | Upvote count |
| `numberOfComments` | Comment count |
| `communityName` | Subreddit (e.g. `r/soccer`) |
| `url` | Canonical public post URL |
| `searchQuery` | Reddit query that found this post |
| `matchedKeyword` | Input keyword from that search |

#### Example

```json
{
  "dataType": "post",
  "username": "example_user",
  "authorFlair": null,
  "title": "Adidas vs Nike running shoes",
  "body": "Looking for recommendations...",
  "upVotes": 42,
  "numberOfComments": 15,
  "communityName": "r/running",
  "url": "https://www.reddit.com/r/running/comments/abc123/example/",
  "searchQuery": "adidas",
  "matchedKeyword": "adidas"
}
```

### Keyword filter

When `filterByKeywords` is `true`, a post is saved and charged only if **at least one** input keyword appears in the title, body, or URL (case-insensitive). This removes obvious noise from Reddit search (e.g. posts that matched indirectly). You may receive **fewer than `maxPosts`** rows if many candidates are filtered out or fail to load.

### Limitations

- **Public content only** — no private or login-only data
- **Fail-fast** — failed requests are not retried (`maxRequestRetries: 0`); expect some loss; increase `requestDelayMs` or lower `maxConcurrency` to improve stability
- **Fewer than `maxPosts`** — possible when search returns few results, many requests fail, or the keyword filter rejects posts
- **Empty `body`** — normal for link posts, videos, and polls
- **Rate limits** — Reddit may block or throttle; use residential proxy and reasonable delays
- **No comments scraping** — only post-level fields, not individual comments
- **Duplicate keywords across searches** — same post appears once; `matchedKeyword` reflects the first search that enqueued it

### Local development

```bash
npm install
npm run build
npx apify run
```

Use `scripts/test-input.example.json` or set input in Apify Console. For cloud runs, connect the Git repository and deploy from your `dev` branch.

### Troubleshooting

| Issue | What to try |
|-------|-------------|
| Few or zero results | Widen `time`, change `sort`, add keywords, or remove `subreddit` |
| Slow or failing runs | Enable residential proxy; set `requestDelayMs` to 2000–3000; reduce `maxConcurrency` |
| Noisy results | Set `filterByKeywords: true` |
| Adult content in results | Set `includeNSFW: false` |
| Empty `body` fields | Expected for link/media posts — check `title` and `url` |

### Pricing

When **pay-per-event** is enabled on Apify Store:

| Mode | Event | Description |
|------|-------|-------------|
| `filterByKeywords: false` | **`reddit-post`** | Each saved post from search (may include off-topic results) |
| `filterByKeywords: true` | **`reddit-post-filtered`** | Each post verified to contain a keyword in title, body, or URL |

Set **`apify-default-dataset-item`** price to **$0** to avoid double billing with dataset rows. Configure both custom events in Apify Console → Monetization (price the filtered event higher than raw). Platform usage (compute, proxy) is billed separately.

### Run via API

```http
POST https://api.apify.com/v2/acts/olek_automate~reddit-search/runs?token=YOUR_TOKEN
Content-Type: application/json

{
  "keywords": ["adidas", "nike"],
  "maxPosts": 10,
  "filterByKeywords": true,
  "includeNSFW": false,
  "proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

Fetch results:

```http
GET https://api.apify.com/v2/datasets/{defaultDatasetId}/items?token=YOUR_TOKEN
```

# Actor input Schema

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

Keywords or phrases to search for. Each keyword runs as a separate Reddit search (reference actor style).

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

How to sort search results.

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

Limit results to posts from this time period.

## `maxPosts` (type: `integer`):

Maximum number of posts to save to the dataset.

## `includeNSFW` (type: `boolean`):

Include not-safe-for-work content in search results.

## `postDateLimit` (type: `string`):

ISO date — skip posts older than this.

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

Restrict search to a subreddit (without r/ prefix).

## `filterByKeywords` (type: `boolean`):

When enabled, only posts containing at least one keyword in title, body, or URL are saved and charged.

## `proxy` (type: `object`):

Apify proxy configuration. Residential proxy recommended.

## `requestDelayMs` (type: `integer`):

Pause before each page load (±25% jitter). Default 1000. Use 1500–3000 to reduce rate limits; lower values are faster but may increase 403 errors.

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

Maximum parallel browser pages.

## `debugMode` (type: `boolean`):

Enable verbose logging.

## Actor input object example

```json
{
  "keywords": [
    "adidas",
    "nike"
  ],
  "sort": "new",
  "time": "day",
  "maxPosts": 10,
  "includeNSFW": true,
  "filterByKeywords": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "requestDelayMs": 1000,
  "maxConcurrency": 4,
  "debugMode": false
}
```

# Actor output Schema

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

Dataset items from 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 = {
    "keywords": [
        "adidas",
        "nike"
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("morph_coder/reddit-keyword-search").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": [
        "adidas",
        "nike",
    ],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("morph_coder/reddit-keyword-search").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 '{
  "keywords": [
    "adidas",
    "nike"
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call morph_coder/reddit-keyword-search --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/Ma58eCp266EJbPAwC/builds/UJ0ixeP2XZXeFNNEl/openapi.json
