Reddit Posts & Threads by Date Range | Comments avatar

Reddit Posts & Threads by Date Range | Comments

Pricing

from $0.60 / 1,000 results

Go to Apify Store
Reddit Posts & Threads by Date Range | Comments

Reddit Posts & Threads by Date Range | Comments

2026-10-12 test, 20 matched posts: a 22-day-old archive differed on 9 scores, 5 comment counts. Comments USD 0.00015 each (FREE). Live Reddit posts and threads by UTC date range.

Pricing

from $0.60 / 1,000 results

Rating

0.0

(0)

Developer

Eli J

Eli J

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Export Reddit posts and threads from an exact UTC date range, including historical windows beyond Reddit's live listing horizon. Supply subreddit names and two dates to receive current live posts, optionally bundled with their comment trees. A separate frozen ID dataset lets you repeat the same candidate selection later.

Try a subreddit date range

The form prefill is an example, not an API default or a row-count guarantee.

{"subreddits": ["selfhosted"], "startDate": "2026-09-20T01:27:35Z", "endDate": "2026-09-20", "maxPosts": 1, "maxCommentsPerPost": 0}

The form example requests one post and no comments. With includeRemoved: false, a removed post is skipped without a result charge. When Reddit blocks direct reads, a skipped historical post uses a browser read and the next available frozen candidate may be attempted within maxBrowserReads and the deadline. Direct JSON reads do not replace it. A run can still be empty. If every attempted live read fails and no rows are delivered, the run fails.

Use mode: "threads" and increase maxCommentsPerPost above zero to include comments. Browser threads contain the comments present on one page, with gaps disclosed in coverage. For a research export, increase maxPosts. When Reddit blocks direct reads, maxPosts caps delivered posts. A filtered candidate uses a browser read but not a row, and an unreadable read is not replaced. When direct JSON reads work, maxPosts caps candidates, so filtered or unreadable candidates leave fewer rows. Dates are inclusive and a plain end date includes its entire UTC day. ISO instants normalize to UTC.

When Reddit blocks direct reads, a run reads at most maxBrowserReads historical posts, oldest first. Raising maxPosts beyond that bound adds unread IDs. Continue a historical window with a later startDate; replaying the same frozen set reads the same oldest IDs again.

Across the October 12, 2026 qualification sample, about 69–73% of capped candidates were delivered with includeRemoved: false. Yield depends on each community's removal rate, so a single small window can deliver far fewer. Max-charge discovery uses the conservative 69% share when estimating how many candidates can cover affordable visible rows.

Input

FieldTypeDefaultWhat it does
subredditsarrayNo default; form prefillPublic names such as selfhosted or r/selfhosted. Names are matched without regard to case, and COVERAGE and the frozen set use lowercase; rows keep Reddit's spelling. When Reddit refuses direct requests, the subreddit page is opened with your spelling, such as LocalLLaMA.
startDatestringNo default; form prefillInclusive UTC date or ISO instant.
endDatestringNo default; form prefillInclusive UTC date or ISO instant, at or after startDate.
modestringpostsposts returns live post rows; threads returns one bundled post and comment tree per delivered post.
includeRemovedbooleanfalseInclude live removed/deleted labels. Never restores archive text.
maxPostsintegerAPI omission: 20; form prefill: 1Row cap when Reddit blocks direct reads; candidate cap when direct JSON reads work. Archive and replay candidates are oldest first; blocked historical reads stop at maxBrowserReads, leaving the rest unread. Listings arrive newest page first and deliver oldest first within each page. Zero collects nothing.
maxCommentsPerPostintegerAPI omission: 500; form prefill: 0Choose threads mode and raise this above zero to include comments, up to 5,000 per bundle. Each delivered comment is billed. Browser snapshots can expose fewer comments; coverage records the gaps.
maxBrowserReadsinteger10Shared bound of 0–10 browser pages for historical posts and comment threads; one historical page supplies its post and available comments together. Listing pages have a separate run bound of 10.
replayFrozenSetDatasetIdstringNoneREAD resource picker for a previous frozen ID dataset. Replays without discovery. Any supplied subreddit/date bounds must match its header.
proxyConfigurationobjectApify residentialOptional proxy configuration. Anonymous browserless reads use residential proxies by default.

