# Reddit Scraper - Posts, Comments, Subreddits & Media (`abotapi/reddit-scraper`) Actor

Scrape Reddit posts, comments and media from any subreddit or user profile. Search by keyword, sort by hot, new, top or rising, and optionally extract full comment threads and media URLs. Fast, resource-efficient and requires no login or API keys.

- **URL**: https://apify.com/abotapi/reddit-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** Social media, Developer tools
- **Features:** Limited permissions
- **Stats:** 19 total users, 1 monthly users, 87.1% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

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: Posts, Comments and Media from Any Subreddit or User

Reddit Scraper turns Reddit into a clean data feed. Point it at any subreddit or any user profile, pull posts sorted by new, hot, top or rising, optionally fetch available comment-thread entries under each post, and collect image and video links, or download the files themselves. Export the results to JSON, CSV or Excel, or read them straight through the API.

### Why This Scraper?

- **Two targets, one actor.** Scrape any public subreddit's listing, or switch to username mode and pull one user's posted history instead.
- **Posts with context.** Collect post text, author, timestamps, media links and post type together in each post record.
- **Comments on demand.** Turn on comment scraping to read each post's public comment-thread feed. Reddit currently exposes few or no comment entries in those feeds, so comment output can be empty (disclosed up front, never silently billed).
- **Media without extra tooling.** Image and video links come straight from the post data, and can optionally be downloaded to storage instead of just linked.
- **Reliable connection.** Reddit refuses most ordinary datacenter connections, so the actor reads the feeds over Apify's result-unblocking connection, with your own selected connection tried first and a backup connection taking over automatically if it is refused.
- **Built for schedules.** Resume continues one interrupted pull without re-collecting or re-charging posts it already has, and incremental mode returns only new and changed posts on recurring runs.
- **Optional extra work.** Comment scraping and media downloads are off by default. Media URLs can be collected without downloading files; recurring monitoring can suppress unchanged posts.

### Use Cases

- **Market research and brand monitoring:** track product mentions and competitor discussion across chosen subreddits.
- **Sentiment and NLP research:** build labeled text datasets from post titles, self text and comment threads.
- **Content curation:** collect trending posts and their media for aggregation or a content pipeline.
- **Academic and social research:** gather subreddit or user activity for longitudinal studies.
- **Lead generation:** find users discussing a relevant topic or product across a community.
- **Recurring monitoring:** schedule the actor with incremental mode to track a subreddit or user's new activity without re-collecting what you already have.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live record.

The dataset also ships three ready-made views (Posts Overview, Comments, Media URLs) selectable from the dataset's view tabs.

