# Reddit Post & Modqueue Scraper — MCP, Community Intel + AI (`harvestlab/reddit-scraper`) Actor

RAG-ready Reddit feed with 99%+ run success — posts, comments, modqueue, sentiment at $0.002/post, no OAuth. MCP-compatible alternative to Brandwatch/Sprout/Mention ($4 vs $249/mo). AI digest across 5 LLM providers. Trudax-grade with bonus moderation. x402-ready.

- **URL**: https://apify.com/harvestlab/reddit-scraper.md
- **Developed by:** [Nick](https://apify.com/harvestlab) (community)
- **Categories:** Social media, Marketing, MCP servers
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Scraper — Posts, Comments, Modqueue & AI Sentiment Analysis

Scrape Reddit posts, comments, and **moderation queues** from any subreddit or search query — **no OAuth required for public data**. Extract titles, scores, upvote ratios, comment threads, flair, virality scores, and full post metadata with a single run. Add an optional **built-in LLM analyst** to get sentiment scores, theme detection, community health assessment, emerging trends, and actionable recommendations — all in one dataset.

### What it does

Unlike every other Reddit scraper on Apify, this one covers three distinct use cases in a single actor: **subreddit browsing**, **site-wide search**, and a **moderation queue tier** for community managers who need to export modqueue / reports / spam / unmoderated feeds into Apify dashboards and triage workflows.

This actor connects to Reddit's public HTML endpoints and (optionally) Reddit's authenticated JSON API to extract structured data. For subreddit and search modes, no Reddit account or API key is needed — the actor appends `.json` to Reddit URLs and parses the response. For modqueue mode, the actor exchanges your moderator OAuth credentials for a user-scope token and calls Reddit's private moderation endpoints.

**Scraping modes:**

- **Subreddit mode** — Browse any public subreddit sorted by hot, top, new, or rising with configurable time filters and pagination up to 100 posts per run
- **Search mode** — Search across all of Reddit (or scoped to a subreddit) for posts matching any keyword, phrase, or topic with relevance and time-based sorting
- **Moderation Queue mode** — Community managers and subreddit mods can pipe the `modqueue`, `reports`, `spam`, or `unmoderated` feeds into Apify for triage dashboards, escalation workflows, or long-term moderation analytics

**Data enrichment:**

- Optional **comment extraction** pulls top-level comments for each post including author, score, and body — and as a side effect enriches each post with `selftext` (full post body) and `upvote_ratio` from the post-detail page
- Optional **Reddit OAuth mode** (`useJsonApi: true`) unlocks richer metadata on every post (`upvote_ratio`, `subreddit_subscribers`, `awards_count`, `author_flair`, `edited`, `distinguished`, `num_crossposts`) and increases rate limits from ~30 req/min to ~100 req/min

**AI analysis:**

When `enableAiAnalysis` is enabled, the actor sends scraped post titles and metadata to your chosen LLM provider and returns a structured analysis item with overall sentiment scores, top discussion themes, emerging trends, common complaints, common praises, community health score, most engaging posts, and actionable recommendations — all as structured JSON in the same dataset as the raw posts.

### Features

- **No OAuth required by default** — Uses Reddit's public HTML endpoints; no Reddit account, no API keys, no app registration needed for subreddit and search modes
- **Subreddit scraping** — Browse any public subreddit by hot, top, new, or rising posts with configurable time filters and pagination
- **Reddit search** — Search across all of Reddit or scoped to a specific subreddit for posts matching any keyword, phrase, or topic
- **Moderation queue mode** — Community managers and subreddit mods can pipe the `modqueue`, `reports`, `spam`, or `unmoderated` feeds into Apify for triage dashboards, escalation workflows, or long-term moderation analytics. Each item carries `item_type` (post/comment), `reported`, `num_reports`, `mod_reports[]`, `user_reports[]`, `removal_reason`, `banned_by`, `approved_by`, `ignore_reports`, and `spam` metadata. Requires a moderator-scope OAuth token
- **Comment extraction** — Optionally scrape top-level comments for each post including author, score, and body text. Also enriches each post with `selftext` and `upvote_ratio` from the post-detail page — fields not available in listing markup
- **Full post metadata** — title, author, score, upvote ratio, comment count, flair, awards, NSFW flag, stickied, spoiler, locked, archived, is_self, is_video flags, creation date, permalink, content text, and a derived `virality_score` (score normalized by age in hours, useful for ranking trending posts)
- **AI sentiment analysis** — Automatically analyze scraped posts to identify overall community sentiment with positive, negative, and neutral scores
- **Theme and trend detection** — AI identifies the top discussion themes, emerging trends, common complaints, and common praises across the scraped posts
- **Community health scoring** — AI-generated community health assessment based on engagement patterns, discussion quality, and upvote ratios
- **Multi-LLM provider support** — OpenRouter (recommended — 300+ models), Anthropic (Claude), Google AI (Gemini), OpenAI (GPT), or Ollama (self-hosted) for AI analysis
- **Optional Reddit OAuth mode** — Bring your own Reddit app credentials (`useJsonApi: true`) to unlock richer metadata and ~3x higher rate limits. Falls back to HTML scraping on auth failure so a bad token never breaks a run
- **Rate-limit compliant** — Built-in 2-second delay between requests (0.65s in OAuth mode) and a descriptive User-Agent to comply with Reddit's public API guidelines
- **Pay-per-event pricing** — You pay only for what you scrape: $0.002 per post, $0.001 per comment, $0.01 per modqueue item, $0.05 per AI analysis

### Use Cases

#### Market Research and Consumer Insights
Monitor what consumers are saying about products, brands, or industries in relevant subreddits. Track sentiment shifts over time by scheduling recurring scrapes of subreddits like r/technology, r/gadgets, or industry-specific communities. Identify unmet needs and feature requests that surface in user discussions. The AI analysis highlights the most common themes and complaints from hundreds of posts without manual reading.

#### Brand and Reputation Management
Track mentions of your brand, products, or competitors across Reddit. AI analysis highlights common complaints and praises, giving you an early warning system for reputation issues. Combine subreddit monitoring with Reddit search to capture discussions that happen outside your primary communities. Schedule hourly or daily runs to catch emerging threads before they go viral.

#### Product Teams and UX Research
Scrape subreddits where your users congregate to understand their pain points, feature requests, and workflow challenges. The structured comment data lets you build qualitative research datasets without manual copy-pasting. Use AI analysis to quickly surface the most common themes from hundreds of posts. Route the dataset to Google Sheets or Airtable via Apify integrations for collaborative tagging.

#### Community Management and Moderation
Assess the health and engagement levels of subreddits you manage or participate in. Community health scoring evaluates discussion quality, engagement levels, and overall mood. Track how community sentiment changes after product launches, policy changes, or major announcements.

**Moderation Queue tier**: mods of a subreddit can point the actor at their `modqueue`, `reports`, `spam`, or `unmoderated` feed to export items awaiting action into Apify. Typical uses: (1) build a triage dashboard in Retool / Metabase / Sheets that surfaces high-report-count items to senior mods first, (2) archive modqueue snapshots for audit trails, (3) escalate repeatedly-reported users via webhook, (4) cross-reference report volume against post themes using the same AI analysis layer.

#### Content Creation and Marketing
Discover what topics are trending in your niche by scraping relevant subreddits sorted by hot or rising posts. Identify high-engagement content formats and topics that resonate with your target audience. Use AI trend analysis to plan content calendars around emerging discussions. The most-engaging-posts field in the AI output shows which formats and angles drive the most comments.

#### Investment Research and Due Diligence
Monitor subreddits like r/investing, r/wallstreetbets, r/stocks, or industry-specific communities for sentiment around companies, sectors, or market events. AI sentiment scoring provides quantitative data that can complement financial analysis. Track how community mood shifts around earnings reports, product launches, or regulatory changes.

#### Academic and Social Research
Build datasets for social science research on community dynamics, information propagation, or platform culture. The actor exports clean JSON, CSV, or Excel — compatible with pandas, R, and standard research toolchains. The virality_score field provides a normalized engagement signal useful for comparative analysis across subreddits of different sizes.

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `mode` | select | `subreddit` | Scraping mode: `subreddit` (browse a specific subreddit), `search` (search across Reddit), or `modqueue` (fetch moderation queue — requires mod auth) |
| `subreddit` | string | `artificial` | Subreddit name without the r/ prefix (e.g. "python", "webdev", "startups"). Required for subreddit mode |
| `searchQuery` | string | — | Search query to find posts across Reddit. Required for search mode |
| `searchSubreddit` | string | `all` | Scope the search to a specific subreddit. Leave as `all` to search site-wide. Scoping to a specific subreddit is far more reliable because Reddit's bot filters are aggressive on the site-wide /search endpoint |
| `sortBy` | select | `hot` | Sort order: `hot` (trending), `top` (highest scored), `new` (most recent), `rising` (gaining traction), `relevance` (search mode only) |
| `timeFilter` | select | `week` | Time period filter for top and relevance sorting: `hour`, `day`, `week`, `month`, `year`, `all` |
| `maxPosts` | integer | `25` | Maximum posts to scrape (1–100). Higher values paginate across multiple Reddit pages |
| `includeComments` | boolean | `false` | Scrape top comments for each post. Also enriches each post with `selftext` and `upvote_ratio`. Adds ~2–3s per post |
| `maxCommentsPerPost` | integer | `10` | Maximum top-level comments per post (1–50). Only used when `includeComments` is enabled |
| `enableAiAnalysis` | boolean | `false` | Generate AI sentiment and trend analysis. Requires an LLM API key |
| `llmProvider` | select | `openrouter` | AI provider: `openrouter` (recommended), `anthropic` (Claude), `google` (Gemini), `openai` (GPT), or `ollama` (self-hosted) |
| `llmModel` | string | (auto) | Override the default model. Leave empty for provider default |
| `openrouterApiKey` | string | — | OpenRouter API key. Required when using OpenRouter provider. Get one at openrouter.ai/keys |
| `anthropicApiKey` | string | — | Anthropic API key. Get one at console.anthropic.com |
| `googleApiKey` | string | — | Google AI (Gemini) API key. Get one at aistudio.google.com/app/apikey |
| `openaiApiKey` | string | — | OpenAI API key. Get one at platform.openai.com/api-keys |
| `ollamaBaseUrl` | string | `http://localhost:11434` | Base URL for your local Ollama instance |
| `useJsonApi` | boolean | `false` | Opt in to Reddit's authenticated JSON API. Requires `redditClientId` + `redditClientSecret`. Unlocks richer metadata and ~3x higher rate limit |
| `redditClientId` | string | — | Reddit app client ID from reddit.com/prefs/apps. Required when `useJsonApi` is enabled or `mode=modqueue` |
| `redditClientSecret` | string | — | Reddit app secret. Required when `useJsonApi` is enabled or `mode=modqueue` |
| `redditUsername` | string | — | Moderator Reddit username for `mode=modqueue` password-grant auth |
| `redditPassword` | string | — | Moderator Reddit password. Use an app password if 2FA is enabled |
| `redditRefreshToken` | string | — | Pre-obtained Reddit OAuth refresh token (preferred for modqueue production pipelines) |
| `modqueueFeed` | select | `modqueue` | Modqueue mode only — which feed to fetch: `modqueue` (all pending), `reports`, `spam`, `unmoderated` |
| `modqueueOnly` | select | (both) | Modqueue mode only — narrow to `links` (posts) or `comments`. Empty means both |
| `proxyConfiguration` | object | Residential | Proxy settings. Residential proxies are strongly recommended for Reddit at scale |

**Cost** (pay-per-event pricing):

| Event | Price |
|-------|-------|
| Post scraped | $0.002 |
| Comment scraped | $0.001 |
| Modqueue item scraped | $0.01 |
| AI analysis completed | $0.05 |

Plus Apify compute costs and your LLM provider's charges (typically $0.001–0.01 per analysis with OpenRouter + Gemini Flash). A typical 25-post run with AI analysis costs roughly **$0.10 all-in**.

### Output

Each post is pushed as an individual dataset item:

```json
{
    "post_id": "1abc123",
    "title": "What AI tools are you using in your workflow?",
    "author": "techuser42",
    "subreddit": "artificial",
    "subreddit_subscribers": 428512,
    "score": 342,
    "upvote_ratio": 0.94,
    "num_comments": 87,
    "created_utc": "2026-04-10T14:30:00+00:00",
    "url": "https://www.reddit.com/r/artificial/comments/1abc123/...",
    "permalink": "https://www.reddit.com/r/artificial/comments/1abc123/...",
    "selftext": "I've been experimenting with several AI tools for my daily work...",
    "is_self": true,
    "is_video": false,
    "flair": "Discussion",
    "author_flair": "Senior Dev",
    "awards_count": 2,
    "over_18": false,
    "stickied": false,
    "spoiler": false,
    "locked": false,
    "archived": false,
    "edited": false,
    "distinguished": "",
    "num_crossposts": 3,
    "domain": "self.artificial",
    "virality_score": 28.5,
    "scraped_at": "2026-04-10T16:00:00+00:00",
    "comments": [
        {
            "comment_id": "def456",
            "author": "devpro",
            "body": "I've been using Cursor for code and it's been a game changer...",
            "score": 89,
            "created_utc": "2026-04-10T15:00:00+00:00"
        }
    ]
}
````

Fields `subreddit_subscribers`, `author_flair`, `edited`, `distinguished`, and `num_crossposts` are fully populated when `useJsonApi: true` is set. In HTML mode they default to `0` / `""` / `false` so the schema stays consistent across both paths.

When AI analysis is enabled, a summary item is pushed at the end of the dataset:

```json
{
    "type": "summary",
    "source": "r/artificial",
    "mode": "subreddit",
    "sort_by": "hot",
    "posts_found": 25,
    "ai_analysis": {
        "top_themes": ["AI coding tools", "LLM comparisons", "AI ethics"],
        "sentiment": {
            "positive_score": 55,
            "negative_score": 15,
            "neutral_score": 30,
            "summary": "Generally optimistic community with excitement about new tools"
        },
        "most_engaging_posts": [
            {
                "title": "What AI tools are you using in your workflow?",
                "score": 342,
                "num_comments": 87,
                "why_engaging": "Practical discussion that invites personal experience sharing"
            }
        ],
        "common_complaints": ["API pricing too high", "Model hallucinations"],
        "common_praises": ["Productivity improvements", "Open source model quality"],
        "emerging_trends": ["Local LLM hosting", "AI agents for automation"],
        "community_health": {
            "score": 8,
            "engagement_level": "high",
            "discussion_quality": "high",
            "summary": "Active community with constructive discussions"
        },
        "recommendations": [
            "Share practical tool comparisons for high engagement",
            "Address pricing concerns with cost-optimization guides"
        ]
    },
    "generated_at": "2026-04-10T16:00:00+00:00"
}
```

**Moderation queue items** (`mode=modqueue`) include full report metadata:

```json
{
    "type": "modqueue_item",
    "item_type": "post",
    "item_id": "1xy9abc",
    "title": "Is this a legit discount?",
    "author": "someuser123",
    "subreddit": "yoursubreddit",
    "permalink": "https://www.reddit.com/r/yoursubreddit/comments/1xy9abc/...",
    "score": -3,
    "num_reports": 4,
    "reported": true,
    "mod_reports": [{"reason": "spam link", "moderator": "ModAlice"}],
    "user_reports": [{"reason": "misleading title", "count": 2}, {"reason": "spam", "count": 2}],
    "removal_reason": "",
    "banned_by": "",
    "approved_by": "",
    "ignore_reports": false,
    "spam": false,
    "scraped_at": "2026-04-22T15:00:00+00:00"
}
```

Output is available as JSON, CSV, or Excel via Apify's dataset export. Use Apify integrations to send results to Google Sheets, Slack, webhooks, or any downstream system.

### Quick Start

**Scrape hot posts from a subreddit with AI analysis (no OAuth needed):**

```json
{
    "mode": "subreddit",
    "subreddit": "artificial",
    "sortBy": "hot",
    "maxPosts": 25,
    "includeComments": false,
    "enableAiAnalysis": true,
    "openrouterApiKey": "sk-or-..."
}
```

#### Sentiment Deep-Dive — Posts + Threaded Comments

Pulls top posts plus full threaded comments (1 post + N comments per thread) for sentiment / discourse analysis. Comments charge $0.001 each, so a 10-post run with 50 comments/post is $0.55, ideal for community-research projects.

```json
{
    "subreddits": ["MachineLearning"],
    "sortBy": "top",
    "timeRange": "week",
    "maxPostsPerSubreddit": 10,
    "includeComments": true,
    "maxCommentsPerPost": 50,
    "enableAiAnalysis": true,
    "aiProvider": "openrouter"
}
```

**Per run cost**: 10 posts × $0.002 + 500 comments × $0.001 + 1 AI summary × $0.05 = **$0.57**. Equivalent to ~3 minutes of an SMM analyst's time at $50/hr — and you get a structured JSON of every comment with sentiment scores.

**Best for**: academic research, community-pulse reports, brand-mention deep-dives, modqueue analysis, product-launch reaction tracking.

**Search Reddit for a topic with comments:**

```json
{
    "mode": "search",
    "searchQuery": "best project management tools",
    "sortBy": "relevance",
    "timeFilter": "month",
    "maxPosts": 50,
    "includeComments": true,
    "maxCommentsPerPost": 10,
    "enableAiAnalysis": true,
    "openrouterApiKey": "sk-or-..."
}
```

**Raw data collection without AI (zero API keys required):**

```json
{
    "mode": "subreddit",
    "subreddit": "webdev",
    "sortBy": "top",
    "timeFilter": "week",
    "maxPosts": 100,
    "includeComments": true,
    "maxCommentsPerPost": 5,
    "enableAiAnalysis": false
}
```

**Reddit OAuth mode — richer metadata, ~3x higher rate limit:**

Register a Reddit app at https://www.reddit.com/prefs/apps (select "script" type — simplest). Copy the client ID and secret.

```json
{
    "mode": "subreddit",
    "subreddit": "startups",
    "sortBy": "top",
    "timeFilter": "week",
    "maxPosts": 100,
    "useJsonApi": true,
    "redditClientId": "YOUR_REDDIT_APP_CLIENT_ID",
    "redditClientSecret": "YOUR_REDDIT_APP_SECRET",
    "enableAiAnalysis": true,
    "openrouterApiKey": "sk-or-..."
}
```

OAuth mode falls back to HTML scraping automatically if credentials are invalid, so a bad token never breaks a run.

**Moderation Queue mode — community managers:**

```json
{
    "mode": "modqueue",
    "subreddit": "yoursubreddit",
    "modqueueFeed": "modqueue",
    "maxPosts": 100,
    "redditClientId": "YOUR_REDDIT_APP_CLIENT_ID",
    "redditClientSecret": "YOUR_REDDIT_APP_SECRET",
    "redditUsername": "your_mod_username",
    "redditPassword": "your_mod_password"
}
```

Preferred for production — use a refresh token (no password stored):

```json
{
    "mode": "modqueue",
    "subreddit": "yoursubreddit",
    "modqueueFeed": "reports",
    "maxPosts": 50,
    "redditClientId": "YOUR_REDDIT_APP_CLIENT_ID",
    "redditClientSecret": "YOUR_REDDIT_APP_SECRET",
    "redditRefreshToken": "YOUR_PRE_OBTAINED_REFRESH_TOKEN"
}
```

**Modqueue OAuth setup (one-time):**

1. Go to https://www.reddit.com/prefs/apps and click "create another app..."
2. For the simplest path choose **"script"** — list the moderator Reddit account as a developer. For production choose **"web app"** and mint a refresh token via the authorization code flow
3. The moderator account must have **posts** or **access** moderator permissions on the target subreddit
4. Script apps: pass `redditClientId`, `redditClientSecret`, `redditUsername`, `redditPassword` as inputs (or matching env vars `REDDIT_CLIENT_ID`, `REDDIT_CLIENT_SECRET`, `REDDIT_USERNAME`, `REDDIT_PASSWORD`)
5. Web apps: generate a refresh token once via the code flow with scopes `read modposts`, then pass `redditClientId`, `redditClientSecret`, `redditRefreshToken`
6. Modqueue mode fails fast with a clear status message if credentials are missing or rejected — it does NOT silently fall back to HTML

### Troubleshooting

**Getting 403 or empty results from subreddit/search mode**
Reddit blocks requests from datacenter IP ranges at scale. Ensure the proxy configuration uses **Residential** proxies (the default prefill). Without residential proxies, most requests return 403.

**Search returns fewer results than expected**
Reddit search is notoriously inconsistent for unauthenticated scrapers. Try `sort: "new"` or `sort: "top"` instead of relevance. Very new posts may not be indexed yet. For comprehensive coverage, scrape the subreddit directly with `mode: "subreddit"` and filter by keyword in post-processing. Scoping search to a specific subreddit (`searchSubreddit: "python"`) is far more reliable than site-wide search.

**`upvote_ratio` is null on some posts**
Reddit only exposes upvote ratio on the post-detail page, not on listing pages (HTML path). Two fixes: (1) set `includeComments: true` — the actor fetches the detail page for each post and populates `upvote_ratio` and `selftext` as a side effect; or (2) enable `useJsonApi: true` with your Reddit app credentials to get `upvote_ratio` on every post from the authenticated JSON API with no extra requests.

**Posts return empty body text (`selftext`)**
Reddit posts can be link posts (no text), image posts, or video posts. The `selftext` field is empty for link posts by design. Check the `is_self` field: `true` = text post, `false` = link/image/video post.

**Modqueue returns 0 items or HTTP 403**
Modqueue mode requires you to be authenticated as a moderator of the target subreddit. Verify: (1) the Reddit app credentials are correct, (2) the moderator account has `posts` or `access` permissions on that subreddit (check reddit.com/r/SUBREDDIT/about/moderators), (3) for script apps the moderator account is listed as a developer on the app.

**Modqueue fails with auth error despite correct credentials**
If 2FA is enabled on the moderator account, use an **app password** (not the account password) for the `redditPassword` field. Generate one at reddit.com/prefs/apps under "authorized apps." For production pipelines, mint a refresh token once via the code flow and use `redditRefreshToken` instead of username/password.

**Comments load but are empty or truncated**
Some subreddits hide comment trees until users are logged in, or rate-limit comment fetches. Set `includeComments: false` if you only need post metadata, or add a residential proxy configuration to bypass comment-level rate limits. Comment bodies are limited to 500 characters and post selftext to 1000 characters to keep dataset sizes practical.

**AI analysis returns an error about missing API key**
Make sure you have set both the `llmProvider` field and the corresponding API key field (e.g., `openrouterApiKey` for OpenRouter). API keys can also be provided as environment variables: `OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`, `OPENAI_API_KEY`. Ollama does not require an API key; set `ollamaBaseUrl` to your local instance URL.

**Actor runs slowly with comments enabled**
Each post with comments requires an additional detail-page request subject to the 2-second rate limit delay. 100 posts with comments = ~3–4 minutes minimum. Enable OAuth mode (`useJsonApi: true`) to reduce the delay to 0.65 seconds per request (~3x faster). Alternatively, reduce `maxCommentsPerPost` or set `includeComments: false` for the initial exploratory run.

### Legal and Compliance

This actor scrapes publicly available data from Reddit. By using this actor, you agree to the following:

- **Your responsibility**: You are solely responsible for ensuring your use complies with all applicable laws, regulations, and Reddit's terms of service and API terms. This includes but is not limited to GDPR (EU), CCPA (California), and other data protection laws in your jurisdiction.
- **Reddit API Terms**: This actor uses Reddit's public JSON endpoints and HTML interface. Review Reddit's API Terms of Use (https://www.reddit.com/wiki/api-terms) and ensure your use case is compliant. Automated access to Reddit is subject to their acceptable use policies.
- **No legal advice**: This actor does not constitute legal advice. Consult a qualified attorney if you have questions about the legality of your specific use case.
- **Intended use**: This actor is designed for legitimate business purposes such as market research, competitive analysis, brand monitoring, and academic research using publicly accessible data.
- **Data handling**: You are responsible for how you store, process, and share any data collected. Ensure you have a lawful basis for processing any personal data (such as usernames) under applicable privacy laws.
- **Rate limiting**: This actor implements polite crawling practices including a 2-second delay between requests and a descriptive User-Agent header to minimize impact on Reddit's servers.
- **No warranty**: This actor is provided "as is" without warranty. Data accuracy depends on Reddit's content and API availability.
- **Content copyright**: Reddit posts and comments are authored by their respective users. Do not republish scraped content without considering the original authors' rights and Reddit's content policy.
- **Personal data notice**: Reddit posts and comments contain usernames which may constitute personal data under GDPR. Ensure you have a lawful basis for processing. Do not use extracted data for unsolicited contact, doxxing, or harassment of Reddit users.
- **Public subreddits only**: This actor can only access public subreddits. Private, quarantined, or restricted communities may return empty results or errors. The modqueue mode requires explicit moderator authorization and cannot access moderation data for subreddits where the authenticated account is not a moderator.

#### Related Actors

- **[Google News Monitor](https://apify.com/harvestlab/news-monitor)** — Combine Reddit community sentiment with news media coverage for a complete picture. Track what the media says alongside what Reddit communities discuss about your brand or industry.
- **[YouTube Scraper](https://apify.com/harvestlab/youtube-scraper)** — Scrape YouTube creator content and video metadata for cross-platform social media analysis. Compare Reddit thread discussions with YouTube audience reactions to the same topic.
- **[ProductHunt Scraper](https://apify.com/harvestlab/producthunt-scraper)** — Monitor product launches and community feedback on ProductHunt alongside subreddit discussions (`r/SideProject`, `r/startups`, `r/programming`) for a multi-platform launch sentiment view.

# Actor input Schema

## `mode` (type: `string`):

Choose whether to browse a specific subreddit, search across Reddit, or scrape a moderation queue. Moderation Queue mode requires moderator credentials (see Reddit OAuth section below) and charges a separate PPE event per item.

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

Subreddit name without r/ (e.g. "python", "webdev", "startups"). Used in subreddit mode.

## `searchQuery` (type: `string`):

Search query to find posts across Reddit. Used in 'search' mode only (ignored for 'subreddit' mode). Examples: 'AI agents', 'remote jobs', 'startup mistakes'.

## `searchSubreddit` (type: `string`):

Subreddit to scope the search to (without r/ prefix). Leave as "all" to search across all of Reddit (equivalent to r/all). Scoping to a specific subreddit (e.g. "python", "datascience") is far more reliable because Reddit's bot filters are aggressive on the site-wide /search endpoint. Used in search mode only.

## `sortBy` (type: `string`):

How to sort the results. "Most Relevant" only applies to search mode.

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

Time period for filtering results. Applies to "Top" and "Most Relevant" sort modes.

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

Maximum number of posts to scrape. Each Reddit page shows ~25 posts; higher values paginate.

## `maxItems` (type: `integer`):

CLI alias for maxPosts. Hidden from Console form; exposed so `apify call -i '{"maxItems":5}'` works consistently across the portfolio.

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

Scrape top-level comments for each post. Also enriches each post with `selftext` (full post body) and `upvote_ratio` from the post-detail page — fields that aren't available in listing markup. Adds ~2-3s per post.

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

Maximum number of top-level comments to scrape per post. Replies to comments are not scraped.

## `modqueueFeed` (type: `string`):

Which moderation feed to scrape (used only when mode = 'Moderation Queue'). 'modqueue' = all items awaiting moderator action (reports + auto-filtered spam + new submissions awaiting approval). 'reports' = items with user reports. 'spam' = items auto-classified as spam by Reddit. 'unmoderated' = never-actioned-on posts (useful for catching what fell through the cracks).

## `modqueueOnly` (type: `string`):

Narrow the moderation feed to posts only or comments only. Leave as 'Both' to return everything. Applies only in Moderation Queue mode.

## `useJsonApi` (type: `boolean`):

Opt in to the authenticated Reddit JSON API. Requires your own Reddit app credentials (redditClientId + redditClientSecret). Benefits: upvote\_ratio populated on every post (not just PDP-enriched ones), subreddit\_subscribers, awards\_count, author\_flair, edited/distinguished/num\_crossposts flags, and ~3x higher rate limit (~100 req/min vs ~30 req/min unauthenticated). Zero HTML-parsing intermittency. Register an app at https://www.reddit.com/prefs/apps (type: "script" — simplest). Falls back to HTML scraping on any auth error.

## `redditClientId` (type: `string`):

Your Reddit app's client ID (the short string shown under the app name in https://www.reddit.com/prefs/apps). Required when useJsonApi is enabled. Alternatively set REDDIT\_CLIENT\_ID env var.

## `redditClientSecret` (type: `string`):

Your Reddit app's secret (shown in https://www.reddit.com/prefs/apps). Required when useJsonApi is enabled. Alternatively set REDDIT\_CLIENT\_SECRET env var. For 'script' type apps the secret is shown directly; for 'web app' type follow Reddit's OAuth docs.

## `redditUsername` (type: `string`):

Reddit username of a moderator of the target subreddit. Required for modqueue mode with password grant. Works only for 'script' type Reddit apps where this user is listed as a developer on the app. Alternatively set REDDIT\_USERNAME env var. For web apps, use redditRefreshToken instead.

## `redditPassword` (type: `string`):

Reddit password for the moderator account. Required for modqueue mode password grant. Alternatively set REDDIT\_PASSWORD env var. Use an app password if 2FA is enabled. Prefer redditRefreshToken for production pipelines.

## `redditRefreshToken` (type: `string`):

Pre-obtained Reddit OAuth refresh token (issued via the authorization code flow for a 'web app' type Reddit app with 'modposts' + 'read' scopes). Preferred over username/password for production. Alternatively set REDDIT\_REFRESH\_TOKEN env var. See the README 'Modqueue OAuth setup' section for how to mint a refresh token.

## `enableAiAnalysis` (type: `boolean`):

Generate AI-powered sentiment and trend analysis from the scraped posts. Requires an API key for your chosen LLM provider.

## `llmProvider` (type: `string`):

AI backend for sentiment/trend analysis. 'OpenRouter' (default) is cheapest — Gemini Flash via OpenRouter is ~$0.001 per analysis. 'Anthropic' = Claude, 'Google AI' = Gemini direct, 'OpenAI' = GPT-4o mini, 'Ollama' = self-hosted (no API cost). Each provider needs its own API key field below.

## `llmModel` (type: `string`):

Specific model to use. Leave empty for the provider default (google/gemini-2.0-flash-001 for OpenRouter, claude-sonnet-4-20250514 for Anthropic, gemini-2.0-flash for Google AI, gpt-4o-mini for OpenAI, llama3.1 for Ollama).

## `openrouterApiKey` (type: `string`):

Your OpenRouter API key. Get one at openrouter.ai/keys

## `anthropicApiKey` (type: `string`):

Your Anthropic API key. Get one at console.anthropic.com

## `googleApiKey` (type: `string`):

API key for Google AI (Gemini). Get one at aistudio.google.com/app/apikey

## `openaiApiKey` (type: `string`):

API key from platform.openai.com (required if using OpenAI provider)

## `ollamaBaseUrl` (type: `string`):

Base URL for Ollama API. Default: http://localhost:11434

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

Proxy settings. Reddit rate-limits and 429-blocks datacenter IPs at scale — RESIDENTIAL (default) is strongly recommended, especially for runs >50 posts or repeated calls within a few minutes. Reddit detects curl\_cffi TLS impersonation, so this actor uses plain httpx with rotating User-Agents — proxy rotation is the main anti-block lever.

## Actor input object example

```json
{
  "mode": "subreddit",
  "subreddit": "ChatGPT",
  "searchSubreddit": "all",
  "sortBy": "hot",
  "timeFilter": "week",
  "maxPosts": 25,
  "includeComments": false,
  "maxCommentsPerPost": 10,
  "modqueueFeed": "modqueue",
  "modqueueOnly": "",
  "useJsonApi": false,
  "enableAiAnalysis": false,
  "llmProvider": "openrouter",
  "ollamaBaseUrl": "http://localhost:11434",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `datasetOutput` (type: `string`):

Dataset containing scraped Reddit posts, comments, modqueue items, and AI sentiment summary records.

# 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 = {
    "mode": "subreddit",
    "subreddit": "ChatGPT",
    "searchSubreddit": "all",
    "ollamaBaseUrl": "http://localhost:11434",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("harvestlab/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 = {
    "mode": "subreddit",
    "subreddit": "ChatGPT",
    "searchSubreddit": "all",
    "ollamaBaseUrl": "http://localhost:11434",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("harvestlab/reddit-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 '{
  "mode": "subreddit",
  "subreddit": "ChatGPT",
  "searchSubreddit": "all",
  "ollamaBaseUrl": "http://localhost:11434",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call harvestlab/reddit-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Reddit Post & Modqueue Scraper — MCP, Community Intel + AI",
        "description": "RAG-ready Reddit feed with 99%+ run success — posts, comments, modqueue, sentiment at $0.002/post, no OAuth. MCP-compatible alternative to Brandwatch/Sprout/Mention ($4 vs $249/mo). AI digest across 5 LLM providers. Trudax-grade with bonus moderation. x402-ready.",
        "version": "1.9",
        "x-build-id": "NBRgFzws7fthFtzFb"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/harvestlab~reddit-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-harvestlab-reddit-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/harvestlab~reddit-scraper/runs": {
            "post": {
                "operationId": "runs-sync-harvestlab-reddit-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/harvestlab~reddit-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-harvestlab-reddit-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "mode": {
                        "title": "Scraping Mode",
                        "enum": [
                            "subreddit",
                            "search",
                            "modqueue"
                        ],
                        "type": "string",
                        "description": "Choose whether to browse a specific subreddit, search across Reddit, or scrape a moderation queue. Moderation Queue mode requires moderator credentials (see Reddit OAuth section below) and charges a separate PPE event per item.",
                        "default": "subreddit"
                    },
                    "subreddit": {
                        "title": "Subreddit",
                        "type": "string",
                        "description": "Subreddit name without r/ (e.g. \"python\", \"webdev\", \"startups\"). Used in subreddit mode."
                    },
                    "searchQuery": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Search query to find posts across Reddit. Used in 'search' mode only (ignored for 'subreddit' mode). Examples: 'AI agents', 'remote jobs', 'startup mistakes'."
                    },
                    "searchSubreddit": {
                        "title": "Search Scope (Subreddit)",
                        "type": "string",
                        "description": "Subreddit to scope the search to (without r/ prefix). Leave as \"all\" to search across all of Reddit (equivalent to r/all). Scoping to a specific subreddit (e.g. \"python\", \"datascience\") is far more reliable because Reddit's bot filters are aggressive on the site-wide /search endpoint. Used in search mode only.",
                        "default": "all"
                    },
                    "sortBy": {
                        "title": "Sort By",
                        "enum": [
                            "hot",
                            "top",
                            "new",
                            "rising",
                            "relevance"
                        ],
                        "type": "string",
                        "description": "How to sort the results. \"Most Relevant\" only applies to search mode.",
                        "default": "hot"
                    },
                    "timeFilter": {
                        "title": "Time Filter",
                        "enum": [
                            "hour",
                            "day",
                            "week",
                            "month",
                            "year",
                            "all"
                        ],
                        "type": "string",
                        "description": "Time period for filtering results. Applies to \"Top\" and \"Most Relevant\" sort modes.",
                        "default": "week"
                    },
                    "maxPosts": {
                        "title": "Max Posts",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of posts to scrape. Each Reddit page shows ~25 posts; higher values paginate.",
                        "default": 25
                    },
                    "maxItems": {
                        "title": "Max Items (CLI alias)",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "CLI alias for maxPosts. Hidden from Console form; exposed so `apify call -i '{\"maxItems\":5}'` works consistently across the portfolio."
                    },
                    "includeComments": {
                        "title": "Include Comments",
                        "type": "boolean",
                        "description": "Scrape top-level comments for each post. Also enriches each post with `selftext` (full post body) and `upvote_ratio` from the post-detail page — fields that aren't available in listing markup. Adds ~2-3s per post.",
                        "default": false
                    },
                    "maxCommentsPerPost": {
                        "title": "Max Comments per Post",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of top-level comments to scrape per post. Replies to comments are not scraped.",
                        "default": 10
                    },
                    "modqueueFeed": {
                        "title": "Moderation Feed",
                        "enum": [
                            "modqueue",
                            "reports",
                            "spam",
                            "unmoderated"
                        ],
                        "type": "string",
                        "description": "Which moderation feed to scrape (used only when mode = 'Moderation Queue'). 'modqueue' = all items awaiting moderator action (reports + auto-filtered spam + new submissions awaiting approval). 'reports' = items with user reports. 'spam' = items auto-classified as spam by Reddit. 'unmoderated' = never-actioned-on posts (useful for catching what fell through the cracks).",
                        "default": "modqueue"
                    },
                    "modqueueOnly": {
                        "title": "Item Type Filter (Modqueue)",
                        "enum": [
                            "",
                            "links",
                            "comments"
                        ],
                        "type": "string",
                        "description": "Narrow the moderation feed to posts only or comments only. Leave as 'Both' to return everything. Applies only in Moderation Queue mode.",
                        "default": ""
                    },
                    "useJsonApi": {
                        "title": "Use Reddit OAuth JSON API",
                        "type": "boolean",
                        "description": "Opt in to the authenticated Reddit JSON API. Requires your own Reddit app credentials (redditClientId + redditClientSecret). Benefits: upvote_ratio populated on every post (not just PDP-enriched ones), subreddit_subscribers, awards_count, author_flair, edited/distinguished/num_crossposts flags, and ~3x higher rate limit (~100 req/min vs ~30 req/min unauthenticated). Zero HTML-parsing intermittency. Register an app at https://www.reddit.com/prefs/apps (type: \"script\" — simplest). Falls back to HTML scraping on any auth error.",
                        "default": false
                    },
                    "redditClientId": {
                        "title": "Reddit Client ID",
                        "type": "string",
                        "description": "Your Reddit app's client ID (the short string shown under the app name in https://www.reddit.com/prefs/apps). Required when useJsonApi is enabled. Alternatively set REDDIT_CLIENT_ID env var."
                    },
                    "redditClientSecret": {
                        "title": "Reddit Client Secret",
                        "type": "string",
                        "description": "Your Reddit app's secret (shown in https://www.reddit.com/prefs/apps). Required when useJsonApi is enabled. Alternatively set REDDIT_CLIENT_SECRET env var. For 'script' type apps the secret is shown directly; for 'web app' type follow Reddit's OAuth docs."
                    },
                    "redditUsername": {
                        "title": "Reddit Username (modqueue mode)",
                        "type": "string",
                        "description": "Reddit username of a moderator of the target subreddit. Required for modqueue mode with password grant. Works only for 'script' type Reddit apps where this user is listed as a developer on the app. Alternatively set REDDIT_USERNAME env var. For web apps, use redditRefreshToken instead."
                    },
                    "redditPassword": {
                        "title": "Reddit Password (modqueue mode)",
                        "type": "string",
                        "description": "Reddit password for the moderator account. Required for modqueue mode password grant. Alternatively set REDDIT_PASSWORD env var. Use an app password if 2FA is enabled. Prefer redditRefreshToken for production pipelines."
                    },
                    "redditRefreshToken": {
                        "title": "Reddit Refresh Token (modqueue mode, preferred)",
                        "type": "string",
                        "description": "Pre-obtained Reddit OAuth refresh token (issued via the authorization code flow for a 'web app' type Reddit app with 'modposts' + 'read' scopes). Preferred over username/password for production. Alternatively set REDDIT_REFRESH_TOKEN env var. See the README 'Modqueue OAuth setup' section for how to mint a refresh token."
                    },
                    "enableAiAnalysis": {
                        "title": "Enable AI Analysis",
                        "type": "boolean",
                        "description": "Generate AI-powered sentiment and trend analysis from the scraped posts. Requires an API key for your chosen LLM provider.",
                        "default": false
                    },
                    "llmProvider": {
                        "title": "LLM Provider",
                        "enum": [
                            "openrouter",
                            "anthropic",
                            "google",
                            "openai",
                            "ollama"
                        ],
                        "type": "string",
                        "description": "AI backend for sentiment/trend analysis. 'OpenRouter' (default) is cheapest — Gemini Flash via OpenRouter is ~$0.001 per analysis. 'Anthropic' = Claude, 'Google AI' = Gemini direct, 'OpenAI' = GPT-4o mini, 'Ollama' = self-hosted (no API cost). Each provider needs its own API key field below.",
                        "default": "openrouter"
                    },
                    "llmModel": {
                        "title": "LLM Model",
                        "type": "string",
                        "description": "Specific model to use. Leave empty for the provider default (google/gemini-2.0-flash-001 for OpenRouter, claude-sonnet-4-20250514 for Anthropic, gemini-2.0-flash for Google AI, gpt-4o-mini for OpenAI, llama3.1 for Ollama)."
                    },
                    "openrouterApiKey": {
                        "title": "OpenRouter API Key",
                        "type": "string",
                        "description": "Your OpenRouter API key. Get one at openrouter.ai/keys"
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API Key",
                        "type": "string",
                        "description": "Your Anthropic API key. Get one at console.anthropic.com"
                    },
                    "googleApiKey": {
                        "title": "Google AI API Key",
                        "type": "string",
                        "description": "API key for Google AI (Gemini). Get one at aistudio.google.com/app/apikey"
                    },
                    "openaiApiKey": {
                        "title": "OpenAI API Key",
                        "type": "string",
                        "description": "API key from platform.openai.com (required if using OpenAI provider)"
                    },
                    "ollamaBaseUrl": {
                        "title": "Ollama Base URL",
                        "type": "string",
                        "description": "Base URL for Ollama API. Default: http://localhost:11434"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. Reddit rate-limits and 429-blocks datacenter IPs at scale — RESIDENTIAL (default) is strongly recommended, especially for runs >50 posts or repeated calls within a few minutes. Reddit detects curl_cffi TLS impersonation, so this actor uses plain httpx with rotating User-Agents — proxy rotation is the main anti-block lever."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