Omitted required selection inputs, empty subreddits, and maxPosts: 0 return guidance with no result rows. Invalid selections or refused communities produce an ERRORS record with no result rows.

Output

The default dataset contains delivered result rows only. This example illustrates the posts contract; values are illustrative source values.

{
"id": "t3_aa1",
"parsedId": "aa1",
"subreddit": "selfhosted",
"created_utc": "2026-09-20T00:02:03.000Z",
"createdUtc": 1789862523,
"title": "Live source title",
"selftext": "Live source text",
"author": "source_author",
"score": 17,
"upvote_ratio": 0.91,
"num_comments": 1,
"permalink": "/r/selfhosted/comments/aa1/",
"url": "https://example.com/source",
"flair": "Source flair",
"nsfw": false,
"spoiler": true,
"removed_by_category": null,
"isRemovedOrDeleted": false,
"idSource": ["archive"],
"scrapedAt": "2026-10-12T00:00:00.000Z"
}

Score and counts are Reddit's own integers; upvote_ratio is a ratio from zero to one. createdUtc is Unix seconds and string timestamps are UTC. Source-absent values are null. idSource contains archive, listing, or both; all delivered content is live Reddit content.

Threads mode adds comments and coverage. Each comment contains its stable fullname and bare ID, parentId, postId, depth, UTC creation time, author, body and score. Coverage includes declared_comments, captured_comments, unresolved children and branches, orphan/cycle checks, the stop reason and complete. Complete means that the captured count agrees with Reddit's declared count and the collector has no unresolved continuation or linkage. It is not a promise that Reddit exposes every comment. A cap or source omission is visible in coverage.

Coverage and frozen ID replay

Run records are separate from result rows:

  • COVERAGE: one entry per subreddit and UTC day, with archive attempts, discovered counts and live-read counts.
  • SUMMARY: result/candidate/read counts, the requested maxPosts, effectiveRowCap (maxPosts lowered when your maximum cost cannot cover it), removedPosts and historical/comment removedBrowserReads, recallMode, gateway reason, degraded days, charge-limit state and browser-fallback usage. listing reports the ten-page bound, pages used, browser page reads without and with scripts (browserReads) and per-subreddit oldest/newest source timestamps and stop reason. browserThreadPages reports the selected read bound, reads used and remaining. liveRequests.threadPage403Retries counts the empty-403 retries, how many recovered, and each post ID with its outcome. coveredRange reports the oldest/newest read candidate and unread IDs; in threads mode a post read without its requested thread remains unread here. These endpoints are not a claim that every intervening post was read. estimatedChildCostCeilingUsd estimates our browser-service cost, which we bear: USD 0.226 for the ten listing pages (at most six of them read with scripts) plus USD 0.03 × maxBrowserReads. estimatedChildCostUsedUsd is USD 0.004 per listing page read without scripts, USD 0.035 per listing page read with scripts and USD 0.03 per historical or comment page used. These estimates add no buyer charge and are not a guaranteed cost cap. Hard page/read caps stop further work.
  • frozenSet: the separate dataset ID, header and candidate/read/emitted counts.
  • ERRORS: handled input, identity and source failures. Live listing, post-batch and thread read failures carry their reason; text that is not a fixed failure token is reduced to its exception class.