| Field | Example |
| --- | --- |
| `type` | `"post"` (also `"comment"`) |
| `id` | `"1hj2abc"` |
| `title` | `"What's your favorite Python library?"` |
| `author` | `"pythonista123"` |
| `subreddit` | `"python"` |
| `created_utc` | `"2024-12-20T15:30:00"` |
| `permalink` | `"https://reddit.com/r/python/comments/1hj2abc/..."` |
| `url` | `"https://reddit.com/r/python/comments/1hj2abc/..."` (media link or destination link where the post has one; the post's own address for text posts) |
| `score` | `null` (not published in the public feeds) |
| `upvote_ratio` | `null` (not published in the public feeds) |
| `num_comments` | `null` (not published in the public feeds) |
| `num_crossposts` | `null` (not published in the public feeds) |
| `selftext` | `"I've been exploring different libraries..."` (text posts) |
| `post_type` | `"text"` (also `"image"`, `"video"`, `"link"`) |
| `is_nsfw` | `null` (not published in the public feeds) |
| `is_spoiler` | `null` (not published in the public feeds) |
| `flair` | `null` (not published in the public feeds) |
| `total_awards` | `null` (not published in the public feeds) |
| `has_media` | `false` |
| `media_urls` | `{ "images": [], "videos": [], "galleries": [] }` (when Extract Media URLs is on) |
| `media_downloaded` | `true` (when Download Media Files is on) |
| `changeType` | `"NEW"` (incremental mode only) |
| `changedFields` | `[]` (incremental mode only) |
| `firstSeenAt` / `lastSeenAt` | `"2026-07-30T03:00:00Z"` (incremental mode only) |

Reddit publishes scores, vote ratios, comment counts, flair and NSFW/spoiler flags only through interfaces that are closed to unauthenticated readers, so those fields are `null` in every row rather than a fabricated zero. Everything else (titles, authors, text, timestamps, permalinks, media links) is complete.

Comment records use a separate shape carried under `type: "comment"`: `comment_id`, `post_permalink`, `post_title`, `parent_id`, `author`, `body`, `score`, `created_utc`, `depth` (entries in the public thread feed are flat, so depth is always 0) and `is_submitter`. Reddit's public comment feeds currently expose few or no entries, so comment output can be empty; comments never carry `changeType` or the other incremental fields, and incremental mode only classifies posts.

### How to Use

1. Enter a **target**: a subreddit name (e.g. `python`) or, with **Is Username** on, a Reddit username.
2. Set **Post Limit** and **Sort By** (`new`, `hot`, `top` or `rising`); pick a **Timeframe** if sorting by `top`.
3. Turn on **Scrape Comments** and/or **Extract Media URLs** (and **Download Media Files**) for the extra data you need.
4. Click **Start**. Results are saved to the dataset as they are scraped.

**Subreddit, hot posts with media URLs and no comments:**

```json
{
  "target": "python",
  "limit": 100,
  "sort": "hot",
  "scrapeComments": false,
  "extractMediaUrls": true
}
```

**User profile, latest submitted posts:**

```json
{
  "target": "spez",
  "isUser": true,
  "limit": 50
}
```

**Recurring subreddit monitor with incremental mode:**

```json
{
  "target": "askreddit",
  "limit": 200,
  "sort": "new",
  "incrementalMode": true,
  "emitExpired": true
}
```

**Continue an interrupted large pull:**

```json
{
  "target": "python",
  "limit": 1000,
  "sort": "new",
  "resumeFromRunId": "abCdEfGhIjKlMnOpQ"
}
```

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/reddit-scraper").call(run_input={"target": "python", "limit": 50, "sort": "hot"})
for post in client.dataset(run["defaultDatasetId"]).iterate_items():
    if post.get("type") == "post":
        print(post["title"], post["score"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/reddit-scraper').call({ target: 'python', limit: 50, sort: 'hot' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### Resume and recurring updates

Two different features, both opt-in:

- **Resume** (`resumeFromRunId`) continues one specific interrupted run: paste its run or dataset ID and this run skips posts it already collected there, so you don't pay twice.
- **Incremental mode** (`incrementalMode`) is for scheduling this actor on the same subreddit or user, sort and timeframe again and again. State is kept separately per target, sort, timeframe and media-toggle combination, or under one name you choose with `stateKey`. Each post is classified `NEW`, `UPDATED` (with `changedFields`), `UNCHANGED`, `REAPPEARED` or `EXPIRED`. `NEW` and `UPDATED` are always returned. `UNCHANGED` is suppressed (not returned or billed) unless `emitUnchanged` is on. `EXPIRED` is only produced when `emitExpired` is on and the run scanned the whole listing to its natural end, which a Post Limit cap or `resumeFromRunId` prevents; without that, previous state is left untouched. `REAPPEARED` can therefore only happen for a post that a past `emitExpired` run already tombstoned as `EXPIRED` and that later shows up again; turning `emitExpired` on is what makes `REAPPEARED` possible at all. With incremental mode off, output is exactly as before.
- **A vote or a new comment alone never marks a post `UPDATED`.** Score, upvote ratio and comment count drift on their own within minutes, and together with the other fields the public feeds do not publish they are excluded from change detection; `UPDATED` means the title, text, URL, type or media actually changed. The first run after the November 2026 update may classify existing tracked posts `UPDATED` once while baselines adjust to the change in field availability, then suppress normally again.

#### Caps and media limits

**Post Limit** stops a run after that many posts are scanned (a suppressed `UNCHANGED` post still counts against it). **Comments Per Post** caps the comments returned per post; Reddit's public comment feeds currently expose few or no entries, so comment output can be empty. Comment rows are additional to Post Limit. When **Download Media Files** is on, downloads are capped per post: up to 5 images, up to 10 gallery items and up to 2 videos (YouTube links are kept as URLs only, never downloaded).

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each record, not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify → Settings → Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `target` | string | none (example: `python`) | Subreddit name or username (required). |
| `isUser` | boolean | `false` | Set `true` if `target` is a username instead of a subreddit. |
| `limit` | integer | `10` | Maximum posts to scrape, up to 1000. |
| `sort` | string | `new` | `new`, `hot`, `top`, or `rising`. Applies to subreddit listings; username mode returns the user's submitted posts in Reddit's own order. |
| `timeframe` | string | `all` | Time filter used with `top` sort: `hour`, `day`, `week`, `month`, `year`, `all`. |
| `scrapeComments` | boolean | `false` | Read each post's public comment-thread feed; each returned comment is a separate billable result row. Reddit currently exposes few or no entries there, so comment output can be empty. |
| `commentsLimit` | integer | `100` | Maximum comments returned per post, up to 500. Reddit's public comment feeds currently expose few or no entries, so the returned count can be lower. |
| `extractMediaUrls` | boolean | `true` | Extract image, video and gallery URLs from posts. |
| `downloadMedia` | boolean | `false` | Download media files to the Key-Value Store; requires `extractMediaUrls: true` and adds transfer/storage work. |
| `proxy` | object | Apify Proxy, result-unblocking connection group | Connection settings. Reddit serves its public post feeds only through Apify's result-unblocking connection group, which the actor selects by default; a backup connection takes over automatically if your selected connection is refused. |
| `resumeFromRunId` | string | none | Continue one specific interrupted run without re-collecting or re-charging its posts. |
| `incrementalMode` | boolean | `false` | Turn on for recurring monitoring: classify each post as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against the previous run. |
| `stateKey` | string | none | Name a monitoring campaign explicitly; otherwise the state key is derived automatically from target, sort, timeframe and media toggles. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) UNCHANGED posts every run. |
| `emitExpired` | boolean | `false` | Also return (and bill) posts no longer found, once a run fully scans the listing. |
| `mcpConnectors` | array | none | Optional: send a summary of each record to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | none | Notion connector only: page under which item pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. Does not affect the dataset. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live record.

**Example post record:**

```json
{
  "type": "post",
  "id": "1hj2abc",
  "title": "What's your favorite Python library?",
  "author": "pythonista123",
  "subreddit": "python",
  "created_utc": "2024-12-20T15:30:00",
  "permalink": "https://reddit.com/r/python/comments/1hj2abc/",
  "url": "https://reddit.com/r/python/comments/1hj2abc/",
  "score": null,
  "upvote_ratio": null,
  "num_comments": null,
  "num_crossposts": null,
  "selftext": "I've been exploring different libraries and wanted to hear what everyone's using...",
  "post_type": "text",
  "is_nsfw": null,
  "is_spoiler": null,
  "flair": null,
  "total_awards": null,
  "has_media": false,
  "media_urls": {
    "images": [],
    "videos": [],
    "galleries": []
  }
}
```

### Plan Requirement

Check the Pricing tab for current actor charges and your Apify plan for available connection resources. Choose limits and optional data appropriate to your workload.

### FAQ

#### How much does it cost?

The **Pricing** tab shows the current actor-start charge and per-result rate. Each post and each comment returned is a result. **Post Limit** caps scanned posts, not comment rows or total charges. Connection usage and downloaded files can add transfer and storage costs.

For a lower-workload starting point, keep **Scrape Comments** and **Download Media Files** off, keep **Extract Media URLs** on if you need media links, and choose a Post Limit that covers your needs. For recurring monitoring, enable incremental mode and leave Emit unchanged and Emit expired off unless you need those rows. Incremental mode still scans the source and still fetches comments when enabled; it reduces post output, rather than eliminating request work or the actor-start charge.

#### Is it legal to scrape Reddit?

This actor collects publicly available posts and comments. Follow Reddit's terms, applicable privacy laws and regulations, and use a lawful basis when processing personal data. Obtain legal advice for your intended use where needed.

#### Can I get only new or changed posts on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental changes for scheduled runs**. Later runs then return only NEW and UPDATED posts by default, and unchanged posts are not returned or billed unless you turn on **Emit unchanged**. When Scrape Comments is enabled, comments can still be fetched and returned as separate billable rows for an unchanged post.

#### What's the difference between Resume and Incremental mode?

**Resume** (`resumeFromRunId`) continues one specific interrupted run from a pasted run or dataset ID, so a large one-off pull can finish without starting over. **Incremental mode** is for scheduling the actor repeatedly against the same subreddit or user, sort and timeframe, so each run returns only what's new or changed since the last one. They solve different problems and can be combined for a first bootstrap run.

#### Why did my run fail instead of returning an empty dataset?

This actor fails the run for a configuration problem (a missing target, a `resumeFromRunId` that doesn't resolve to a run or dataset you own, or turning on incremental mode with `resumeFromRunId` while that state key already has saved history) or an unexpected internal error. If Reddit itself refuses requests during the scrape, the run still finishes and simply returns fewer posts, or none, rather than failing; try again in a few minutes, and keep the default connection selection (see the Connection input), which reads the feeds over the connection Reddit serves.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 Want more social media data?

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>📱 <a href="https://apify.com/abotapi/lemon8-feeds-scraper"><b>Lemon8 Feed Scraper</b></a><br>Scrape Lemon8 feeds across 22 categories and 10+ regions. Extract posts, images, videos...</td><td>📱 <a href="https://apify.com/abotapi/lemon8-discover-scraper"><b>Lemon8 Search Scraper</b></a><br>Scrape Lemon8 posts by keyword across multiple regions. Extract posts, images, videos...</td></tr>
<tr><td>📱 <a href="https://apify.com/abotapi/lemon8-profile-scraper"><b>Lemon8 Profile Scraper</b></a><br>Scrape Lemon8 user profiles with automated multi-profile discovery. Extract profile data...</td><td>📱 <a href="https://apify.com/abotapi/lemon8-media-scraper"><b>Lemon8 Media Scraper</b></a><br>Lightweight Lemon8 scraper for extracting image and video URLs from posts, with optional...</td></tr>
<tr><td>🧩 <a href="https://apify.com/abotapi/pikabu-scraper"><b>Pikabu Scraper</b></a><br>Scrape Pikabu (Пикабу): keyword search, hot/new/best feeds, communities, tags, full story...</td><td>📱 <a href="https://apify.com/abotapi/mastodon-social-scraper"><b>Mastodon Scraper</b></a><br>Scrape trending Mastodon profiles and related posts from any Mastodon instance. Extract...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/reddit-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `target` (type: `string`):

Subreddit name (for example, python or askreddit) or username (for example, spez). Enter the name only; turn on Is Username for user posts.

## `isUser` (type: `boolean`):

Set to true if target is a Reddit username instead of subreddit

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

Maximum posts to scan, up to 1000. Unchanged posts suppressed by incremental mode still count. Comments are additional result rows and are not included in this limit.

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

Subreddit post order: new, hot, top, or rising. User mode returns submitted posts in the source’s own order; this setting does not change that order.

## `timeframe` (type: `string`):

Time period for 'top' posts

## `scrapeComments` (type: `boolean`):

Fetch the public comment-thread feed for each post. Each returned comment is a separate, billable result row. Reddit currently exposes few or no comment entries in these feeds, so posts-only monitoring is unaffected but comment output can be empty; adds requests and runtime.

## `commentsLimit` (type: `integer`):

Maximum comments returned per post, up to 500. Reddit's public comment feeds currently expose few or no entries, so the returned count can be lower; this is not a hard output-row cap.

## `extractMediaUrls` (type: `boolean`):

Extract image, video, and gallery URLs from the post data already collected. Does not download the files.

## `downloadMedia` (type: `boolean`):

Download available media files to the Key-Value Store. Requires Extract Media URLs. Adds transfer and storage work; leave off when URLs are enough.

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

Reddit serves its public post feeds only through Apify's result-unblocking connection group, which this input selects by default. Keep the default unless you have a connection that already works for you.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull of posts without returning or charging for posts already collected there. Use this after an interrupted run, or when continuing a pull in another run. For recurring daily monitoring of the same subreddit/user, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring of the same subreddit/user. The first run returns all matching posts as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED posts. A post is UPDATED only when its title, text, URL, or type actually changes -- score, upvote ratio, comment count, and the other fields the public post feeds do not publish (see the README) are excluded from that comparison, so voting or commenting alone never marks a post UPDATED. Turn on "Emit unchanged" or "Emit expired" only when you also want those posts returned (and billed). State is kept separately for each subreddit/user, sort, timeframe, and media toggle combination; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the subreddit/user, sort, timeframe, and media toggles -- different setups then never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return posts that have not changed since the last run, marked UNCHANGED. This returns -- and bills -- extra rows you already have, so leave it off unless you specifically want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return posts that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the subreddit/user listing to its natural end -- not when Post Limit capped it, or when Resume was used. This returns -- and bills -- extra synthetic rows, so leave it off unless you need expiry tracking.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "target": "python",
  "isUser": false,
  "limit": 10,
  "sort": "new",
  "timeframe": "all",
  "scrapeComments": false,
  "commentsLimit": 100,
  "extractMediaUrls": true,
  "downloadMedia": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50
}
```

# 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 = {
    "target": "python",
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ]
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/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 = {
    "target": "python",
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
    },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/reddit-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "target": "python",
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false
}' |
apify call abotapi/reddit-scraper --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Cig5OVeJyKx5TkYYK/builds/ueNx1RYcdmSFY2Jex/openapi.json
