Reddit Scraper API - Posts, Comments & Monitoring avatar

Reddit Scraper API - Posts, Comments & Monitoring

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Reddit Scraper API - Posts, Comments & Monitoring

Reddit Scraper API - Posts, Comments & Monitoring

Scrape public Reddit posts, search, subreddits, media, and nested comments or monitor only newly observed posts. Anonymous read-only OAuth; no browser, proxy, login, cookies, or API key.

Pricing

from $1.00 / 1,000 results

Rating

5.0

(1)

Developer

Thirdwatch

Thirdwatch

Maintained by Community

Actor stats

5

Bookmarked

391

Total users

55

Monthly active users

15 hours ago

Last modified

Features

Limited permissions

Share

Reddit Scraper API - Posts, Comments, Search & Monitoring

Thirdwatch portfolio: 8,800+ users across 140+ public Actors, 2M+ records delivered, >95% run success. Explore all Thirdwatch Actors.

What you get

Extract public Reddit posts, subreddit listings, global search results, self-post text, engagement, media, and comments through anonymous read-only access. No Reddit login or user-supplied API key is required.

Why this Actor

  • Anonymous access — structured JSON results without a Reddit login or user-supplied API key.
  • 100 posts per page — paginate automatically to 1,000 posts per query.
  • Three query modes in one field — global search, subreddit listings, and search within a subreddit.
  • Full public post bodies — self-post text, media, flair, awards, crossposts, and moderation flags arrive in the structured response.
  • Comments included in the post price — embed up to 100 public comments without paying per comment row. Available detail depends on the source, as described below.
  • Persistent new-post monitoring — the first run creates a baseline; later complete runs return only unseen post IDs.
  • Zero unchanged result charges — a scheduled monitor with no new posts writes no dataset rows.
  • No duplicate billing — overlapping queries, URLs, and subreddit pages are deduplicated by Reddit post ID across the run.

Query patterns

InputBehavior
AI agentsSearch all public Reddit posts
r/programmingBrowse a public subreddit using the selected sort
r/programming: Python 3.14Search within one subreddit
startUrlsPaginate an existing Reddit listing/search page or fetch a post URL
postUrlsFetch exact public posts and optionally their comments

For a startUrl with an after or before cursor, pagination starts at that cursor. If the requested listing is unavailable, the Actor does not substitute a different listing whose cursor may mean something else.

URLs must point to supported Reddit pages; postUrls must point to individual Reddit posts. If a supplied URL is invalid, the run stops so it does not return results for an unintended target.

minScore, skipPinnedPosts, and newerThan apply to both listings and exact post URLs. The default minimum score is 0, so set a negative minScore if you also want negative-scoring posts. Invalid newerThan values stop the run. If a post's creation time cannot be verified while this date filter is active, the Actor omits that post and reports an incomplete target rather than guessing.

Basic subreddit run

{
"queries": ["r/programming", "r/python"],
"sort": "new",
"maxResults": 100
}

Global and subreddit-specific research

{
"queries": [
"AI coding agents",
"r/SaaS: customer support automation"
],
"sort": "relevance",
"timeFilter": "month",
"maxResults": 250,
"minScore": 5
}

Scheduled new-post monitoring

{
"queries": ["r/devops: alternative to", "r/sysadmin: recommend"],
"sort": "new",
"skipPinnedPosts": true,
"maxResults": 50,
"includeComments": true,
"maxCommentsPerPost": 20,
"monitorMode": "new-posts",
"monitorStoreName": "infrastructure-buyer-signals"
}

Save that input as an Apify Task and attach a Schedule. The first successful run emits the current baseline with changeType: "baseline". Later runs using the same monitor name emit posts this watch has not seen, with changeType: "new_post". The Actor commits state after publishing rows, providing at-least-once delivery. A target that cannot be read keeps its last checkpoint and is tried again on the next run.

When queries overlap, the Actor emits each post once while retaining a separate recent window for each query's continuity check.

Use one monitorStoreName per independent watch. Cloud runs use a lock to prevent overlapping runs of the same monitor; a run waits up to 30 seconds for it, then stops and can be retried. After an interrupted run, a retry may need to wait for the lock to expire. Local runs do not have this protection. Changing a query, sort, or filter changes the cohort; use a new monitor name. newerThan remains available for one-off timestamp-filtered exports but is not needed for persistent monitoring.

If a run writes an alert but stops before saving its state, a retry can return that post again. Deduplicate downstream by monitor name and post id when repeats matter.

If the run's spending limit prevents some alerts from being saved, the monitor leaves its state unchanged. Increase the limit before retrying; alerts already written in the interrupted batch may be repeated.

