Reddit Post Comments Scraper — Full Comment Tree, Any Post URL
Pricing
$1.50 / 1,000 per comment returneds
Reddit Post Comments Scraper — Full Comment Tree, Any Post URL
Reddit comments scraper: paste post URLs (permalinks, redd.it, share links, comment links) and get every comment as flat rows with parent id, depth, thread path, reply and descendant counts, author, score, timestamps. Expands 'load more' stubs. No login or API key.
Pricing
$1.50 / 1,000 per comment returneds
Rating
0.0
(0)
Developer
Scrapers Delight
Maintained by CommunityActor stats
0
Bookmarked
9
Total users
5
Monthly active users
10 days ago
Last modified
Categories
Security
Limited permissionsShare
Paste Reddit post URLs and get every comment under them as flat rows that still carry the tree. One row per comment: body, author, score, depth, parent_comment_id, thread_path, reply_count, descendant_count, position, created_iso, edited, permalink, is_deleted and the post context on every row (post_title, post_url, post_score, post_num_comments, tree_complete). Reddit shows a big thread in pieces — the first 25 comments, then "N more replies", "View more comments" and "Continue this thread" links. This Actor opens every one of them, so a big thread comes back whole. No login. No Reddit API key. No CAPTCHA solving.
{"postUrls": ["https://www.reddit.com/r/programming/comments/luq9oz/how_i_cut_gta_online_loading_times_by_70/"],"commentSort": "top","maxCommentsPerPost": 200}
Click Try for free and hit Start — that block is the input the Actor ships with: the
first 200 comments of that thread in top order, for $0.30.
What makes it different
- Tree fields that are computed, not copied. Every row has
parent_comment_idanddepth, plusthread_path(root-first list of ancestor comment ids, so oneJOINrebuilds any branch),reply_count(direct replies present),descendant_count(whole subtree size),is_top_levelandposition(delivery order). "Which top-level comment started the biggest argument" isORDER BY descendant_count DESC WHERE is_top_level— no recursion on your side. - The hidden part of the thread, expanded. With
expandMoreCommentson (default) every "more replies" loader and every "Continue this thread" cut is opened, at any depth, until the tree is complete or your cap is hit. tree_completeon every row, andpost_num_commentsto check it against. You never have to guess whether a thread was cut by a cap, the time budget or a loader that would not open — the row says so, and the log printsdelivered of N reddit countsper post.
Also: any URL shape Reddit produces is accepted — desktop permalinks, redd.it short
links, the mobile app's /r/sub/s/AbCdEfG share links (resolved live from Reddit's redirect),
profile post links (/user/name/comments/…), old. / new. / np. subdomains, bare ids, and
comment permalinks: paste a link to one comment and you get that comment's thread only
(scope: "comment-thread", focus_comment_id set).
Read this before you buy rows
post_num_commentsis Reddit's counter, not a promise. It is kept separately from the tree and drifts both ways: deleted comments that still have replies stay in the tree as[deleted]rows, while deleted comments with no replies are not shown at all.tree_complete: truemeans every loader Reddit offered was opened.- The per-post cap cuts after the tree math. With
maxCommentsPerPost: 200you get the first 200 rows in the order Reddit's page serves them (the top-level comments of the first page and their replies first), and each row still carries thereply_count/descendant_countof everything fetched.thread_pathcan name an ancestor that is not in your rows — it is an id, not a join failure. [deleted]and[removed]rows are real rows. Reddit keeps them so the tree stays connected. They come withis_deleted: true,body"[deleted]"/"[removed]", and usually no score; they are billed like any other row. SetincludeDeleted: falseto drop them unbilled.- Score is a snapshot. Re-run later if you need settled scores.
- Big trees take calls. Reddit's page opens about 10 comments per "more replies" loader, so the whole tree of a ~1,000-comment thread is several hundred Reddit calls and a few minutes; the shipped 200-comment cap is about 25 calls.
What you get
One row per unique comment, deduplicated on Reddit's fullname (t1_…) across the whole run.
Timestamps are ISO-8601 UTC plus the raw created_utc epoch. edited is false, or the ISO
time of the edit.
| Group | Fields | Example |
|---|---|---|
| Identity | id, name, post_id, permalink, subreddit, subreddit_id | gp8beoa · t1_gp8beoa · luq9oz |
| Tree | parent_id, parent_comment_id, is_top_level, depth, position, reply_count, descendant_count, thread_path[] | depth 2 · 7 replies · 53 descendants |
| Author | author, author_fullname, author_flair_text, author_is_op | deruke |
| Content | body, body_length, is_deleted, edited, distinguished, stickied, locked, collapsed, collapsed_reason | 525 chars |
| Votes | score, ups, score_hidden, total_awards_received | 3034 |
| Time | created_utc, created_iso | 2021-02-28T21:35:00.233Z |
| Post context | post_title, post_url, post_author, post_subreddit, post_score, post_upvote_ratio, post_num_comments, post_created_iso, post_link_flair_text, post_is_self, post_external_url, post_selftext_preview, post_over_18, post_locked, post_archived | 992 comments · ratio 0.97 |
| Provenance | source (listing / more-children / continue-thread), scope, focus_comment_id, comment_sort, tree_complete, comments_delivered_for_post, comments_absent_at_source, input_url, scraped_at |
body is the comment as plain text: paragraphs on their own lines, list items as - item,
quotes as > line, code blocks verbatim, links as their text.
Fields Reddit does not show logged-out visitors (measured on 1,006 rows of the
thread above, 2026-10-27): author_fullname 0.8% (only where a subreddit renders user
flair), author_flair_text 0% on r/programming, collapsed_reason always null, stickied / locked null unless set,
comments_absent_at_source always 0. Every other field is filled on every row it applies to:
score 96.4% (deleted rows carry none), edited holds the edit time on the 3.9% of rows that were edited, distinguished on moderator comments.
Every run prints a measured fill line in the log for the 12 fields most likely to vary by subreddit, so you can check your own subreddit.
The dataset ships with a Comments table view (post, depth, author, score, body, replies, thread size, posted, tree complete, link).
How to run it
1. One or many post URLs (the usual choice)
{"postUrls": ["https://www.reddit.com/r/programming/comments/luq9oz/how_i_cut_gta_online_loading_times_by_70/","https://redd.it/1xgauuz","https://www.reddit.com/r/AskReddit/s/AbCdEfGhIj","t3_luq9oz"],"commentSort": "top","maxCommentsPerPost": 0}
maxCommentsPerPost: 0 = the whole tree. Share links are resolved to the canonical permalink
from Reddit's own redirect and the log prints the resolution.
2. One comment's thread only
{ "postUrls": ["https://www.reddit.com/r/programming/comments/luq9oz/comment/gp8beoa/"] }
A comment permalink scopes the scrape to that comment and everything under it. Rows carry
scope: "comment-thread" and focus_comment_id: "gp8beoa"; the linked comment is depth 0.
3. Top-level comments and their direct replies
{ "postUrls": ["https://redd.it/luq9oz"], "maxDepth": 1, "maxCommentsPerPost": 0 }
maxDepth filters on the 0-based depth field, so maxDepth: 1 returns depths 0 and 1.
It filters after the tree math, so each row still carries reply_count and
descendant_count for the branch you did not buy. Filtered rows are never billed.
4. First page only, fastest and cheapest
{ "postUrls": ["https://redd.it/luq9oz"], "expandMoreComments": false }
One page per post (25 comments). tree_complete is honest about what you skipped.
Scheduling and integrations
Save the input as a Task, attach a Schedule to re-pull a thread as the discussion grows, and read the dataset over the REST API or the standard integrations (Zapier, Make, n8n, webhooks, MCP). Starting a run from the API:
curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~reddit-post-comments-scraper/runs?token=YOUR_TOKEN" \-H 'Content-Type: application/json' \-d '{"postUrls":["https://redd.it/luq9oz"],"maxCommentsPerPost":0}'
Input
Fields in the order the Console shows them.
| Field | Type | Default | What it does |
|---|---|---|---|
postUrls | string list | 1 sample post | Permalinks, redd.it, /s/ share links, profile-post links, comment permalinks, bare ids. One post pasted twice is fetched once. |
commentSort | select | top | top, best, new, controversial, old, qa — decides which rows come first under a cap. |
| 💷 Limits & cost | |||
maxCommentsPerPost | integer | 200 | Per post. 0 = the whole tree. |
maxTotalComments | integer | 0 | Hard cap for the run. 0 = none. The run's Max total charge is honoured to the whole row as well. |
| 🌳 Tree depth & filters | |||
expandMoreComments | boolean | true | Open "more replies" / "Continue this thread". Off = the first page only. |
maxDepth | integer | 0 | Keep depth ≤ N (0-based). 0 = unlimited. Filtered rows are never billed. |
includeDeleted | boolean | true | Off drops [deleted] / [removed] placeholders, unbilled. |
| ⚙️ Proxy & performance | |||
proxyConfiguration | proxy | Apify RESIDENTIAL, country US | Recommended as is — Reddit turns most datacenter IPs away. |
postsPerSession | integer | 40 | Posts served per session before a fresh one is opened (a session is also replaced when Reddit blocks it or its allowance is used up). |
requestDelayMs | integer | 300 | Pacing between the expansion calls. |
Pricing
$0.0015 per comment returned — $1.50 per 1,000. Charged on the comment-scraped event.
No monthly fee from this Actor.
| Run | Comments | Cost |
|---|---|---|
| The shipped default (1 post, 200 cap) | 200 | $0.30 |
| The whole tree of the sample thread | 1,006 | $1.51 |
| 5 posts × ~260 comments (a typical VoC pull) | 1,300 | $1.95 |
| 10,000 comments of a mega-thread | 10,000 | $15.00 |
- You are charged for rows delivered. Duplicates (same post pasted twice, overlapping
comment threads), rows removed by
maxDepth/includeDeleted, and posts that failed or were not found are never billed. - Rows are charged as they are pushed, one post at a time, so a budget cap or time stop leaves you with whole posts' worth of rows, every one of them billed, none unbilled.
maxCommentsPerPost× number of posts is your cost ceiling;maxTotalCommentsand the run's Max total charge are hard caps on top. A charge cap too low for even one comment fetches nothing and bills nothing.
Honest limits
- No user profiles, no subreddit listings, no search. This Actor does one thing: post URL → comment tree. Our Reddit Subreddit Scraper lists a subreddit's posts (and can attach comments).
- Plain text, no media. Images/GIFs in comments appear as their link text inside
body. - Private, quarantined and banned subreddits, and deleted posts, return nothing. The run names each such URL in its status message and moves on; if every post is like that the run ends SUCCEEDED with 0 rows and nothing charged.
Duplicates
Within a post, Reddit can show the same comment on more than one of its pages; the Actor keeps
a per-post set and a run-wide set keyed on the t1_ fullname, drops repeats before
billing, and asserts uniqueness across everything it pushed before the run is allowed to
succeed. Duplicates from input — the same post pasted as a permalink and a redd.it link, or a
comment permalink inside a post you also pasted whole — are dropped and logged, never billed.
When a run ends without rows
- Input that matches nothing (posts not found, private subreddits, share links that lead nowhere, lines that are not Reddit links) → SUCCEEDED, 0 rows, nothing charged, and the status message names each one.
- Reddit refuses every request (no session clears its check, or every post is refused on fresh exits) → FAILED with that reason in the status message; nothing is charged. Re-run later.
- Some posts fail, others deliver → SUCCEEDED with a
WARNING:status message counting what was skipped and why. - Time budget → stops cleanly with every fetched post pushed and a status message; never TIMED-OUT.
FAQ
Does this need an account, a login or cookies? No. It opens a logged-out session the way a browser does and reads the public pages. No credentials, no account cookies, no CAPTCHA service.
Can I get the whole thread, however big?
Yes — maxCommentsPerPost: 0. The sample thread came back as 1,006 rows in
542 Reddit calls; a 10,000-comment thread is thousands of calls across several
sessions (the Actor rotates them for you) — set the run timeout accordingly.
Why does the row count not match post_num_comments?
Reddit's counter is kept separately from the tree — see Read this before you buy rows.
tree_complete: true tells you every loader was opened.
Do I need a residential proxy? It is the default and the recommended setting: Reddit turns most datacenter IPs away.
Will two runs give me duplicates?
Within a run, never — asserted. Across runs, the name field is Reddit's permanent id, so
dedupe on it.
Feedback
Found a URL shape that does not parse or a field you need? Open an issue on the Issues tab, and if the Actor earns it, a review on the Reviews tab helps other buyers find it.