Reddit User Profile Bulk Scraper avatar

Reddit User Profile Bulk Scraper

Pricing

Pay per event

Go to Apify Store
Reddit User Profile Bulk Scraper

Reddit User Profile Bulk Scraper

Bulk-enrich public Reddit usernames into one profile row each with karma, account age, bio, follower count, assets, account flags, and explicit outcome statuses.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Categories

Share

Turn Reddit usernames and profile URLs into one clean account record per user.

This Actor extracts public Reddit profile metadata: account ID, creation date and age, karma breakdown, follower count, bio, profile assets, account badges, moderation flags, NSFW status, visibility, and canonical URL. It deliberately excludes posts and comments, so the output stays compact and predictable for enrichment workflows.

What this Actor does

Provide a list of Reddit usernames, profile URLs, or both. The Actor:

  1. validates and deduplicates targets case-insensitively;
  2. opens an anonymous public Reddit session through an Apify residential proxy;
  3. completes Reddit's automatic JavaScript verification when presented;
  4. reads the public account profile payload;
  5. emits exactly one typed row per unique requested username;
  6. distinguishes missing, suspended, private, blocked, and failed targets.

A Reddit login, Reddit API key, user cookies, and manual CAPTCHA solving are not required.

Who is it for?

  • Audience research teams enriching creator or community-member lists.
  • Moderation teams reviewing account age, karma, and public account flags.
  • Trust and safety teams refreshing public account watchlists.
  • OSINT researchers normalizing public account metadata into datasets.
  • Creator and lead-enrichment teams attaching public Reddit signals to records.
  • Data engineers scheduling profile snapshots for downstream comparison.

Why use a profile-only scraper

General Reddit scrapers are designed around posts, comments, communities, and search results. This Actor is optimized for a different job: converting a known username list into one account-level row per target.

That means:

  • no activity-content explosion;
  • simple joins on username or redditUserId;
  • predictable one-target-to-one-row output;
  • explicit outcome rows instead of silent missing records;
  • charges only for successfully resolved public profiles, not status rows.

Data extracted

FieldMeaning
usernameCanonical Reddit username
redditUserIdReddit account ID without t2_
statussuccess, not_found, suspended, private, blocked, or failed
statusMessageExplanation for non-success outcomes
createdAtISO 8601 account creation time
accountAgeDaysWhole account age in days at scrape time
totalKarmaTotal Reddit karma
linkKarmaLink/post karma
commentKarmaComment karma
awardeeKarmaKarma received from awards
awarderKarmaKarma earned from giving awards
followersCountPublic profile follower/subscriber count when exposed
bioPublic profile bio
profileTitlePublic profile title
profileDescriptionLong public profile description
avatarUrlPublic icon or Snoovatar URL
bannerUrlPublic profile banner URL
canonicalUrlCanonical Reddit profile URL
verifiedReddit verification flag
hasVerifiedEmailPublic verified-email flag when exposed
isEmployeeReddit employee/admin flag
isGoldReddit Premium/Gold flag
isModModerator flag
isNsfwNSFW profile flag
isSuspendedSuspended-account flag
profileVisibilityPublic profile visibility/type value
scrapedAtISO 8601 scrape timestamp

Source fields can be absent. Nullable output fields remain null rather than being guessed.

Pricing

The Actor uses pay-per-event pricing:

  • $0.005 for one start event per run;
  • one profile event per successfully resolved public profile.
Apify plan tierPrice per successful profile
Free$0.0031794
Bronze$0.0027647
Silver$0.0021565
Gold$0.0016588
Platinum$0.0011059
Diamond$0.00077412

not_found, suspended, private, blocked, and failed status rows are not charged as resolved profiles. The live Apify pricing tab remains the source of truth.

For a run with N successful public profiles, use:

estimated charge = $0.005 + (N × profile event price for your plan tier)

Examples:

Successful profilesFree planBronze plan
1$0.00818$0.00776
5$0.02090$0.01882
25$0.08449$0.07412
100$0.32294$0.28147

Residential proxy transfer and browser runtime are handled inside the Actor. Large lists are usually more economical than many one-profile runs because the start event is paid once and healthy sessions are reused.