For newest-first watches, a full result window with no previously seen posts can indicate missed posts. The Actor checks just beyond the window for a known post. If it cannot confirm continuity, the alerts are still delivered, the target is listed as incomplete with the reason window_gap, and its last complete checkpoint is kept. Increase maxResults or schedule runs more often. With allowIncompleteMonitorFallback: false, the run instead stops without writing alerts or changing the baseline. This check can report a gap even when no posts were missed, and it cannot detect every possible gap.

allowIncompleteMonitorFallback is on by default, so a watch keeps running when keyword search or a New, Rising, or Hot subreddit listing is unavailable. Hot recovery is limited to named subreddits. Keyword searches use Reddit's app search when the regular search is unavailable, and newest-first subreddit watches keep their complete feed while it answers. The alternative can miss posts or use a different order, so every alert from an affected run has monitoringComplete: false. Check the run's OUTPUT key-value record: monitoringSourceStatus: "partial" lists the affected incompleteTargets, including when no alerts are returned, with reasons under incompleteReasons such as rate_limited, deadline, page_limit, or window_gap.

On these sources, a post raises a new_post alert only when it was created after the watch's last check, less a six-hour allowance for slow search indexing, and is not older than that target's baseline. Older posts the watch never saw are remembered without an alert or a result charge, and olderPostsNotAlerted in OUTPUT shows how many. A post that Reddit indexes later than the allowance can be missed. A target that fails keeps its checkpoint while other targets still deliver, and the run fails only when no target returns data. A first run using the fallback is an incomplete baseline.

Set allowIncompleteMonitorFallback: false to require complete data. Such a watch stops without writing alerts or state whenever a target is incomplete, which can include most keyword searches while Reddit limits its regular search. This option does not make monitoring complete.

To use the incomplete alternative directly for keyword searches, set preferIncompleteSearch: true. It can miss posts or return a different order, and all affected rows have discoveryComplete: false. The incomplete-monitor behavior above applies to monitors, and this option cannot be combined with allowIncompleteMonitorFallback: false. This option is off by default and does not change subreddit listings. It does not retry another source after a rate limit. Explicit search-page cursors from a different source cannot be used with this option.

For a single-word search inside a named subreddit, set includeAdultSearchSupplement: true, sort: "new", and timeFilter: "all" to also check up to 25 recent subreddit posts for adult-marked literal title or body matches. This selects incomplete app search directly and adds requests and latency; the extra requests can be rate-limited. Matching supplement rows have discoverySupplement: "recent-subreddit-feed"; the one-off OUTPUT target records whether the supplement was checked and how many matching candidates were found. The check covers only a recent feed page and can miss posts; it does not guarantee adult-content coverage. This option is off by default. Monitoring cannot combine it with allowIncompleteMonitorFallback: false; use a new monitor name when changing the option.

Optional incomplete fallback for subreddit listings

For a newest-first subreddit run, if the regular listing is refused or temporarily unavailable, the Actor may try Reddit's app feed. App results can miss or reorder posts, so rows carry discoveryComplete: false and the OUTPUT record reports a partial result. If the listing was refused and the app feed is unavailable without a rate limit, the Actor may try the matching public feed. This recovery does not translate an existing listing cursor or switch sources after a rate limit. Monitoring preserves the last complete checkpoint, and skips this recovery when allowIncompleteMonitorFallback is false. For a one-off run, allowPartialSubredditFallback: true also permits a Hot fallback for certain newest-listing failures; Hot results are sorted by creation time and can miss posts. The option is off by default and does not apply to keyword searches.

If the normal New or Rising sources fail without a rate limit, the Actor may also try a public web listing for a named subreddit. It checks each post against current Reddit data, but the listing may miss or reorder posts; rows are marked discoverySource: "web-subreddit-partial" and discoveryComplete: false. This route uses a residential connection and can add cost and latency. It does not apply to r/all, r/popular, existing listing cursors, or monitors with allowIncompleteMonitorFallback: false. Other monitors preserve the last complete checkpoint. A rate limit stops recovery.

If a named subreddit's Hot listing fails without a rate limit, the Actor may try an incomplete Hot feed. Posts are checked against current Reddit data, but the feed can miss or reorder them; rows are marked discoverySource: "graphql-subreddit-partial" and discoveryComplete: false. The fallback can add requests and latency. It does not apply to r/all, r/popular, existing listing cursors, or monitors with allowIncompleteMonitorFallback: false. Other monitors preserve their last complete checkpoint. A rate limit stops recovery.

