# Reddit Profile Scraper (`agentx/reddit-profile-scraper`) Actor

Turn a Reddit username into an exportable profile with karma, biography and selected post and comment history. Build author research datasets, enrich known accounts and track public activity with source links.

- **URL**: https://apify.com/agentx/reddit-profile-scraper.md
- **Developed by:** [AgentX](https://apify.com/agentx) (community)
- **Categories:** Social media, Automation
- **Features:** Limited permissions
- **Stats:** 15 total users, 2 monthly users, 100.0% runs succeeded, 3 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.0225 / result

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 Profile Scraper

Turn a Reddit username into a profile snapshot with karma, biography and selected post and comment history. Reddit Profile Scraper helps you build author research datasets, enrich known accounts and compare public activity over time. Export one profile row with nested history and source links.

[Open input](https://console.apify.com/actors/bb0YV0rZPcvyB4fX8/input) | [Pricing](https://apify.com/agentx/reddit-profile-scraper/pricing)

### Why Choose Reddit Profile Scraper

- **One username, one profile.** Use a handle or profile link to collect joinable identity and karma data.
- **Choose useful history depth.** Set independent post and comment caps, including profile-only lookups with both at `0`.
- **Keep the source context.** Nested posts and comments include text, community references and source links for further review.
- **Build repeatable research.** Export JSON for nested history or use `processed_at` to compare scheduled profile snapshots.

### Quick Start Guide

#### 1. Configure

Open the Actor input and enter `spez`, `u/spez`, or `https://www.reddit.com/user/spez/`. All three forms resolve to the same public account. Set each activity cap to the amount your workflow needs.

#### 2. Run

Start with one post and one comment:

```json
{
  "username": "spez",
  "max_posts": 1,
  "max_comments": 1
}
```

#### 3. Collect

Read the default Dataset and final status after the run finishes. A FREE-tier lookup with one delivered profile, one post and one comment has a **$0.04600 Actor-event subtotal**. Export JSON or JSONL when nested posts, comments, trophies, moderated communities, or available media arrays matter; use CSV or Excel for flatter profile analysis.

### Input Configuration

Reddit Profile Scraper has three required inputs in schema order, with no hidden filters or credential fields.

| Parameter | Type | Required | Default / unit | Effect | Example |
| --- | --- | --- | --- | --- | --- |
| `username` | string | Yes | None / one account | Public account as a username, `u/` handle, or profile URL | `spez` |
| `max_posts` | integer, minimum 0 | Yes | None / posts | Maximum submissions to request; `0` skips posts | `1` |
| `max_comments` | integer, minimum 0 | Yes | None / comments | Maximum comments to request; `0` skips comments | `1` |

All three values must be supplied. The form prefills `spez`, `1`, and `1`; prefills are examples rather than omitted-input defaults.

Caps limit the history requested from Reddit. Use `0` for a profile-only lookup or a small positive cap for an activity sample. Returned history reflects the public activity available during the run; read the final run message for unfinished sections.

### Output Data Schema

One Dataset row represents one Reddit user profile; the public contract has 39 top-level fields.

| Group | Fields |
| --- | --- |
| Identity | `status`, `id`, `name`, `username`, `url`, `about`, `created_at`, `created_date` |
| Profile presentation | `avatar`, `avatar_size`, `banner`, `banner_size`, `profile_color`, `snoovatar` |
| Verification and karma | `verified`, `verified_email`, `post_karma`, `comment_karma`, `awardee_karma`, `awarder_karma`, `total_karma` |
| Additional public facts | `is_admin`, `contribution_count`, `active_community_count`, `social_links` |
| Audience and state | `follower_count`, `accept_followers`, `is_premium`, `is_employee`, `is_moderator`, `is_suspended`, `over_18`, `robots_hidden` |
| Collections | `trophies`, `moderated`, `posts`, `comments` |
| Provenance | `processor`, `processed_at` |

This abbreviated example truncates every nested collection; real rows may contain many more fields inside posts, comments, trophies, and communities:

```json
{
  "status": "success",
  "id": "1w72",
  "username": "spez",
  "url": "https://www.reddit.com/user/spez/",
  "post_karma": 184005,
  "comment_karma": 756202,
  "total_karma": 940207,
  "is_employee": null,
  "trophies": [{"name": "15-Year Club"}],
  "moderated": [{"name": "r/announcements", "subscribers": 302603085}],
  "posts": [{"id": "1u7hraf", "title": "21 years of Reddit", "score": 840}],
  "comments": [{"id": "os0o1vi", "score": 95, "is_root": false}],
  "processor": "https://apify.com/agentx/reddit-profile-scraper",
  "processed_at": "2026-11-06T13:00:00Z"
}
```

Types below describe populated values; optional facts remain `null` when unavailable. Preserve genuine zero and `false` values. For a found profile, a zero history cap returns `[]`; requested history is `[]` when confirmed empty and `null` when unavailable. A `not_found` row keeps both histories `null`. Stored-file fields contain successful saved references; unsaved list members are removed.

The example is illustrative. `created_date` is a calendar date; `created_at` is an exact source instant when supplied.

#### Result kinds

`status: success` means the profile was found. A run can retain that row and still finish with a warning about requested history, optional detail, media, saving, or billing. There is no `partial` row status. `status: not_found` requires an explicit missing-account response; its unknown facts are null and it has no Profile lookup (`result`), Post, or Comment event. An unavailable lookup yields no invented row and an availability message. Invalid input is rejected. A run stopped by a spending limit retains already saved rows.

#### Profile fields

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | Reddit's internal account identifier; suspended accounts may omit it. |
| `name` | string | Display name shown on the profile when the account set one. |
| `username` | string | Canonical Reddit username without the u/ prefix. |
| `url` | string | Public Reddit profile URL. |
| `avatar` | string | Saved avatar URL when file saving succeeds. |
| `avatar_size` | array | Source-reported avatar width and height in pixels. |
| `banner` | string | Saved banner URL when file saving succeeds. |
| `banner_size` | array | Source-reported profile banner width and height in pixels. |
| `profile_color` | string | Profile theme color reported by Reddit. |
| `about` | string | Profile biography text. |
| `verified` | boolean | Reddit's account verification flag. |
| `verified_email` | boolean | Whether Reddit reports that the account verified an email address. |
| `post_karma` | integer | Karma earned from submissions. |
| `comment_karma` | integer | Karma earned from comments. |
| `awardee_karma` | integer | Karma earned from awards received. |
| `awarder_karma` | integer | Karma earned from awards given. |
| `total_karma` | integer | Total account karma; this may remain available for a suspended account. |
| `follower_count` | integer | Public subscriber count for the user's profile community. |
| `created_at` | string | ISO 8601 account creation time from Reddit. |
| `snoovatar` | boolean | Whether the account prefers to show its Snoovatar. |
| `accept_followers` | boolean | Whether the account accepts followers. |
| `is_premium` | boolean | Whether the account has Reddit Premium. |
| `is_employee` | boolean | Whether the account belongs to Reddit staff. |
| `is_moderator` | boolean | Whether Reddit identifies the account as a moderator. |
| `is_suspended` | boolean | True when Reddit reports that the account is suspended. |
| `over_18` | boolean | Whether the profile is marked for adult content. |
| `robots_hidden` | boolean | Whether the profile asks search engines not to index it. |
| `trophies` | array | Available trophy names, descriptions and links; icon saving is optional. |
| `moderated` | array | Available community identity, URL and audience count. |
| `posts` | array | Authored post objects, bounded by `max_posts`; see the history meanings above. |
| `comments` | array | Authored comment objects, bounded by `max_comments`; see the history meanings above. |
| `processor` | string | Apify Actor URL that processed this record. |
| `processed_at` | string | ISO 8601 timestamp when this record was processed. |
| `status` | string | success for a public profile; not_found only when Reddit explicitly confirms absence. |
| `created_date` | string | Source-published account creation date when an exact instant is unavailable. |
| `is_admin` | boolean | Explicit public Reddit Admin role; employment is not inferred. |
| `contribution_count` | integer | Source-published profile contribution count. |
| `active_community_count` | integer | Source-published count of active communities. |
| `social_links` | array | Public profile links with source labels and platform types. |

#### Post fields

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | Native Reddit identifier without a fullname type prefix, when available. |
| `post_url` | string | Public Reddit page identifying this entity. |
| `title` | string | Source-reported title. |
| `body` | string | Source-disclosed text from the accepted page. |
| `subreddit` | string | Source-reported subreddit name. |
| `subreddit_id` | string | Source-reported subreddit record id. |
| `subreddit_type` | string | Source-reported subreddit type. |
| `subreddit_subscribers` | integer | Native subscriber count of the post community. |
| `created_at` | string | Native publication time converted from epoch seconds to UTC. |
| `edited_at` | string | Native edit time converted from epoch seconds; false and unavailable sentinels are null. |
| `flair_text` | string | Source-reported flair text. |
| `author_flair_text` | string | Source-reported author flair text. |
| `score` | integer | Native score; may be negative and is not a total vote count. |
| `upvote_ratio` | number | Native fraction of post votes that are upvotes. |
| `comment_count` | integer | Native post comment total, not the size of a retrieved list. |
| `crosspost_count` | integer | Source-reported crosspost count. |
| `award_count` | integer | Source-reported award count. |
| `gild_count` | integer | Source-reported gild count. |
| `crosspost_parent_id` | string | Source-reported crosspost parent record id. |
| `crosspost_parent_url` | string | Source-reported crosspost parent url. |
| `crosspost_parent_title` | string | Source-reported crosspost parent title. |
| `crosspost_parent_author` | string | Source-reported crosspost parent author name. |
| `crosspost_parent_subreddit` | string | Source-reported crosspost parent subreddit name. |
| `media_type` | string | Source-reported media type. |
| `media_url` | string | Stored media URL when available; otherwise the external destination linked by the post, then its crosspost parent URL, or null. `crosspost_parent_url` remains present. A self-post permalink is not an external destination. |
| `media_provider_name` | string | Source-reported media provider name. |
| `media_title` | string | Source-reported media title. |
| `media_author_name` | string | Source-reported media author name. |
| `media_width` | integer | Native media width in pixels. |
| `media_height` | integer | Native media height in pixels. |
| `media_duration_seconds` | number | Native Reddit video duration in seconds. |
| `media_bitrate_kbps` | number | Native Reddit video bitrate in kilobits per second. |
| `media_has_audio` | boolean | Native Reddit video audio flag. |
| `media_is_gif` | boolean | Native Reddit video animated-GIF flag. |
| `domain` | string | Native linked domain; self.<community> sentinels are null. |
| `thumbnail` | string | Saved thumbnail URL. |
| `images` | array | Distinct stored-file URLs for successfully saved images, in native order. Null when Reddit did not show image facts; unsaved members are removed, so a known image list can become \[]. |
| `gallery_captions` | array | Complete nonblank captions in native gallery order. |
| `categories` | array | Native content categories. |
| `poll` | object | Source-reported poll. |
| `discussion_type` | string | Source-reported discussion type. |
| `suggested_sort` | string | Source-reported suggested sort. |
| `replies_enabled` | boolean | Native reply-notification preference, not an observed reply count. |
| `score_hidden` | boolean | Source-reported is score hidden. |
| `allow_live_comments` | boolean | Native flag permitting live comments. |
| `is_crosspostable` | boolean | Source-reported is crosspostable. |
| `contest_mode` | boolean | Source-reported is contest mode. |
| `is_meta` | boolean | Source-reported is meta. |
| `media_only` | boolean | Source-reported is media only. |
| `quarantined` | boolean | Source-reported is quarantined. |
| `is_self` | boolean | Source-reported is self. |
| `is_video` | boolean | Source-reported is video. |
| `is_original` | boolean | Source-reported is original content. |
| `is_gallery` | boolean | Source-reported is gallery. |
| `distinguished` | string | Source-reported distinguished. |
| `removed_by` | string | Source-reported removed by category. |
| `indexable` | boolean | Source-reported is indexable. |
| `over_18` | boolean | Native adult-content flag. |
| `spoiler` | boolean | Source-reported is spoiler. |
| `locked` | boolean | Source-reported is locked. |
| `stickied` | boolean | Source-reported is stickied. |
| `pinned` | boolean | Source-reported is pinned. |
| `archived` | boolean | Source-reported is archived. |
| `duplicates` | array | Reserved duplicate-post URLs; normally null. |

#### Comment fields

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | Native Reddit identifier without a fullname type prefix, when available. |
| `comment_url` | string | Public Reddit page identifying this entity. |
| `body` | string | Source-disclosed text from the accepted page. |
| `subreddit` | string | Source-reported subreddit name. |
| `subreddit_id` | string | Source-reported subreddit record id. |
| `subreddit_type` | string | Source-reported subreddit type. |
| `created_at` | string | Native publication time converted from epoch seconds to UTC. |
| `edited_at` | string | Native edit time converted from epoch seconds; false and unavailable sentinels are null. |
| `flair_text` | string | Source-reported flair text. |
| `score` | integer | Native score; may be negative and is not a total vote count. |
| `score_hidden` | boolean | Source-reported is score hidden. |
| `controversiality` | integer | Source-reported controversiality. |
| `award_count` | integer | Source-reported award count. |
| `gild_count` | integer | Source-reported gild count. |
| `over_18` | boolean | Native adult-content flag. |
| `replies_enabled` | boolean | Native reply-notification preference, not an observed reply count. |
| `is_collapsed` | boolean | Source-reported is collapsed. |
| `quarantined` | boolean | Source-reported is quarantined. |
| `is_root` | boolean | True when the native parent fullname identifies a submission rather than another comment. |
| `parent_id` | string | Source-reported parent record id. |
| `post_id` | string | Source-reported post record id. |
| `post_title` | string | Source-reported post title. |
| `post_url` | string | Source-reported post url. |
| `external_url` | string | Source-reported external destination of the parent post, excluding its Reddit permalink. |
| `post_author` | string | Source-reported post author name. |
| `post_comment_count` | integer | Native total for the comment parent post, not retrieved children. |
| `is_submitter` | boolean | Source-reported is submitter. |
| `distinguished` | string | Source-reported distinguished. |
| `stickied` | boolean | Source-reported is stickied. |
| `locked` | boolean | Source-reported is locked. |
| `archived` | boolean | Source-reported is archived. |
| `images` | array | Stored inline image URLs in source order. |

#### Trophy fields

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | Native Reddit identifier without a fullname type prefix, when available. |
| `name` | string | Source-reported title. |
| `icon` | string | Stored-file URL when the icon was saved. |
| `description` | string | Source-disclosed text from the accepted page. |
| `granted_at` | string | Native trophy grant time converted from epoch seconds to UTC. |
| `url` | string | Public Reddit page identifying this entity. |

#### Moderated community fields

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | Native Reddit identifier without a fullname type prefix, when available. |
| `name` | string | Source-reported subreddit name. |
| `title` | string | Source-reported title. |
| `url` | string | Public Reddit page identifying this entity. |
| `subscribers` | integer | Native community subscriber count. |
| `created_at` | string | Native creation time converted from epoch seconds to UTC. |
| `over_18` | boolean | Native adult-content flag. |
| `subreddit_type` | string | Source-reported subreddit type. |
| `icon` | string | Stored-file URL when the icon was saved. |
| `icon_size` | array | Source-reported image width and height in pixels. |
| `banner` | string | Stored-file URL when the community banner was saved. |
| `banner_size` | array | Source-reported banner width and height in pixels. |
| `primary_color` | string | Source-reported primary color. |
| `key_color` | string | Source-reported key color. |

#### Post poll fields

| Field | Type | Meaning |
| --- | --- | --- |
| `end_at` | string | Native poll end time converted from epoch milliseconds to UTC. |
| `total_votes` | integer | Source-reported total vote count. |
| `is_prediction` | boolean | Source-reported is prediction. |
| `resolved_id` | string | Source-reported resolved option id. |
| `options` | array | Native poll options; an empty list is retained only when supplied. |

#### Poll option fields

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | Native Reddit identifier without a fullname type prefix, when available. |
| `text` | string | Source-reported title. |

#### Social link fields

| Field | Type | Meaning |
| --- | --- | --- |
| `title` | string | Source label for the profile link. |
| `url` | string | Absolute destination supplied by the profile. |
| `type` | string | Source link category, normalized to lowercase. |

Stored media links are available only when the media could be saved. Post media_url can instead contain the external destination linked by the post. Missing stored scalar links are null; missing members are removed from media URL arrays. External article and thread links keep their source meaning. Intrinsic dimensions, exact dates, role flags, followers, preferences, poll facts, and duplicate links can remain unknown; a declared field does not promise a populated value. Post and comment arrays describe authored activity rather than a reconstructed reply tree.

### Integration Examples

Use Actor ID `bb0YV0rZPcvyB4fX8` or `agentx/reddit-profile-scraper`. Keep the Apify token in an environment variable or your integration's credential store.

#### Complete cURL workflow

This example needs cURL and `jq`. Set `APIFY_TOKEN` in the environment. It starts one run, polls that run to a terminal state, then reads all Dataset pages, including any retained partial result.

```bash
set -eu
: "${APIFY_TOKEN:?Set APIFY_TOKEN}"
api='https://api.apify.com/v2'
run=$(curl --fail --silent --show-error --request POST   "$api/acts/bb0YV0rZPcvyB4fX8/runs"   --header "Authorization: Bearer $APIFY_TOKEN"   --header 'Content-Type: application/json'   --data '{"username":"spez","max_posts":1,"max_comments":1}')
run_id=$(printf '%s' "$run" | jq -r '.data.id')
dataset_id=$(printf '%s' "$run" | jq -r '.data.defaultDatasetId')
while :; do
  run=$(curl --fail --silent --show-error     --header "Authorization: Bearer $APIFY_TOKEN" "$api/actor-runs/$run_id")
  status=$(printf '%s' "$run" | jq -r '.data.status')
  case "$status" in SUCCEEDED|FAILED|ABORTED|TIMED-OUT) break ;; esac
  sleep 5
done
offset=0
limit=1000
while :; do
  page=$(curl --fail --silent --show-error     --header "Authorization: Bearer $APIFY_TOKEN"     "$api/datasets/$dataset_id/items?offset=$offset&limit=$limit&format=json")
  printf '%s' "$page" | jq -c '.[]'
  count=$(printf '%s' "$page" | jq 'length')
  [ "$count" -eq "$limit" ] || break
  offset=$((offset + count))
done
printf 'Run status: %s\n' "$status" >&2
```

#### Complete Python workflow

Python 3 uses its standard library here; no SDK installation is required.

```python
import json
import os
import time
import urllib.request

API = "https://api.apify.com/v2"
TOKEN = os.environ["APIFY_TOKEN"]

def request(path, body=None):
    payload = None if body is None else json.dumps(body).encode()
    req = urllib.request.Request(
        API + path, data=payload,
        headers={"Authorization": "Bearer " + TOKEN,
                 "Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req, timeout=60) as response:
        return json.load(response)

run = request("/acts/bb0YV0rZPcvyB4fX8/runs", {
    "username": "spez", "max_posts": 1, "max_comments": 1,
})["data"]
run_id, dataset_id = run["id"], run["defaultDatasetId"]
terminal = {"SUCCEEDED", "FAILED", "ABORTED", "TIMED-OUT"}
while run["status"] not in terminal:
    time.sleep(5)
    run = request("/actor-runs/" + run_id)["data"]
offset, limit = 0, 1000
while True:
    page = request(f"/datasets/{dataset_id}/items?offset={offset}&limit={limit}")
    for row in page:
        print(json.dumps(row))
    if len(page) < limit:
        break
    offset += len(page)
print("Run status:", run["status"])
```

#### Complete JavaScript workflow

Node.js 18 or later provides `fetch`; save this example as an `.mjs` file.

```javascript
const api = 'https://api.apify.com/v2';
const token = process.env.APIFY_TOKEN;
if (!token) throw new Error('Set APIFY_TOKEN');
async function request(path, body) {
    const response = await fetch(api + path, {
        method: body === undefined ? 'GET' : 'POST',
        headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
        body: body === undefined ? undefined : JSON.stringify(body),
    });
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return response.json();
}
let { data: run } = await request('/acts/bb0YV0rZPcvyB4fX8/runs', {
    username: 'spez', max_posts: 1, max_comments: 1,
});
const runId = run.id;
const datasetId = run.defaultDatasetId;
const terminal = new Set(['SUCCEEDED', 'FAILED', 'ABORTED', 'TIMED-OUT']);
while (!terminal.has(run.status)) {
    await new Promise(resolve => setTimeout(resolve, 5000));
    ({ data: run } = await request(`/actor-runs/${runId}`));
}
const limit = 1000;
for (let offset = 0; ; ) {
    const page = await request(`/datasets/${datasetId}/items?offset=${offset}&limit=${limit}`);
    for (const row of page) console.log(JSON.stringify(row));
    if (page.length < limit) break;
    offset += page.length;
}
console.error(`Run status: ${run.status}`);
```

A client wait ending can leave the run active. Preserve the run ID and poll it again. Starting another run repeats the lookup and adds another Actor Start event. Read the final status, saved rows, and charged events together before deciding whether to retry.

The documented [start-run](https://docs.apify.com/api/v2/actors-runs-post), [run readback](https://docs.apify.com/api/v2/actor-run-get), and [Dataset items](https://docs.apify.com/api/v2/dataset-items-get) endpoints support these workflows. The same input can be used with Apify SDKs, [MCP](https://docs.apify.com/mcp), Make, or n8n. In Make, choose this Actor, map the three input fields, and pass the returned default Dataset ID to Get Dataset Items. In n8n, choose the Apify Run Actor action and retain its run and Dataset IDs. Schedules repeat one username lookup per run.

### Pricing

At the FREE tier, Reddit Profile Scraper costs $0.03000 per Profile lookup (`result`) plus $0.01000 per Actor Start; a found-profile run with both activity caps at `0` has a **$0.04000 Actor-event subtotal**.

| Event | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| Actor Start | $0.01000 | $0.01000 | $0.01000 | $0.01000 | $0.01000 | $0.01000 |
| Profile lookup (`result`) | $0.03000 | $0.02700 | $0.02400 | $0.02250 | $0.02250 | $0.02250 |
| Post | $0.00500 | $0.00450 | $0.00400 | $0.00375 | $0.00375 | $0.00375 |
| Comment | $0.00100 | $0.00090 | $0.00080 | $0.00075 | $0.00075 | $0.00075 |

The Actor Start is charged when the run begins. The single Profile lookup event covers the profile row; Post and Comment events cover activity items actually included. A FREE-tier run with one profile, one post, and one comment has an Actor-event subtotal of **$0.04600**. A run with one profile, 50 posts and no comments has a **$0.29000 Actor-event subtotal**. A confirmed missing-user row has no Profile lookup, Post or Comment charge, while the **$0.01000 Actor Start** still applies. Confirm current amounts on the [pricing page](https://apify.com/agentx/reddit-profile-scraper/pricing), because prices can change.

### Use Cases

- **Author research (`1` post / `1` comment):** review a sample of topics, communities and source scores alongside the profile.
- **Account enrichment (`0` / `0`):** join karma, biography and creation dates to a lawful list of known Reddit usernames.
- **Community context (`0` / `0`):** review public trophies and moderated-community references before a human investigation.
- **Activity sampling (positive caps):** export post and comment text with source links for qualitative research.
- **Recurring snapshots (`0` / `0`):** schedule the same username and compare source-reported counters by `processed_at`.

### Alternatives

Manual browsing is appropriate for a one-off visual check when no export or repeatability is needed. It becomes inefficient when profiles must be joined, compared, scheduled, or retained with a collection timestamp.

Reddit's own developer offering is the right choice for authorized application features, write actions, or a first-party API integration. Reddit's [Data API guidance](https://support.reddithelp.com/hc/en-us/articles/16160319875092-Reddit-Data-API-Wiki) explains its access and usage requirements. This Actor is designed for read-only public profile snapshots and does not claim official API affiliation.

Community- or search-first Actors are better when the username is not yet known. Choose something else for private data, deleted content recovery, identity verification, bulk usernames in one input, or automated decisions about people.

### Limits and Troubleshooting

- **User-hidden history ->** requested hidden posts remain unavailable (`null`). Requested comments may also remain `null`; hidden history is not guaranteed. Confirmed empty history is `[]`. Read the final run message for unavailable sections.
- **Fewer items than requested →** the caps are maximums and Reddit controls how much public activity is available → retry with `1` to distinguish source availability from volume.
- **User not found →** the account may be misspelled or deleted → verify the public profile URL, then retry the exact username.
- **Missing or restricted profile →** an explicit absence yields `status: not_found`; a refusal yields an unavailable notice. Restricted-profile field coverage varies; unknown flags are not `false`.
- **Spending limit →** collection stops when delivery or billing is refused. Already saved data remains. Inspect the Dataset and charged events; do not automatically rerun an uncertain charge.
- **Nested arrays look flattened →** tabular exports cannot preserve every nested object cleanly → use JSON or JSONL.
- **Optional-details warning →** `Completed | 1 profile · Some optional details could not be collected` means the requested posts and comments were delivered, but optional information such as duplicate links, moderation details or media was unavailable. Read the final run message for unavailable requested history.
- **Temporary retrieval failure →** public source availability varies → retry later with the smallest input before increasing the workload.

For a reproducible defect, open an [Actor issue](https://apify.com/agentx/reddit-profile-scraper/issues) with the public run ID, exact input, and expected outcome. Never include an API token or unrelated personal data.

### Trust and Reliability

The Dataset contains one profile row with the requested history. Its public schema lists 39 top-level fields, and `processor` and `processed_at` identify this Actor and the collection time. Missing profile facts remain unavailable rather than being guessed. Review the final message for any incomplete requested history.

### Legal and Compliance

**Public scope.** Use the Actor only for public account information and activity that Reddit exposes at run time.

**Privacy.** Collect the minimum data needed, define a lawful purpose, apply retention controls, and avoid high-impact automated decisions about individuals.

**Platform terms.** Review Reddit's current terms and [developer access guidance](https://support.reddithelp.com/hc/en-us/articles/14945211791892-Developer-Platform-Accessing-Reddit-Data) for your use case. You are responsible for how collected data is used.

### Frequently Asked Questions

#### Can I run a bulk reddit user lookup?

Yes, by launching one run per username through the API, Tasks, or an orchestrator. Each run intentionally accepts one identity and produces one profile row.

#### Does it support reddit karma and history export?

Yes. Export the profile karma fields and requested posts and comments from the Dataset. The output reference lists all fields; shared missing-value meanings apply.

#### What does a profile-only lookup cost?

At the FREE tier, a found profile with both activity caps at `0` has a $0.04000 Actor-event subtotal. Adding one delivered post and one comment gives the Quick Start subtotal of $0.04600. See Pricing for all tiers.

#### Can I schedule runs to monitor Reddit profiles over time?

Yes. Create an Apify Schedule with a fixed username and compare snapshots by `processed_at`; interpret changes as observations, not explanations.

#### Can I pass a full profile URL?

Yes. A username, `u/` handle, and full profile URL normalize to the same account identifier.

#### Are posts and comments complete histories?

No. The arrays are bounded by the requested caps and by the public activity available during the run.

#### Do I need Reddit credentials?

No credential field exists in the three-input schema. You need an Apify account or token to start the Actor.

#### Is karma an exact count of upvotes?

No. Reddit describes karma as an approximate reflection of votes. Treat it as a source-reported signal rather than audited engagement.

#### Why did the run finish with a warning after saving a profile?

The saved profile and the missing part are separate facts. A warning can identify unavailable requested history, optional details, media, or an unconfirmed charge. Keep the saved row and read the final status before retrying.

After an interrupted run, compare saved posts and comments with the requested caps and final warnings before retrying; a saved profile alone does not establish complete history.

#### What does Billing confirmation is pending mean?

The row may already be saved while billing confirmation is pending. Inspect that same run's charged events and Dataset; starting another run can repeat work and charges. If billing is still pending, retain the run ID and contact support before starting another run.

#### Why are there no rows after a temporary failure?

The public profile could not be retrieved during that run. This differs from an explicit missing-user result. Verify the username, retain the run ID, and try the smallest workload later if needed.

### Related AgentX Actors

- [Reddit Viral Scraper](https://apify.com/agentx/reddit-viral-scraper) — discover posts from keywords before looking up their authors.
- [Subreddit Posts Scraper](https://apify.com/agentx/subreddit-posts-scraper) — collect a community's posts rather than one user's history.
- [SubReddit Info Scraper](https://apify.com/agentx/subreddit-info-scraper) — add community descriptions, rules and settings to author research.

### Support and Community

Ask about Reddit profiles, activity depth, billing, and exports in the [AgentX community on Telegram](https://t.me/Apify_Actor); for a reproducible bug, open an Issue with the run ID and exact input.

AgentX is an Arcyton brand — [arcyton.com](https://arcyton.com).

**Last Updated:** November 7, 2026

# Actor input Schema

## `username` (type: `string`):

Reddit account to look up. Accepts a plain username, a u/ prefix, or a full profile URL — 'spez', 'u/spez' and 'https://www.reddit.com/user/spez/' all resolve to the same account.

## `max_posts` (type: `integer`):

Maximum authored posts per profile, newest first. Zero skips posts. There is no input ceiling; only available public history is returned, and an unavailable continuation is reported.

## `max_comments` (type: `integer`):

Maximum authored comments per profile, newest first then top for additional distinct comments. Zero skips comments. There is no input ceiling; unavailable history is reported.

## Actor input object example

```json
{
  "username": "spez",
  "max_posts": 1,
  "max_comments": 1
}
```

# Actor output Schema

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

Reddit profiles with account facts, stored media, and the requested post and comment collections.

# 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 = {
    "username": "spez",
    "max_posts": 1,
    "max_comments": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("agentx/reddit-profile-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 = {
    "username": "spez",
    "max_posts": 1,
    "max_comments": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("agentx/reddit-profile-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 '{
  "username": "spez",
  "max_posts": 1,
  "max_comments": 1
}' |
apify call agentx/reddit-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,agentx/reddit-profile-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/bb0YV0rZPcvyB4fX8/builds/q6webeXjxjTyDPyac/openapi.json