Getting started

  1. Open the Actor in Apify Console.
  2. Add Reddit usernames under Reddit usernames.
  3. Optionally add existing Reddit profile links under Reddit profile URLs.
  4. Keep Use residential proxy enabled for reliable Reddit access.
  5. Start with concurrency 1 or 2.
  6. Click Start.
  7. Open the Profiles dataset output.
  8. Export the rows as JSON, CSV, Excel, XML, or RSS.

Example input:

{
"usernames": ["spez", "reddit", "AutoModerator"],
"maxItems": 3,
"maxConcurrency": 2,
"maxRetries": 2,
"useResidentialProxy": true,
"proxyCountryCode": "US"
}

Input parameters

ParameterTypeDefaultDescription
usernamesstring array[]Reddit usernames without u/
startUrlsrequest list[]reddit.com/user/... or reddit.com/u/... profile URLs
maxItemsinteger20Maximum unique profiles after deduplication
maxConcurrencyinteger2Parallel profile workers; allowed range 1–5
maxRetriesinteger2Session-rotating retries for transient failures; allowed range 0–4
useResidentialProxybooleantrueUse Apify residential proxy sessions
proxyCountryCodestringUSTwo-letter ISO proxy country code

At least one valid username or profile URL is required. Malformed usernames, unsupported URLs, invalid country codes, and out-of-range limits fail the run before scraping.

Output example

A current public profile produces a row shaped like this:

{
"username": "exampleuser",
"redditUserId": "abc123",
"status": "success",
"statusMessage": null,
"createdAt": "2020-01-15T12:00:00.000Z",
"accountAgeDays": 1825,
"totalKarma": 15420,
"linkKarma": 4210,
"commentKarma": 10980,
"awardeeKarma": 180,
"awarderKarma": 50,
"followersCount": 230,
"bio": "Example public profile bio.",
"profileTitle": "Example Profile",
"profileDescription": null,
"avatarUrl": "https://styles.redditmedia.com/example-avatar.png",
"bannerUrl": null,
"canonicalUrl": "https://www.reddit.com/user/exampleuser/",
"verified": false,
"hasVerifiedEmail": true,
"isEmployee": false,
"isGold": false,
"isMod": true,
"isNsfw": false,
"isSuspended": false,
"profileVisibility": "user",
"scrapedAt": "2025-01-15T12:00:00.000Z"
}

The example is anonymized. Actual values come from the requested public Reddit account.

Status and failure behavior

The Actor never turns a Reddit block into a false missing account.

  • success: a recognizable public account payload was resolved.
  • not_found: Reddit explicitly returned HTTP 404 or a 404 JSON response.
  • suspended: Reddit identified the account as suspended.
  • private: the returned profile visibility is private.
  • blocked: Reddit returned a challenge/interstitial or exhausted 403/418/429 responses.
  • failed: another upstream, browser, network, or payload-shape error exhausted retries.

Every accepted unique target receives one row, even when the profile cannot be resolved. This makes bulk joins and watchlist audits deterministic.

Tips for reliable runs

  • Leave residential proxy enabled; Reddit commonly blocks datacenter traffic.
  • Start with concurrency 1 for small, high-value lists.
  • Use concurrency 2 for normal bulk refreshes.
  • Increase concurrency only when the observed block rate remains low.
  • Keep retries at 2 unless a workflow has strict latency requirements.
  • Split very large watchlists into scheduled batches.
  • Use the status field to route retryable and terminal outcomes separately.
  • Deduplicate upstream when you want stable billing estimates; the Actor also deduplicates input.

Limits

  • Only anonymous public profile metadata is extracted.
  • Posts, comments, messages, and private account data are excluded.
  • Reddit can change fields, verification behavior, and rate limits.
  • Some flags or profile assets are not exposed for every account and remain null.
  • Follower counts depend on what Reddit exposes in the public profile payload.
  • Account age is computed at scrape time and changes between runs.
  • Deleted and suspended account response shapes can vary.
  • Residential proxy access must be available in the Apify account running the Actor.

Integration workflows

Moderation intake

Send usernames from a moderation queue, then use account age, karma, and status fields as inputs to a human-reviewed risk workflow. Do not use a single field as an automatic enforcement decision.

Audience list enrichment

Join exported rows back to a CRM, spreadsheet, or warehouse on lowercase username. Preserve redditUserId for stable account-level tracking.