For requests above 200 posts, incomplete subreddit app feeds can follow more pages, up to a maximum of 50. Larger requests take longer and may stop before reaching the requested count if a page limit, deadline, or rate limit is reached. Check OUTPUT for the run's status; these feeds remain incomplete even when they return the requested count.

For a one-off export of one named subreddit, set captureResumeToken: true and sort to "new" or "rising" to use the incomplete app feed with continuation support. Keep comments and monitoring off. If the run reaches its result or page limit, or an interruption occurs, the target in OUTPUT.targets may contain a resumeToken when a resumable position is known and prior rows are confirmed saved. To continue, run the same subreddit, sort, and filters with that value in resumeToken. A failed run can still have an OUTPUT record. A token is not guaranteed for every interruption or spending limit. If a post cannot be verified, the export can stop at that post and retries can stop there again. Reddit cursors can expire, the feed can change, and repeated or missing posts are possible; deduplicate across runs by post id. Results remain partial.

To use the incomplete app feed directly for New or Rising listings, including r/all and r/popular, set preferIncompleteSubreddit: true. It may miss or reorder posts, and its rows are marked discoveryComplete: false. All and Popular results use discoverySource: "graphql-reddit-feed-partial". For monitoring, alerts and the last complete checkpoint follow the incomplete-monitor behavior above, and this option cannot be combined with allowIncompleteMonitorFallback: false. The option is off by default, does not affect other sorts or keyword searches, and cannot use a listing URL's existing cursor. A rate limit does not trigger another source.

To use a public web feed directly for New or Rising subreddit listings, set preferWebSubreddit: true. This source may miss or reorder posts; its results are checked against current post data and marked discoverySource: "web-subreddit-partial" and discoveryComplete: false. It does not cover keyword searches or other sorts. For monitoring, the last complete checkpoint is preserved, and this option cannot be combined with allowIncompleteMonitorFallback: false. Do not combine this option with preferIncompleteSubreddit or a listing URL's existing cursor. A rate limit does not trigger another source.

If a Rising listing is refused, a one-off run may use Reddit's app Rising feed first. Those results can miss or reorder posts and carry discoveryComplete: false with discoverySource: "graphql-subreddit-partial" or "graphql-reddit-feed-partial". If that source fails without a rate limit, the Actor may return Hot posts instead, marked hot-listing-partial; Hot uses a different ranking. Existing listing cursors are not translated. Persistent monitoring preserves the last complete checkpoint, and skips these alternatives when allowIncompleteMonitorFallback is false. A rate limit stops the request.

Post and comment extraction

{
"postUrls": [
"https://www.reddit.com/r/programming/comments/POST_ID/example/"
],
"includeComments": true,
"maxCommentsPerPost": 50,
"maxCommentDepth": 3
}

Output fields

Every post row includes:

  • identity: id, title, url, permalink, sourceQuery
  • author/community: author, subreddit, flair
  • content: selftext, post_hint, domain, mediaUrl, thumbnail, gallery_images
  • engagement: score, upvoteRatio, numComments, gildingCount
  • flags: isNSFW, is_spoiler, is_stickied, is_self, is_video, is_crosspost, is_locked, is_archived
  • timestamps: created, scrapedAt
  • monitoring: changeType, firstSeenAt when monitorMode is new-posts
  • partial fallback: discoverySource, discoveryComplete when an incomplete discovery source is used
  • keyword search: detailLevel: "search_result". Reddit's search results show each post's title, author, community, score, comment count and time, so these rows leave selftext, upvoteRatio, flair and the link destination empty, and url is the post's own Reddit link. Subreddit listings, user pages and exact post URLs include the full fields.
  • optional comments: topComments[], plus commentsSource, commentDepthFilterApplied and commentTreeComplete when comments are requested. commentTreeComplete is false if the tree is limited, incomplete or cannot be verified. Feed comments include id, author, body, and permalink; fields the feed does not provide are null or empty.

Example result

{
"id": "1uxtv30",
"title": "New Python type checker",
"author": "TheSeriousTrader",
"subreddit": "Python",
"url": "https://www.reddit.com/r/Python/comments/1uxtv30/new_python_type_checker/",
"permalink": "https://www.reddit.com/r/Python/comments/1uxtv30/new_python_type_checker/",
"selftext": "Was checking out some Python type checkers...",
"score": 42,
"upvoteRatio": 0.88,
"numComments": 16,
"created": "2026-07-16T05:39:00+00:00",
"flair": "Discussion",
"is_self": true,
"topComments": []
}

What you're charged for

A run has a start charge, and each unique post written to the dataset has a result charge. Comments included in a post do not add a result charge. An empty or failed run can still incur the start charge. See the Pricing tab on this Actor's Store page for current rates and details.