Archive discovery requests a candidate pool up to the larger of the effective row cap and maxBrowserReads, so a filtered historical browser candidate can be replaced. Processed listing candidates take priority in the frozen set; the oldest other candidates fill remaining pool capacity. Its candidate count can exceed the row cap. Direct JSON reads still select only the first capped candidates. The dataset contains one header and one record per selected candidate: subreddit, bare ID, creation seconds, ID source and UTC day. Its header records discoveryEndDay, effectiveCandidateCap (the requested pool size) and capSource. Replay selects from that stored set without calling the archive or walking listings. A cap larger than the stored set does not discover additional IDs; the status names the recorded cutoff day. Replay preserves candidate selection; Reddit text, scores, removal state and comments can change. Disappearing or filtered candidates can leave a replay empty, which succeeds with no result-row charges.

Blocked historical replays read the same oldest IDs up to maxBrowserReads; replay does not advance through unread IDs. Continue with a later date window to select later IDs. Recent listing rows can be delivered before their frozen set is written; a storage failure or interruption can leave delivered rows without a replayable frozen set.

Historical recall and interruptions

Historical IDs come from a community archive, whose coverage is not an independent census of every Reddit post. Archive query completion means the day was paged to an exhausted response. It does not establish that no post was missing from the archive.

Day states are complete, archive_incomplete, page_budget_exhausted, archive_deferred, archive_unavailable, or not_discovered_cap. Incomplete pages retain their IDs and attempts; budget/deadline stops keep the partial frozen set. Candidate caps explain the days not fully discovered and do not count as degraded archive recall.

The private archive gateway serializes uncached discovery and limits aggregate archive requests to at most one per second, with a daily ceiling of 5,000 and a per-primary share of at most 1,000. Every attempt, including a retry, counts. Dynamic limits slow all discovery; cache hits on complete days older than 36 hours make no archive requests. Queued work that cannot fit the discovery deadline is deferred. These controls can add waiting time.

When archive discovery is deferred or unreachable, the Actor walks live /new listings. Days beyond their roughly 1,000-post horizon become archive_unavailable; SUMMARY and the status message disclose recallMode: listing_horizon. Partial archive discovery uses archive_partial. An archive outage with no reachable listing rows succeeds empty. A login gate ends each affected read as a login_gate source error in ERRORS. A run in which every live read failed and nothing was delivered fails. Archive-lag cover also walks recent listings for windows ending within 36 hours of collection; older archive misses inside listing reach are not independently recovered.

Pricing

This Actor uses pay-per-event pricing. The Pricing tab shows the current price of each event for your discount tier.

  • Result: one delivered post row in posts mode, or one delivered thread bundle in threads mode.
  • Comment: one comment delivered inside a thread bundle. Posts mode charges no comment events.
  • Actor start: charged once per run start, by memory, as shown in the Pricing tab; it applies even when a run delivers no rows.

Discovery records, frozen IDs, unread or filtered posts, COVERAGE, SUMMARY and ERRORS are never charged. Set Maximum cost per run to bound a job: discovery and live reads stop when it binds, and in threads mode each thread's comment collection is capped before it is fetched at the number of comments your remaining maximum can pay for. API omission uses 500 comments; the form example uses zero. Raise maxCommentsPerPost, up to 5,000, when you need larger threads, and the comment charge grows with the comments delivered. A storage or charging failure ends with a distinct delivery-failure status; inspect ERRORS and any rows already delivered.

Browser fallback

Browserless anonymous reads are the primary path. A JSON 403 or 302 is not retried with another identity. A historical or comment page that Reddit refuses with an empty HTTP 403 is read once more in a new browser, which uses a new IP address, when a page read and a full call of time remain; that read counts toward maxBrowserReads. Classified blocks and refused anonymous bootstrap pages route through our private browser Actor, with no separate service charge. A redirect to a Reddit login page is never sent to the browser: the read ends as a login_gate source error. Service calls and waiting time are bounded; a service refusal is disclosed as a source error. SUMMARY counts browser routes (fallbackTriggers) and reserved service-call attempts (fallbackCalls), including failed calls. The gateway and browser service run under our scoped credentials, and we bear their usage.

