Reddit Comments Scraper: Export Comments and Replies
Pricing
from $1.00 / 1,000 comments
Reddit Comments Scraper: Export Comments and Replies
Scrape Reddit comments and replies from any post: one row per comment with author, text, score, depth, parent id, time and permalink. Opens "load more comments" for up to 10,000 comments per post. Sort by best, top, new, controversial, old or Q&A. No login. Monitor mode for new comments.
Pricing
from $1.00 / 1,000 comments
Rating
0.0
(0)
Developer
The Mine Works
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
2
Monthly active users
9 hours ago
Last modified
Categories
Features
Share
From The Mine Works, makers of Reddit Scraper and Threads Scraper, with over 290,000 runs across 310+ public actors.
Updated 13 Nov 2026: Reddit now refuses its API and its .json pages to automated readers, so this actor reads comment threads from Reddit's own web pages. You get author, text, score, depth, parent and time for every comment again, with Reddit's "more comments" and "more replies" links opened. If a thread's web page cannot be read, the actor falls back to a public Reddit archive. Every row says which one it came from in data_source. Numbers measured before 5 Nov 2026, such as the 5,000 comments in 84 seconds in the image above, came from Reddit's old API, which the actor no longer uses.
Updated 10 Oct 2026: first release. One flat row per comment, Reddit's "load more comments" links opened for up to 10,000 comments per post, six comment orders, and monitor mode for new comments. Bookmark this Actor on its Store page so it is one click away next time.
Why choose this actor?
- More than the first screen. Reddit's page shows the first comments and hides the rest behind "more comments" and "more replies" links. This actor opens those links too, shallow levels first, and places every reply under its parent.
- One row per comment, ready for a spreadsheet. Every comment carries its post's title and link, the author, the text, the score, the time, its depth, the comment it replies to and a direct link. No nested JSON to unpack: sort by
positionto read the thread in Reddit's order, or joinparent_comment_idtocomment_idto rebuild the tree. - Pay per comment, nothing for errors. Posts that do not exist, links that are not Reddit posts, summary rows and comments you already have in monitor mode are never charged. No Reddit account, API key or cookies.
Part of The Mine Works Social media and video family: Threads Scraper, Reddit Scraper, Threads Search Scraper, Instagram Profile Scraper, Instagram Followers & Following, Reddit Search Scraper.
Guide and FAQs: Reddit Comments Scraper on themineworks.com.
Try it in one minute
Paste this into the input (JSON view) and press Start. It returns the first 100 comments of two popular threads, 200 rows. The actor takes about 15 seconds to start its browser; in our tests it then read about 300 comments in 25 seconds:
{"postUrls": ["https://www.reddit.com/r/AskReddit/comments/1wy51c1/what_cheat_code_for_life_do_you_wish_youd/","https://www.reddit.com/r/cats/comments/1x15wvi/after_being_homeless_for_15_year_my_cat_and_me/"],"maxCommentsPerPost": 100}
A post can be given as a full link from www, old, new or np.reddit.com, a redd.it short link, or just its id (1wy51c1). Share links of the reddit.com/r/<sub>/s/<code> kind are opened to find the post. The same post given twice is read once.
Apify's free plan includes $5 of credit every month, which covers about 2,400 comments at this actor's price.
Copy to your AI assistant
themineworks/reddit-comments-scraper on Apify. Exports every comment and reply of the Reddit posts you list, one flat row per comment, read from Reddit's web pages with Reddit's "more comments" and "more replies" links opened, a public Reddit archive as the fallback, with no Reddit login. Call ApifyClient("TOKEN").actor("themineworks/reddit-comments-scraper").call(run_input={"postUrls": ["https://www.reddit.com/r/AskReddit/comments/1wy51c1/"], "maxCommentsPerPost": 500}), then client.dataset(run["defaultDatasetId"]).list_items().items. Required: postUrls (list of Reddit post links, redd.it links or post ids; up to 1000). Optional: maxCommentsPerPost (default 500, 1 to 10000), maxDepth (default 10; 1 = top level comments only), commentSort ("best" default, "top", "new", "controversial", "old", "qa"), monitorMode (default false; delivers only comments not delivered by an earlier run in the same Apify account). clientId is ignored and only kept so old inputs run. Comment rows have no _type field and carry comment_id, comment_fullname, post_id, post_title, post_url, post_author, post_num_comments, subreddit, subreddit_id, author, body, score, created_utc, created_iso, depth, parent_id, parent_comment_id, is_top_level, is_submitter, permalink, position, comment_sort, data_source ("web" or "archive"), score_note (only on archive rows under about 36 hours old), scraped_at; fields with no value are left out. Each run also writes one row with _type "summary", one with _type "info" when comments were delivered, and a row with _type "error" for each post that could not be read; none of these is charged. Full spec: GET https://api.apify.com/v2/acts/themineworks~reddit-comments-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations?fpr=ymnoit&utm_source=apify-readme&utm_medium=referral
Key features
- Up to 10,000 comments per post. The page gives the first comments; after that the actor opens Reddit's "more comments" and "more replies" links, shallow levels first, so more top level comments come before deeper replies when a thread is cut. It stops at
maxCommentsPerPost, at the end of the thread, or at the run's time limit, whichever comes first. - Reddit's thread order kept. Comments come out in thread order: a comment, then its replies.
positionnumbers the rows in that order. A reply whose parent was not read comes at the end, so nothing read is lost. - Replies linked both ways.
parent_idholds Reddit's own reference (t3_for the post,t1_for a comment),parent_comment_idthe plain id of the parent comment,is_top_levelanddepththe level. - Six comment orders. best (Reddit's default), top, new, controversial, old and Q&A, the same choices as the sort menu on reddit.com.
- Monitor mode. Remembers up to 50,000 comment ids it delivered to you and skips them on later runs, so a scheduled run pays only for new comments.
- Deadline safe. The actor watches the run's time limit, stops cleanly before it runs out, keeps every comment it read, and says why in the summary row.
How the comments are collected
- Reddit's web page (live). The actor opens the post the way a visitor does, in a browser on a home internet connection. It only waits for Reddit's own check page to pass; it never clicks or solves anything. The page shows the first comments; the actor then opens Reddit's own "more comments" and "more replies" links, shallow levels first, until it has
maxCommentsPerPostor the thread ends. These rows saydata_source: web. Two limits:- Very deep chains are not opened. Replies nested deeper than Reddit's page shows, behind a "Continue this thread" link, are not followed.
- Deleted comments with no replies are not there. Reddit's page does not show them, so they are not in the rows. A deleted or removed comment that has replies is kept, because its replies point to it.
- The archive (fallback). When a post's web page cannot be read, the same thread is read from a public Reddit archive. These rows say
data_source: archive. Three things differ:- Scores can lag. The archive saves a comment soon after it is written and updates its score about 36 hours later. A comment younger than that may show a lower score than Reddit does today, and its row carries a
score_notesaying so. - Deleted and removed comments are left out. Their replies are kept, and their
parent_idstill names the missing comment. commentSortis not applied. The archive has no sort menu, so an archive thread comes in the archive's own order.
- Scores can lag. The archive saves a comment soon after it is written and updates its score about 36 hours later. A comment younger than that may show a lower score than Reddit does today, and its row carries a
The run's status message says when any thread came from the archive.
How to use it
Basic: every comment of one thread
{"postUrls": ["https://www.reddit.com/r/AskReddit/comments/1wy51c1/what_cheat_code_for_life_do_you_wish_youd/"],"maxCommentsPerPost": 3000}
Each comment is one row. Set maxCommentsPerPost to the size of the thread (the summary row shows the count Reddit reports as num_comments_reported) to read all of it.
Brand monitoring: new comments on your launch or AMA thread
{"postUrls": ["https://www.reddit.com/r/SaaS/comments/<your post id>/"],"commentSort": "new","maxCommentsPerPost": 500,"monitorMode": true}
Save it as a task and add a schedule (every hour or every day). The first run delivers the thread; each later run delivers and charges only comments that were not in an earlier run. Sorting by new puts fresh top level comments first.
Competitor research: what buyers say on a rival's threads
Collect a competitor's launch post, its biggest complaint thread and a "X vs Y" discussion in one run:
{"postUrls": ["https://www.reddit.com/r/<subreddit>/comments/<id1>/","https://www.reddit.com/r/<subreddit>/comments/<id2>/","https://redd.it/<id3>"],"commentSort": "top","maxCommentsPerPost": 1000}
Filter rows on score to keep the opinions most people agreed with, and on is_submitter to separate the original poster's answers from everyone else's.
Pain point research: "what tool do you wish existed" threads
Threads where people list their problems are often the richest comment sections on Reddit. Find them with Reddit Search Scraper (for example "is there a tool" subreddit:smallbusiness), then pass the post links here with maxDepth: 2 to keep each complaint and the direct replies that agree or suggest a fix.
AI datasets: question and answer pairs
{"postUrls": ["https://www.reddit.com/r/AskReddit/comments/1wy51c1/what_cheat_code_for_life_do_you_wish_youd/"],"commentSort": "top","maxDepth": 2,"maxCommentsPerPost": 2000}
post_title is the question, depth 0 rows are answers, depth 1 rows are reactions to them. score is a quality signal. body is the text as the page shows it on web rows (paragraphs, lists and quotes kept as plain text) and Reddit's markdown on archive rows.
Moderation review: the controversial side of a thread
{"postUrls": ["https://www.reddit.com/r/<subreddit>/comments/<id>/"],"commentSort": "controversial","maxCommentsPerPost": 500}
Web rows come in Reddit's controversial order, so the most divided comments come first. To find the busiest arguments, count replies per comment by joining parent_comment_id to comment_id. Reddit's page no longer shows the controversial mark, the moderator mark, the pinned flag or the collapsed flag, so those are not in the rows.
Input parameters
| Parameter | Type | Default | What it does |
|---|---|---|---|
postUrls | array of strings | required | Reddit post links (www, old, new, np), redd.it links, share links or post ids. Up to 1,000 per run. |
maxCommentsPerPost | integer | 500 | Most comments per post, top level and replies together, 1 to 10,000. The actor opens "more comments" links until it has this many or the thread ends. |
maxDepth | integer | 10 | Levels of the thread to return: 1 = top level only, 2 = plus direct replies, up to 10. |
commentSort | string | best | best, top, new, controversial, old or qa. Decides which comments come first. |
monitorMode | boolean | false | Delivers and charges only comments not delivered to you by an earlier run. |
clientId | string | empty | No longer needed and ignored. It stays so older inputs still run. Leave it blank. |
What data do you get?
One row per comment. Comment rows have no _type field; the summary, info and error rows do, so a filter on _type separates them.
| Field | What it is |
|---|---|
comment_id | Reddit's comment id, e.g. pdzjpb2 |
comment_fullname | The id with its t1_ prefix, the value replies point to |
post_id, post_title, post_url, post_author | The post the comment is on |
post_num_comments | Comment count Reddit showed on the post when the row was read |
subreddit | Where the post lives |
subreddit_id | Reddit's id for the subreddit; on web rows, from the post page |
author | Who wrote the comment; [deleted] when the account is gone |
body | Comment text: as the page shows it on web rows, Reddit's markdown on archive rows; [deleted] when gone |
score | Votes at the time of the run (on young archive rows, see score_note) |
created_utc, created_iso | When it was posted (Unix seconds and ISO 8601, UTC) |
depth, is_top_level | 0 for a top level comment, 1 for a reply to it, and so on |
parent_id, parent_comment_id | What it replies to: t3_<post> or t1_<comment>, and the plain parent comment id |
is_submitter | True when the post's author wrote the comment. Worked out from the two usernames, so it is left out when either is deleted |
permalink | Direct link to the comment |
position | Place in the thread as read, 1 = first |
comment_sort | The order the thread was read in |
data_source | web (Reddit's own page, live) or archive (the public Reddit archive, used when the page could not be read) |
score_note | Only on archive rows under about 36 hours old: the score may still be lower than on Reddit |
scraped_at | When the row was written |
These fields are no longer filled, because Reddit's web page does not show them: author_fullname, author_flair_text, score_hidden, controversiality, awards_count, edited, edited_utc, distinguished, stickied, locked, collapsed. They are left out of the row, never shown as 0 or false.
Summary row (_type: "summary", never charged): posts_requested, posts_read, posts_failed, posts_not_started, invalid_urls, comments_found, comments_delivered, charged_for, posts_from_web, posts_from_archive, ended_on_deadline, stopped_by_max_cost, shortfall_reason when fewer comments came back than asked, and per_post, one entry per post with num_comments_reported, comments_read, comments_delivered, stopped, complete, source (web or archive) and route_note. The same summary is saved as the OUTPUT record of the run.
Error rows (_type: "error", never charged): one per post that could not be read, with error_type (not_found, fetch_error or invalid_url), identifier and reason.
Stable fields for automations
These are on comment rows from both routes, and their names will not change:
| Field | What it is |
|---|---|
comment_id | The key to store and join on |
comment_fullname | Join target for parent_id |
post_id | The post's id |
post_title | The post's title |
post_url | Link to the post |
subreddit | Subreddit name |
author | Commenter's username or [deleted] |
body | Comment text |
score | Score when read |
created_utc | Unix seconds, UTC |
created_iso | ISO 8601, UTC |
depth | Level in the thread |
parent_id | Reddit's parent reference |
permalink | Link to the comment |
position | Thread order |
data_source | web or archive |
Optional, present only when there is a value: parent_comment_id (absent on top level comments), is_submitter (absent when either username is deleted), post_author, post_num_comments, subreddit_id, score_note (only on archive rows under about 36 hours old).
Output examples
A top level comment and the first reply under it, from the "Try it" input above, trimmed. The values come from a test run on 10 Oct 2026; the fields are the ones a web row has now:
[{"comment_id": "pdzjpb2","comment_fullname": "t1_pdzjpb2","post_id": "1wy51c1","post_title": "What 'cheat code' for life do you wish you'd discovered earlier?","post_url": "https://www.reddit.com/r/AskReddit/comments/1wy51c1/what_cheat_code_for_life_do_you_wish_youd/","post_author": "Unnamedaccount0","post_num_comments": 2889,"subreddit": "AskReddit","author": "explodingkraken","body": "Give people appreciation. That's what most people want, and they'll remember you for it. ","score": 9738,"created_utc": 1791196213,"created_iso": "2026-10-05T10:30:13.000Z","depth": 0,"parent_id": "t3_1wy51c1","is_top_level": true,"is_submitter": false,"permalink": "https://www.reddit.com/r/AskReddit/comments/1wy51c1/what_cheat_code_for_life_do_you_wish_youd/pdzjpb2/","position": 1,"comment_sort": "best","data_source": "web"},{"comment_id": "pe0h7sz","comment_fullname": "t1_pe0h7sz","post_id": "1wy51c1","subreddit": "AskReddit","author": "notacrook","body": "And doing it publicly if appropriate (its a really great thing in a work setting too): ...","score": 2074,"created_iso": "2026-10-05T13:41:45.000Z","depth": 1,"parent_id": "t1_pdzjpb2","parent_comment_id": "pdzjpb2","is_top_level": false,"is_submitter": false,"permalink": "https://www.reddit.com/r/AskReddit/comments/1wy51c1/what_cheat_code_for_life_do_you_wish_youd/pe0h7sz/","position": 2,"data_source": "web"}]
The shape of the summary row for that input, trimmed (the comment counts Reddit reports change over time):
{"_type": "summary","posts_requested": 2,"posts_read": 2,"comments_found": 200,"comments_delivered": 200,"charged_for": 200,"posts_from_web": 2,"posts_from_archive": 0,"ended_on_deadline": false,"per_post": [{ "post_id": "1wy51c1", "num_comments_reported": 2889, "comments_read": 100, "comments_delivered": 100, "stopped": "max_comments_reached", "complete": false, "source": "web" },{ "post_id": "1x15wvi", "num_comments_reported": 3412, "comments_read": 100, "comments_delivered": 100, "stopped": "max_comments_reached", "complete": false, "source": "web" }]}
Error rows for a post that does not exist and a link that is not Reddit (nothing charged for either):
[{ "_type": "error", "error_type": "not_found", "identifier": "https://www.reddit.com/r/AskReddit/comments/zzzzzzzq/this_post_does_not_exist/", "reason": "Post zzzzzzzq was not found: Reddit's page has no such post (removed, private or a wrong id) and the archive does not have it either." },{ "_type": "error", "error_type": "invalid_url", "identifier": "https://example.com/not-a-reddit-link", "reason": "Not a Reddit post link. Use a link that contains /comments/<id>/, a redd.it link, or a post id such as 1wy51c1." }]
Pricing
Pay per event: you pay for the comments you receive, plus a flat $0.005 per run, whatever memory you choose.
| Event | When it is charged | Free plan | Bronze (Starter) | Silver (Scale) | Gold (Business) |
|---|---|---|---|---|---|
comment-scraped | Once per comment row stored in your dataset | $2.00 per 1,000 | $1.50 per 1,000 | $1.25 per 1,000 | $1.00 per 1,000 |
run-start | Once per run, when the first thread has loaded (a run that reads no post pays nothing) | $0.005 | $0.005 | $0.005 | $0.005 |
The price of one comment is the price per 1,000 divided by 1,000.
Never charged:
- posts that do not exist, are private or banned, and links that are not Reddit posts (each gets an error row);
- comments skipped by monitor mode because an earlier run delivered them;
- comments read past your
maxCommentsPerPost; - the summary, info and error rows;
- a run with no valid post link, or one where no thread can be read: it ends before the start fee;
- anything past your "Max cost per run". The actor checks the budget before each batch of rows and stops while the total is still below your limit, so the run ends SUCCEEDED with a partial result and a status message saying so.
Run it on a schedule
- Open the actor in Apify Console, set your input and click Save as a new task.
- In the task, open Schedules, click Add schedule and pick how often (every hour, every day at 08:00 and so on).
- Turn on
monitorModein the task's input so each run delivers and charges only comments you have not received yet. - Optional: add an integration (Google Sheets, Slack, a webhook) so new comments land where your team works.
Monitor mode keeps the ids of up to 50,000 delivered comments in a storage named monitor-reddit-comments-scraper in your own Apify account, shared by all your runs of this actor. If that storage cannot be opened, the run says so in its log, delivers everything, and sets monitor_degraded: true in the summary row.
FAQ
What does this actor read?
The public comment section of the Reddit posts you list, as anyone sees it without logging in: Reddit's web page for each post, with its "more comments" and "more replies" links opened, or a public Reddit archive's copy of the thread when the page cannot be read. It does not read posts you have not listed; for whole subreddits use Reddit Subreddit Scraper.
How many comments can I get per post?
Up to 10,000 per post, set in maxCommentsPerPost, and up to 1,000 posts per run. The page gives the first comments; each "more comments" or "more replies" link the actor opens adds about 10 more. It stops at your maxCommentsPerPost, at the end of the thread, or at the run's time limit, whichever comes first. A thread of many thousands of comments takes many of those links, so give such a run a longer time limit.
Why do I get fewer comments than the number Reddit shows?
Reddit's count includes deleted and removed comments, which its page does not show when they have no replies. Very deep chains ("Continue this thread") are not opened. On archive rows, deleted and removed comments are left out, and the archive folds part of a very big thread, so an archive thread can stop short of maxCommentsPerPost. If you set maxCommentsPerPost below the thread size, the run stops there on purpose.
In what order do the comments come, and how do I rebuild the thread?
On web rows, in Reddit's thread order for the commentSort you chose: a comment, then its replies, then the next comment. Archive rows come in the archive's own order. position numbers the rows in the order they were read. To rebuild the tree, link each row's parent_comment_id to the comment_id of another row; top level comments have is_top_level: true and no parent_comment_id. On archive rows, a reply to a deleted comment points to a comment that is not in the rows.
What do maxDepth and commentSort change?
maxDepth is how many levels you keep: 1 returns top level comments only, 2 adds the direct replies, 10 returns every level the page shows. It works on both routes. commentSort is the order of the thread, the same menu as on reddit.com, and it decides which comments come first when maxCommentsPerPost cuts a thread. It applies to the live pages only; the archive has no sort. When a thread is cut, top level comments are opened before deeper replies.
How long does a run take?
About 15 seconds to start the browser, then about 300 comments in 25 seconds in our tests (three threads of 100 each). Bigger threads take longer, because each "more comments" link is one more page.
Do I need a Reddit account, API key, cookies or a proxy?
No. The actor brings its own browser and connection. Nothing to set up. The old clientId field is ignored.
What happens with deleted, removed, private or missing posts?
A post that cannot be found on Reddit's page or in the archive gets an error row not_found and is not charged. A post that cannot be read for another reason gets fetch_error, also not charged. A run where no post can be read on either route costs nothing and ends as FAILED with the reason. A deleted or removed post that still has comments is read for its comments. On web rows, a deleted or removed comment that has replies comes back as [deleted], because its replies still point to it; one with no replies is not on Reddit's page, so it is not in the rows. On archive rows, deleted and removed comments are left out.
Which link formats work?
Full post links from www, old, new and np.reddit.com (with or without the title part, or ending in a comment id), reddit.com/comments/<id>, redd.it/<id>, bare post ids such as 1wy51c1, and share links like reddit.com/r/<sub>/s/<code>, which the actor opens to find the post. If a share link cannot be opened, paste the full address instead.
How does monitor mode work with maxCommentsPerPost?
Each run reads the thread up to maxCommentsPerPost and delivers only the comments not delivered before. With commentSort: "new" the newest top level comments come first, so a run every hour or day catches fresh comments. Replies to older comments are caught as long as they fall inside the comments the run reads.
What happens when a run reaches its time limit?
The actor stops reading about 35 seconds before the run's timeout (900 seconds unless you change it), delivers every comment it read, and ends SUCCEEDED with ended_on_deadline: true, a shortfall_reason, and the number of posts it did not start in posts_not_started. Part of the time is kept back so the archive can still read any thread the live pages could not.
Which Reddit actor should I use?
This one when you have the posts and want their comments as rows. Reddit Scraper for posts from subreddits, search, users or links with comments nested inside each post. Reddit Search Scraper to find posts by keyword. Reddit Subreddit Scraper for the posts of whole subreddits. Reddit User Scraper for profiles, karma and a user's post and comment history.
Which formats can I download?
JSON, CSV, Excel, XML, RSS and HTML from the run's Storage tab or through the API. Rows are flat, so CSV and Excel keep every field. The dataset has two ready views: Comments and Thread structure.
Can I use it from Claude, ChatGPT or Cursor (MCP)?
Yes, through Apify's MCP server. Connector URL: https://mcp.apify.com/?tools=themineworks/reddit-comments-scraper
- Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
- ChatGPT: turn on developer mode, add an MCP connector with the URL, sign in with Apify.
- Cursor or VS Code: add it as an HTTP MCP server with that URL.
- Claude Code:
claude mcp add -t http reddit-comments-scraper "https://mcp.apify.com/?tools=themineworks/reddit-comments-scraper"
Is it legal to scrape Reddit comments?
The actor reads only public comments that anyone can see without logging in. Comments contain usernames and what people chose to write in public; you are responsible for how you use them, including Reddit's terms and data protection law such as GDPR and CCPA. This is general information, not legal advice.
Integrations
- Google Sheets: send each run's comments to a sheet with Apify's Google Sheets integration; one row per comment fits a sheet as is.
- Make, Zapier and n8n: start a run and read its dataset with the Apify apps and nodes, for example "new comments on our launch thread to Slack".
- Webhooks: have Apify call your URL when a run succeeds, then fetch the dataset.
- API and SDKs: run it from Python or JavaScript with the Apify client, or with a plain HTTP call (see "Copy to your AI assistant" above).
- MCP clients: Claude, ChatGPT, Cursor and VS Code can run it as a tool through the connector URL in the FAQ.
More from The Mine Works
Social media and video
- Threads Scraper
- Reddit Scraper
- Threads Search Scraper
- Instagram Profile Scraper
- Instagram Followers & Following
- Reddit Search Scraper
- Twitter / X Scraper
- YouTube Transcript
- Xiaohongshu (RED) Scraper
- Telegram Channel Scraper
- Telegram Channel Finder
- Pinterest Profile Scraper
Leads and business directories
Marketing, SEO and reviews
Real estate
Science, health and government data
Jobs and hiring
Company and business data
E-commerce and marketplaces
Food and local services
Developer and AI tools
More tools
Support
Found a thread that should return more comments, or a link format that is not read? Open an issue in the Issues tab with the input and the run ID, and we will look at it. For a field you need or a new source, email dmineworks@gmail.com.
Give Reddit post links and get every comment and reply back as one row each, with author, text, score, depth, parent and time, up to 10,000 comments per post, no login.