Reliability and responsible use

  • For one-off runs, check the run's OUTPUT key-value record for resultStatus (complete, partial, failed, or limited) and per-target status and resultCount. A run can save useful rows even when another target fails. An unavailable target could not be accessed; a not_processed target was not attempted. When Reddit rate-limits a target, its entry includes failureReason: "rate_limited"; a rate-limited session can instead report that reason at the top level before targets are attempted. If the run approaches its time limit while retrieving a page, verified posts may be saved as partial and the target can report failureReason: "deadline". An unverifiable creation time with newerThan can report failureReason: "timestamp_unavailable". complete means the Actor finished the requested target window; it does not guarantee Reddit returned every matching post. Some failures before target processing may not have this summary.
  • A valid empty response from an incomplete source can finish the run with resultStatus: "partial", zero rows, and a target incompleteReason: "source_may_omit_results". This does not establish that no matching posts exist. Actual rate limits, invalid responses and deadline failures are not counted as valid empty responses.
  • Across all inputs, each run supports up to 50 listing targets and 100 exact post URLs. Extra targets in a one-off run are listed as not_processed in OUTPUT; split them into another run. A monitor exceeding either combined limit stops before updating its state; split the watch into smaller monitors.
  • If the comment-enabled post cap or spending limit reduces a one-off listing's requested maximum, its OUTPUT entry includes requestedMaxResults, appliedMaxResults, and limitReason. When the lower limit is reached and more posts may be available, the target is marked partial.
  • A Reddit URL is sent to the right kind of target whichever input holds it, and Reddit app share links are followed to their post. A URL that cannot be used is skipped and listed as unsupported in OUTPUT while the valid targets continue; the run fails only when no input can be used. A non-Reddit URL in queries or postUrls is rejected when the run starts, before any charge.
  • The default run time limit is 20 minutes. Large requests may still return fewer posts when Reddit limits access, the time limit is reached, or fewer matches are available. Check the OUTPUT record for the run's status.
  • If comment retrieval reaches the run's cleanup reserve, the Actor keeps the verified post and marks its comments unavailable and incomplete. Other interruptions can still prevent output from being saved.
  • The Actor collects public Reddit content only. Private, banned, quarantined, removed, or login-only content is unavailable.
  • Requests are globally rate-limited with bounded retries for 429, authorization refreshes, timeouts, and transient network failures.
  • A persistent monitor raises a new-post alert only for posts created since its previous check, with a six-hour allowance. An older post that appears for the first time is recorded without an alert and counted as olderPostsNotAlerted in OUTPUT.
  • Persistent monitors keep at most 50,000 post identities. The oldest identities can eventually age out of extremely high-volume watches.
  • Monitoring visits every configured target but buffers at most 2,000 current post observations before diffing. With large watchlists, the Actor lowers maxResults evenly per listing; split broader cohorts into separate Tasks.
  • A target that fails keeps its last checkpoint, so a failed page or deadline cannot corrupt the baseline. With allowIncompleteMonitorFallback: false, state updates only after every configured target completes.
  • Reddit scores and comment counts can change between requests and may be hidden for very new posts.
  • Comment-enabled listing runs are capped at 100 posts total across all queries; exact postUrls reuse their detail response and remain separate.
  • The Actor first tries Reddit's current comment tree. commentsSource: "graphql-comment-tree" rows include available comment scores, parent IDs and depths. It can expand up to three collapsed branches per post and 30 per run, subject to the run deadline. commentTreeComplete is false when comments were excluded by the requested depth or count, or when the initial response reports more or collapsed comments, even if some branches were expanded. If the app tree fails and the direct web page is blocked or temporarily unavailable, it may try a public web page through a proxy connection; this can omit or reorder comments. When at least five requested comments are still missing, the web fallback can follow up to three top-level continuation pages per post, sharing the 30-request per-run continuation limit. Other sources cannot establish a complete tree, so also report false. Web and feed fallbacks omit blank text and removal placeholders; this can also omit media-only comments. Web comments have unknown award and controversiality fields. When a public feed is used, comments have unknown scores, parent IDs and reply depths, and commentDepthFilterApplied is false; maxCommentDepth cannot be enforced. Other commentsSource values are public-feed, comment-tree, and unavailable.
  • Reddit has announced that RSS feed support ends on November 13, 2026. Search, newest-listing and comment feed fallbacks may stop working after that date.
  • Search relevance and geographic availability are controlled by Reddit.
  • If Reddit blocks the regular search endpoint, one-off keyword searches and monitors may use Reddit's app search before the search feed. Those rows carry discoverySource: "graphql-search-partial" and discoveryComplete: false: results can omit posts, including adult content, or differ from the normal search in order. Check the run's OUTPUT record for a partial result status. If app search cannot handle the input, the Actor may try the search feed. A rate limit stops the search rather than triggering a source switch. Persistent monitors skip app search when allowIncompleteMonitorFallback is false, and otherwise preserve their last complete checkpoint. It does not substitute for newest-first subreddit listings.
  • If Reddit asks the Actor to pause partway through a search page, a one-off run can return the posts already verified. These rows have discoveryComplete: false; comments may be unavailable. Persistent monitors deliver those verified posts and keep their last complete checkpoint.
  • Runs may pause once and retry when Reddit supplies a reset time: up to 6 seconds for fewer than five potential posts, 35 seconds for five to nine, or one minute for ten or more. Runs can still return partial results or fail if the limit continues.

