# Reddit User Profile & Post History Crawler Pro (`dataspryva/reddit-user-profile-and-post-history-crawler-pro`) Actor

Turn Reddit usernames or profile URLs into split karma, account-age and status-badge data, plus filterable post history with per-post awards, media and gilding, and optional trophies, mod subs and comments.

- **URL**: https://apify.com/dataspryva/reddit-user-profile-and-post-history-crawler-pro.md
- **Developed by:** [Dataspryva](https://apify.com/dataspryva) (community)
- **Categories:** Social media, Automation, Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Reddit User Profile & Post History Crawler Pro

Turn Reddit usernames or profile links into structured user records: split karma, account age, badges, bio and avatar, plus the user's posts or comments with media, awards, upvote ratio, trophies and moderated communities.

Runs on public pages without a Reddit account, login cookie, API key, or proxy setup.

### Modes

| Mode | What it collects |
|---|---|
| **Posts** (`submitted`) | The user's submitted posts, with optional recent comments. |
| **Overview** (`overview`) | Posts **and** comments in one record. |
| **Comments** (`comments`) | The user's recent comments only. |
| **Gilded** (legacy) | Reddit no longer exposes a gilded feed; accepted for saved tasks and treated as Posts with a warning. |

Every mode supports Hot, New, Top and Controversial ordering. Top and Controversial use the `timeFilter` window.

### What each record contains

#### User fields

- `username`, `user_id`, `profile_url`
- `post_karma`, `comment_karma`, `total_karma`
- `account_created` (ISO 8601), `account_age_years`
- `description`, `icon_img`
- `contributions`
- `is_admin`, `is_employee`, `is_moderator`, `is_gold`, `verified`, `has_verified_email` — only present when Reddit shows the badge
- `posts[]`, `post_count`
- `filtered_post_count` — only when posts existed but every one was filtered out
- `section_empty` — only when the chosen feed genuinely has no content for that user
- `trophies[]`, `trophy_count` — when Include trophy case is on
- `moderated_subreddits[]`, `moderated_subreddit_count` — when Include moderated communities is on
- `moderator_list_hidden` — when the public moderator list is hidden
- `recent_comments[]`, `recent_comment_count`, `recent_comments_total_score` — for Overview, Comments, or when Include recent comments is on
- `posts_total_score` — sum of kept post scores when non-zero
- `scraped_at`

#### Post fields

- `post_id`, `post_name`, `title`, `author`, `author_fullname`
- `subreddit` (bare name, e.g. `aww`), `subreddit_prefixed` (`r/aww`)
- `score`, `num_comments`, `upvote_ratio`
- `permalink`, `url`, `external_url`, `domain`, `post_type`, `post_hint`
- `content` (self-text, up to 1,000 characters), `content_html`
- `thumbnail_url`, `link_flair`
- `created_utc`, `created_at`, `post_age_seconds`, `title_word_count`
- `is_self`, `is_gallery`, `is_video`, `is_crosspost`, `is_stickied`, `is_locked`, `is_archived`, `is_nsfw`, `is_spoiler`, `is_original_content`, `is_promoted`
- `awards[]`, `total_awards_received`, `gilded_count` (when Reddit labels the award as a gild)
- `media_metadata` — type, thumbnail, gallery images, MP4/HLS video URL
- `crosspost_parent` — original post id, subreddit and link

#### Comment fields

- `comment_id`, `comment_name`, `post_id`, `post_title`
- `author`, `text`, `body_html`
- `score`, `subreddit`, `subreddit_prefixed`
- `permalink`, `created_utc`, `created_at`
- `is_edited`, `distinguished`

A field the profile genuinely lacks is omitted, never emitted as `null`.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `usernames` | array | – | Usernames, `u/name` handles, or full profile URLs. Legacy `username` is also accepted. |
| `section` | select | `submitted` | Posts, Overview, Comments, or legacy Gilded. |
| `sort` | select | `new` | New, Hot, Top, or Controversial. |
| `timeFilter` | select | `all` | All time, year, month, week, day, or hour. Used by Top/Controversial. |
| `maxPosts` | integer | `50` | Posts to collect per user (1–1000). |
| `maxComments` | integer | `25` | Comments to collect per user (1–1000). |
| `includeComments` | boolean | `false` | Also collect comments when the section is Posts. |
| `includeTrophies` | boolean | `false` | Add the trophy case. |
| `includeModeratedSubreddits` | boolean | `false` | Add the public moderated-community list. |
| `minPostScore` | integer | – | Drop posts below this score. |
| `maxPostAgeDays` | integer | – | Drop posts older than this many days. |
| `excludeNsfwPosts` | boolean | `false` | Drop NSFW / not-brand-safe posts. |
| `minPostComments` | integer | – | Drop posts with fewer comments. |
| `maxPostComments` | integer | – | Drop posts with more comments. |
| `postType` | select | `all` | Keep one type: text, link, image, video, gallery, crosspost, GIF, multi-media, or poll. |
| `includeKeywords` | array | – | Keep posts matching these terms in title, body, flair, or subreddit. |
| `excludeKeywords` | array | – | Drop posts matching any of these terms. |
| `keywordMatch` | select | `any` | Include keywords may match any or all terms. |
| `excludeStickied` | boolean | `false` | Drop pinned posts. |

#### Example: recent posts

```json
{
  "usernames": ["spez", "https://www.reddit.com/user/Poem_for_your_sprog"],
  "section": "submitted",
  "sort": "new",
  "maxPosts": 25
}
```

#### Example: top comments

```json
{
  "usernames": ["spez"],
  "section": "comments",
  "sort": "top",
  "timeFilter": "year",
  "maxComments": 50,
  "excludeNsfwPosts": true
}
```

#### Example: filtered image posts

```json
{
  "usernames": ["GallowBoob"],
  "section": "submitted",
  "sort": "top",
  "timeFilter": "month",
  "maxPosts": 100,
  "postType": "image",
  "minPostScore": 500,
  "excludeKeywords": ["giveaway"]
}
```

#### Example: full profile

```json
{
  "usernames": ["spez"],
  "section": "overview",
  "maxPosts": 50,
  "maxComments": 50,
  "includeTrophies": true,
  "includeModeratedSubreddits": true,
  "excludeNsfwPosts": true
}
```

### Error records

Each unusable username emits one record with `recordType: "error"` and `type: "reddit_profile_crawler_pro_error"`. The run continues with the remaining users.

| `reason` | Meaning |
|---|---|
| `user_not_found` | Reddit has no profile with that name. |
| `profile_private` | The profile is private. |
| `profile_suspended` | The account is suspended. |
| `blocked` | Reddit blocked every anonymous route for this run. |
| `scrape_failed` | The page raised an unexpected error. |
| `no_valid_usernames` | The input contained no usable username. |

### Use cases

- **User research** — posting cadence, top communities, karma split and account age.
- **Trust and safety checks** — combine age, status badges, verification and trophy history.
- **Influence analysis** — rank posts by score, comments, awards and upvote ratio.
- **Community audits** — export the public list of communities a user moderates.
- **Dataset building** — collect posts and comments with media and engagement metadata.

### FAQ

#### Is this affiliated with Reddit?

No. This is an independent third-party actor that reads publicly available Reddit pages. It is not operated by or affiliated with Reddit.

#### Do I need a Reddit account, API key, or proxy?

No. The actor reads public pages anonymously. It handles Reddit's network challenges automatically and needs no credentials or proxy configuration from you.

#### Why is `post_count` lower than `maxPosts`?

The profile feed ran out of pages before reaching the limit, or the client-side filters removed posts. `filtered_post_count` appears when filters removed every post.

#### Why did a user return no comments?

The account may have no public comments, or Reddit's comments feed may be empty for that profile. `section_empty` flags the empty feed.

#### Why is `section: "gilded"` treated as Posts?

Reddit's current public profile UI no longer has a gilded-only feed. Saved tasks that send `gilded` keep working as Posts, and the status log explains the substitution.

#### Why are awarder/awardee karma fields often missing?

Reddit's current public profile header only shows post, comment and total karma for most accounts. Those fields appear only when the page carries them.

#### Are private or suspended profiles supported?

No. They emit an error record explaining the reason; no personal data is collected from them.

### Data source

Public Reddit profile, posts and comments pages. The actor does not use Reddit's OAuth API, does not log in, and does not require cookies.

### Legacy input compatibility

Old saved tasks keep working. The actor maps these keys in code:

- `username` (string) → `usernames`
- `sortBy` → `sort`
- `section: "gilded"` → `submitted`
- old sort aliases `best` / `rising` / `relevance` → `hot` / `new` / `hot`

Legacy keys are intentionally **not** shown in the input form, so the schema only contains fields the actor actually uses.

# Actor input Schema

## `usernames` (type: `array`):

Reddit usernames to scrape. Accepts plain names (`spez`), `u/spez`, or full profile URLs such as `https://www.reddit.com/user/spez`. URLs are normalised automatically.

## `section` (type: `string`):

Which part of the profile to collect. Overview includes the mixed posts + comments feed.

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

Feed order for the chosen section. `top` and `controversial` use the time filter below.

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

Time window used when sorting by Top or Controversial. Ignored for New and Hot.

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

Maximum posts to collect per user. The actor stops when the profile runs out of pages.

## `maxComments` (type: `integer`):

Maximum comments to collect per user in the Comments and Overview sections, or when Include comments is on.

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

Also collect the user's recent comments when section is Posts. Adds `recent_comments[]`.

## `includeTrophies` (type: `boolean`):

Collect trophy names and icons shown on the profile. Adds `trophies[]` and `trophy_count`.

## `includeModeratedSubreddits` (type: `boolean`):

Collect the public list of communities the user moderates. Adds `moderated_subreddits[]`.

## `minPostScore` (type: `integer`):

Drop posts whose score is below this value.

## `maxPostAgeDays` (type: `integer`):

Drop posts older than this many days.

## `excludeNsfwPosts` (type: `boolean`):

Drop posts Reddit marks NSFW or not brand-safe.

## `minPostComments` (type: `integer`):

Drop posts with fewer comments than this value.

## `maxPostComments` (type: `integer`):

Drop posts with more comments than this value.

## `postType` (type: `string`):

Keep only one kind of post, or all types.

## `includeKeywords` (type: `array`):

Keep only posts whose title, body, flair or subreddit contains at least one of these terms (or all of them when Keyword match is All).

## `excludeKeywords` (type: `array`):

Drop posts whose title, body, flair or subreddit contains any of these terms.

## `keywordMatch` (type: `string`):

Whether a post must contain any or all include keywords.

## `excludeStickied` (type: `boolean`):

Drop posts pinned to the top of a community.

## Actor input object example

```json
{
  "usernames": [
    "spez",
    "u/example_user",
    "https://www.reddit.com/user/another_user"
  ],
  "section": "submitted",
  "sort": "new",
  "timeFilter": "all",
  "maxPosts": 3,
  "maxComments": 25,
  "includeComments": false,
  "includeTrophies": false,
  "includeModeratedSubreddits": false,
  "excludeNsfwPosts": false,
  "postType": "all",
  "includeKeywords": [
    "python",
    "data"
  ],
  "excludeKeywords": [
    "giveaway",
    "meme"
  ],
  "keywordMatch": "any",
  "excludeStickied": false
}
```

# Actor output Schema

## `profiles` (type: `string`):

Dataset containing all scraped Reddit user profiles.

# 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 = {
    "usernames": [
        "spez"
    ],
    "maxPosts": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataspryva/reddit-user-profile-and-post-history-crawler-pro").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 = {
    "usernames": ["spez"],
    "maxPosts": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("dataspryva/reddit-user-profile-and-post-history-crawler-pro").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 '{
  "usernames": [
    "spez"
  ],
  "maxPosts": 3
}' |
apify call dataspryva/reddit-user-profile-and-post-history-crawler-pro --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataspryva/reddit-user-profile-and-post-history-crawler-pro"
        }
    }
}
```

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/rYwbbQBxhDrt2c8YN/builds/aT8GkXhjIG7JQF8J0/openapi.json