Scheduled watchlist refresh

Create an Apify schedule that runs daily or weekly. Store each run's scrapedAt, karma, follower, and flag fields for downstream comparisons.

Trust-and-safety routing

Route blocked and failed rows to a later retry. Treat not_found separately because it requires an explicit Reddit 404.

Run with the Apify API using cURL

Replace YOUR_TOKEN with an Apify API token:

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~reddit-user-profile-bulk-scraper/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"usernames": ["spez", "reddit"],
"maxItems": 2,
"maxConcurrency": 1,
"useResidentialProxy": true
}'

To wait for results synchronously:

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~reddit-user-profile-bulk-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"usernames":["spez"],"maxItems":1}'

Run with JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor(
'automation-lab/reddit-user-profile-bulk-scraper'
).call({
usernames: ['spez', 'reddit'],
maxItems: 2,
maxConcurrency: 1,
useResidentialProxy: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Install the client with:

$npm install apify-client

Run with Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor(
"automation-lab/reddit-user-profile-bulk-scraper"
).call(run_input={
"usernames": ["spez", "reddit"],
"maxItems": 2,
"maxConcurrency": 1,
"useResidentialProxy": True,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Install the client with:

$pip install apify-client

Use with MCP and AI agents

Add the Actor to Claude Code through Apify MCP:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/reddit-user-profile-bulk-scraper"

Claude Desktop

Add the following remote MCP server JSON to Claude Desktop's MCP configuration.

Cursor

Use Settings → Tools & MCP → Add MCP server and supply the same remote URL.

VS Code

Add the same remote server object to your workspace or user MCP configuration.

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/reddit-user-profile-bulk-scraper"
}
}
}

Example prompts:

  • “Enrich these 50 Reddit usernames and return account age, karma, and moderator status.”
  • “Check this Reddit profile watchlist and separate missing, suspended, blocked, and successful accounts.”
  • “Create a CSV-ready table of public bios, follower counts, karma, and profile URLs.”

Responsible use and legality

This Actor accesses anonymous public Reddit profile metadata. Use it only for lawful purposes and in accordance with applicable laws, Reddit's terms, Apify's terms, and your organization's policies.

Do not use the output to harass users, bypass access controls, infer private traits, or make high-impact automated decisions without appropriate review. Minimize stored personal data, set retention limits, secure exports, and honor valid deletion or access requests where applicable.

You are responsible for determining the lawful basis for your processing and for complying with privacy, employment, consumer-protection, and other relevant rules.

Troubleshooting

Why did I receive blocked instead of not_found?

Reddit returned a challenge, rate limit, or blocked response rather than an explicit 404. The Actor reports that uncertainty honestly. Retry later with residential proxy enabled and conservative concurrency.

Why are some values null?

Reddit does not expose every field for every account. The Actor preserves missing values as null rather than fabricating defaults.

Why did the run fail before producing rows?

Check for malformed usernames, non-Reddit URLs, an invalid proxy country, or out-of-range numeric inputs. Input validation intentionally fails closed.

Can I scrape posts and comments too?

Not with this profile-only Actor. Use the related Reddit Scraper for activity, community, and search workflows.

Can I disable the proxy?

Yes, for diagnostics, but Reddit frequently blocks datacenter and direct traffic. The default residential route is recommended for real workloads.

FAQ

Does the Actor require a Reddit account?

No. It uses anonymous public surfaces and does not accept Reddit credentials or cookies.

Does one input always produce one output row?

Each unique, valid username accepted after deduplication produces exactly one row. Duplicate username and URL forms collapse to one case-insensitive target.

Are unresolved rows charged as profiles?

No. Only success rows emit the per-profile charge event.

Can I schedule it?

Yes. Use Apify Schedules to refresh a watchlist daily, weekly, or at another interval.

What export formats are available?

Apify datasets support JSON, JSONL, CSV, Excel, XML, and RSS exports.

  • Reddit Scraper — scrape Reddit posts, comments, communities, and search results when you need activity content rather than one profile row per username.

Support

If Reddit changes its public profile response or a valid input repeatedly returns an unexpected status, open an issue from the Actor's Apify Console page. Include a minimal reproducible input, run ID, and expected outcome. Do not include private credentials or personal data that is not already public.