Workflows and guides

Pairs well with Twitter/X Scraper, Google News Scraper, and YouTube Scraper for cross-channel listening.

Input parameters

ParameterRequiredDescription
queriesNoPlain text searches all Reddit. Use r/python for a subreddit listing or r/python: asyncio for search within one subreddit. r/python+golang runs each community separately, and they share maxResults.
startUrlsNoExisting public Reddit URLs. Subreddit/search pages are paginated; post URLs are extracted directly.
postUrlsNoFetch exact public Reddit posts and, optionally, their comment threads. Accepts post links, redd.it short links, and Reddit app share links.
sortNoHow subreddit and search results are ordered.
timeFilterNoTime range for top and relevance searches.
maxResultsNoMaximum unique posts returned for each query or listing URL. Pagination is automatic in batches of up to 100. Persistent monitors distribute a 2,000-observation safety budget across listing targets.
includeCommentsNoEmbed public comments in each post row. Feed comments have limited metadata. Comment-enabled listing runs are capped at 100 posts total.
maxCommentsPerPostNoMaximum public comments embedded in each post row when comments are enabled.
maxCommentDepthNoMaximum reply depth when the full comment tree is available. The public feed cannot be filtered by depth.
minScoreNoOnly write posts at or above this visible Reddit score.
skipPinnedPostsNoExclude moderator-pinned or stickied posts from results.
newerThanNoA date, a timestamp, or an age for one-off incremental exports, for example 2026-07-01, 2026-07-01T00:00:00Z, or 7 days. Persistent monitors usually leave this empty.
monitorModeNoReturn every current post, or persist a baseline and return only posts not seen by this watch. An unchanged new-posts run writes no billable result rows.
allowIncompleteMonitorFallbackNoOn by default. Keeps a monitor running on an incomplete keyword or New, Rising, or named-subreddit Hot source when the regular source is unavailable. Alerts and the OUTPUT record identify affected runs; posts can be missed. Set to false to require complete data.
captureResumeTokenNoEnable resumable one-off New or Rising exports for one named subreddit, without comments. The feed remains incomplete.
resumeTokenNoContinue from a token returned in a previous run's OUTPUT, using the same subreddit, sort, and filters.
monitorStoreNameNoStable identity for one scheduled watch. Reuse the same name and input on every run; use a different name for each independent monitor.
allowPartialSubredditFallbackNoAllow an additional incomplete Hot-page recovery for one-off newest-first subreddit listings. Not used for monitoring or keyword search.
preferWebSubredditNoUse the incomplete web feed directly for New or Rising subreddit listings. Persistent watches cannot combine it with allowIncompleteMonitorFallback: false.
maxConcurrencyNoParallel parsing tasks for bodies/comments. Actual Reddit requests remain globally rate-limited.
requestDelaySecsNoMinimum delay between anonymous Reddit API requests. Keep at 0.65 seconds unless you need a gentler crawl.

Use cases

  • Marketers monitoring social presence and engagement
  • Researchers building social-media datasets
  • Teams tracking public figures and trends

Limitations

  • Comment-enabled listing runs are capped at 100 posts total across all queries, to respect Reddit and the run timeout; disable includeComments for larger post-only pulls.
  • Persistent monitors distribute a 2,000-observation safety budget across listing targets, so very broad watch configurations can be throttled before every target is checked.
  • Deleted, removed, or private-subreddit content disappears from results between runs, since the Actor reflects whatever Reddit currently serves publicly.
  • maxCommentsPerPost limits comment count. maxCommentDepth applies only when commentDepthFilterApplied is true.
  • Listing URLs that page backwards with before are not supported; use the URL without it.

Last verified: 2026-11-10

⌂ 换网址