Recent ranges use subreddit /new/ pages and their more-posts partials when JSON is blocked. Each page is first read without page scripts, which costs much less. If a mixed-case subreddit's page comes back without posts and names its case-correct address, that address is read without scripts once; a page that shows no posts that way is read again with scripts before anything from it is used. Each of those extra reads counts toward the ten listing pages. Each page is delivered before the next is requested. Historical IDs beyond listing reach use one HTML thread page each; threads mode reuses that page's available comments. Browser snapshots do not traverse more-reply controls and do not promise a full comment tree. At most ten listing pages and maxBrowserReads historical/comment pages run; deadlines, row caps and buyer charge limits can stop earlier. Rows already delivered survive a later refusal or bound. SUMMARY states the range actually read and the selected IDs still unread, so long windows can be partial.

HTML selftext is rendered text, and its creation timestamp can include fractional Unix seconds. upvote_ratio, flair and link url come from page attributes/text when present and remain null otherwise. NSFW, spoiler and JSON removal-category labels remain null. A missing article body gives null selftext. Reddit's [ Removed by moderator ] title with no article body is recognized as removed, whatever the author. It returns isRemovedOrDeleted: true with a null removal category. With includeRemoved: false it is skipped without a result charge, and SUMMARY counts it and its historical/comment browser read. Other posts without an article body have null isRemovedOrDeleted; includeRemoved: false cannot skip them, so they are delivered and charged. No separate media field or media download is supplied; a media post's source content-href is retained as url. These nulls and snapshot limits are also described in the output schema.

The current maximum of ten historical/comment reads limits our unbilled service costs. Raising that maximum after per-read pricing becomes effective is a future change; this build keeps the maximum at ten and adds no read charge.

A separate 600-second browser-service waiting budget and the run deadline can stop collection before all page/read allocations are used. Remaining allocations do not guarantee more pages can finish in that run.

Data sources and responsible use

Historical post IDs come from Arctic Shift, the free community Reddit archive maintained by ArthurHeitmann/arctic_shift. Post and comment content is read live from Reddit. Arctic Shift's README removal-request route explains how to request removal from its archive.

Reddit's robots policy disallows crawling, and its User Agreement prohibits scraping without prior written consent. This is a known limitation. No Arctic Shift terms page or commercial-use statement was located in the reviewed captures; its documentation asks bulk users to use monthly dumps and to respect dynamic limits. This Actor is not affiliated with Reddit or Arctic Shift.

Communities whose purpose is vulnerable people's personal disclosures are refused. The explicit refusal list is: suicidewatch, selfharm, depression, mentalhealth, anxiety, ptsd, cptsd, bipolar, bipolarreddit, schizophrenia, eatingdisorders, anorexianervosa, stopdrinking, addiction, opiatesrecovery, alcoholism, narcoticsanonymous, rape, sexualassault, domesticviolence, abusesurvivors, raisedbynarcissists, cancer, breastcancer, chronicpain, askdocs, legaladvice, legaladviceuk, assistance, homeless. Do not use other communities to target such disclosures. No login, posting or account action is performed.

Limits and help

This product collects subreddit date windows. Keyword search, user history, community metadata, media downloads, archived content copies and a dump-based independent ID index are outside its scope. Source counts can disagree with available comments and current Reddit state can differ from archived metadata. Preserve SUMMARY, COVERAGE and the frozen dataset when reporting a missing day or thread.

In one measured thread, Reddit declared seven comments and six were readable; coverage reported complete: false with no unresolved branch. The cause of such gaps is not established.

Run time

On October 12, 2026, three 20-post jobs (one subreddit, one UTC day) on build 0.1.18 took 8.8–12.8 seconds from start to finish, with a median of 11.7 seconds. On the same day and window, an archive-only Actor took 6.3–8.5 seconds. This Actor reads current Reddit content live and runs a separate archive-gateway step, both of which add time. These are measured samples, not a speed claim for the current build.