Reddit Historical Archive Scraper for Posts and Comments avatar

Reddit Historical Archive Scraper for Posts and Comments

Pricing

from $0.01 / 1,000 archived contents

Go to Apify Store
Reddit Historical Archive Scraper for Posts and Comments

Reddit Historical Archive Scraper for Posts and Comments

Collect public Reddit posts and comments from historical date ranges. Search by subreddit, author, post ID, or Reddit URL, then filter by type, phrase, score, and order. Get text, links, dates, engagement, and archive details when available.

Pricing

from $0.01 / 1,000 archived contents

Rating

0.0

(0)

Developer

Maxime Dupré

Maxime Dupré

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

🗃️ Find Reddit's public history

Researchers, journalists, analysts, and developers can use Reddit Historical Archive Scraper to find public Reddit posts and comments from past date ranges. It saves structured rows with text, authors, subreddits, dates, scores, links, and archive details when the source provides them. Use those rows to study older discussions, compare communities over time, or prepare text for search and retrieval.

Try these workflows

📚 Archived Reddit posts and comments

Each saved row is one public archived post or comment. The recordType field shows which shape the row uses. Posts can include title, body text, author, subreddit, timestamps, URLs, scores, flair, media, moderation state, and archive provenance. Comments can include text, author, subreddit, timestamps, URL, score, flair, parent and related-post links, moderation state, and archive provenance. Optional fields appear when the archive supplies them.

Useful facts

  • The stable Reddit id helps you join a post or comment with other data.
  • The public url gives you a source page to review.
  • provenance can include the archive name and known time and volume coverage.
  • text is normalized for embedding or retrieval when post body text is available.

▶️ Search the archive in a few steps

Run steps

  1. Choose posts, comments, or both as the result type.
  2. Choose one discovery method: subreddit, author, post, or url.
  3. Enter one or more values for that target.
  4. Add date bounds, a search phrase, a minimum score, or a result order when needed.
  5. Use the two limits for a smaller first run, then start the Actor and open the dataset.

A narrow date range and a small limit leave less data to review. The form uses one discovery method per run. Use separate runs for different search setups, while lists of values of the same kind remain supported.

⚙️ Input

Input fields

FieldTypeWhat it does
resultTypestringChooses posts, comments, or both.
discoveryMethodstringChooses subreddit, author, post, or url as the target kind.
subredditNamesarray of stringsAdds one or more subreddit names without the r/ prefix.
authorNamesarray of stringsAdds one or more Reddit usernames without the u/ prefix. The Actor searches posts, comments, or both for each author.
postIdsarray of stringsAdds one or more Reddit post IDs. The Actor retrieves matching archived posts or their comments in the date range.
redditUrlsarray of objectsAdds one or more public Reddit URL objects for archived targets.
redditUrls[].urlstringA full public Reddit URL that starts with https://.
startDatestringAn optional lower UTC creation-date bound. Records created before it are skipped. Use YYYY-MM-DD.
endDatestringAn optional upper UTC creation-date bound. Records created after it are skipped. Use YYYY-MM-DD.
searchPhrasestringAn optional phrase checked in post titles and body text or in comment body text. With both, it is checked in both types.
minScoreintegerAn optional minimum engagement score. Records with a lower score are skipped.
sortOrderstringChooses newest or oldest creation order.
maxCommentsPerPostintegerLimits comments for post ID or Reddit URL targets when comments are selected. Leave it empty to return all available comments until the source is exhausted.
maxItemsintegerLimits returned posts or comments in the run. Leave it empty to return all available records until the source is exhausted. The schema has no fixed upper bound.

The required fields are resultType and discoveryMethod. Dates use UTC.

Input example

This is the public input from a successful run.

{
"resultType": "posts",
"discoveryMethod": "subreddit",
"subredditNames": [
"AskReddit"
],
"sortOrder": "newest",
"maxItems": 100
}

🧾 Output

The Output panel links to the dataset. Each dataset item uses one of the two shapes below, and recordType tells you which one it is. Optional fields are present when the archive supplies them.

Post rows

FieldTypeWhat it does
recordTypestringIdentifies this shape as post.
idstringGives the stable Reddit ID for joining this post with other data.
titlestringGives the post title.
textstringGives normalized post body text when body text is available.
authorobjectGroups public author details when available.
author.namestringGives the public Reddit username of the author.
subredditstringGives the Reddit community where the post was published.
createdAtstringGives the UTC creation time.
editedAtstringGives the UTC edit time when the archive supplies it.
urlstringGives the public Reddit URL for the post.
scoreintegerGives the engagement score recorded by the archive.
upvoteRationumberGives the archive's upvote ratio from 0 to 1.
commentCountintegerGives the number of comments recorded for the post.
flairstringGives the post flair when available.
mediaarray of objectsLists media attached to the post when available.
media[].typestringGives the source media type for one media item.
media[].urlstringGives the public URL for one media item.
moderationobjectGroups moderation states recorded for the post.
moderation.removedbooleanSays whether the archive marks the post as removed.
moderation.lockedbooleanSays whether the archive marks the post as locked.
moderation.archivedbooleanSays whether the archive marks the post as archived on Reddit.
moderation.stickiedbooleanSays whether the archive marks the post as stickied.
provenanceobjectGroups the archive source and coverage facts for the post.
provenance.archiveNamestringGives the name of the public archive that supplied the post.
provenance.coverageobjectGroups known time and volume coverage for the target.
provenance.coverage.earliestCreatedAtstringGives the earliest creation time covered for the target.
provenance.coverage.latestCreatedAtstringGives the latest creation time covered for the target.
provenance.coverage.availableRecordCountintegerGives the number of records the archive reports for the target.

Genuine post row

{
"recordType": "post",
"id": "kmtys6",
"title": "What made the Cambodian Genocide a genocide?",
"subreddit": "AskHistorians",
"createdAt": "2020-12-30T03:28:06.000Z",
"url": "https://www.reddit.com/r/AskHistorians/comments/kmtys6/what_made_the_cambodian_genocide_a_genocide/",
"provenance": {
"archiveName": "arctic-shift.photon-reddit.com",
"coverage": {
"earliestCreatedAt": "2020-12-30T03:28:06.000Z",
"latestCreatedAt": "2020-12-30T03:28:06.000Z",
"availableRecordCount": 1
}
},
"text": "I understand why a lot of other genocides qualify as genocides since they are one group trying to wipe out another. But the Cambodian Genocide seems different to me in that that doesn’t seem to be the case. Based on what I have read about it, it seems like what happened in Cambodia was a mass killing by the government of its own people. That’s certainly horrible but that just sounds like mass murder rather than genocide. Was there an effort to wipe out non-Cambodians at the time that I am not aware of?",
"author": {
"name": "historydude420"
},
"score": 3,
"upvoteRatio": 0.6700000166893005,
"commentCount": 8,
"moderation": {
"locked": false,
"archived": false,
"stickied": false
}
}

Comment rows

FieldTypeWhat it does
recordTypestringIdentifies this shape as comment.
idstringGives the stable Reddit ID for joining this comment with other data.
textstringGives normalized comment body text.
authorobjectGroups public author details when available.
author.namestringGives the public Reddit username of the author.
subredditstringGives the Reddit community where the comment was posted.
createdAtstringGives the UTC creation time.
editedAtstringGives the UTC edit time when the archive supplies it.
urlstringGives the public Reddit URL for the comment.
scoreintegerGives the engagement score recorded by the archive.
flairstringGives the comment flair when available.
parentobjectGroups the parent post or comment when the archive supplies the relationship.
parent.idstringGives the stable ID of the parent item.
parent.typestringIdentifies the parent as post or comment.
postobjectGroups related post details when the archive supplies them.
post.idstringGives the stable ID of the related post.
post.titlestringGives the title of the related post when available.
post.urlstringGives the public URL of the related post when available.
moderationobjectGroups moderation states recorded for the comment.
moderation.lockedbooleanSays whether the archive marks the comment as locked.
moderation.archivedbooleanSays whether the archive marks the comment as archived on Reddit.
moderation.stickiedbooleanSays whether the archive marks the comment as stickied.
provenanceobjectGroups the archive source and coverage facts for the comment.
provenance.archiveNamestringGives the name of the public archive that supplied the comment.
provenance.coverageobjectGroups known time and volume coverage for the target.
provenance.coverage.earliestCreatedAtstringGives the earliest creation time covered for the target.
provenance.coverage.latestCreatedAtstringGives the latest creation time covered for the target.
provenance.coverage.availableRecordCountintegerGives the number of records the archive reports for the target.

Genuine comment row

{
"recordType": "comment",
"id": "ghh2v1p",
"text": "Happy to write up an answer to this, but in the meantime you could look at this answer [here](https://www.reddit.com/r/AskHistorians/comments/8dgspn/were_the_crimes_of_the_khmer_rouge_a_unique_form/) and [here](https://www.reddit.com/r/AskHistorians/comments/9506jd/how_controverse_is_the_term_genocide_among/) or for an answer I made for my youtube channel addressing this question [here](https://youtu.be/D7JkO0ZmQHk)",
"subreddit": "AskHistorians",
"createdAt": "2020-12-30T05:49:01.000Z",
"url": "https://www.reddit.com/r/AskHistorians/comments/kmtys6/what_made_the_cambodian_genocide_a_genocide/ghh2v1p/",
"provenance": {
"archiveName": "arctic-shift.photon-reddit.com",
"coverage": {
"earliestCreatedAt": "2020-12-30T03:28:06.000Z",
"latestCreatedAt": "2020-12-31T21:41:27.000Z",
"availableRecordCount": 5
}
},
"author": {
"name": "ShadowsofUtopia"
},
"editedAt": "2021-01-01T00:48:27.000Z",
"score": 5,
"flair": "Cambodian History | The Khmer Rouge",
"parent": {
"id": "kmtys6",
"type": "post"
},
"post": {
"id": "kmtys6",
"title": "What made the Cambodian Genocide a genocide?",
"url": "https://www.reddit.com/r/AskHistorians/comments/kmtys6/what_made_the_cambodian_genocide_a_genocide/"
},
"moderation": {
"locked": false,
"stickied": false
}
}

💳 Pricing

How charging works

Pricing uses one event for each public archived Reddit post or comment saved to the dataset. A run with no saved post or comment does not create this result event. The current price is shown in the Pricing tab.

Use maxItems to bound post and comment rows. For post ID or Reddit URL runs with comments, maxCommentsPerPost bounds the comments. Leave either limit empty to return all available results until the source is exhausted.

🔌 Integrations

Run the Actor in Apify Console or through the Apify API. Use the dataset link to download the rows or pass them to another step in your workflow. Apify schedules and webhooks can help with repeat runs and run notifications.

❓ FAQ

Can I choose posts, comments, or both?

Yes. Set resultType to posts, comments, or both. Every row says post or comment in recordType.

Can I search inside comment text?

Yes. Set searchPhrase. It checks post titles and body text, and it checks comment body text when comments are in scope.

How do the date fields work?

startDate and endDate use UTC and YYYY-MM-DD. Records before the start date or after the end date are skipped.

Can one run use several target kinds?

Choose one discoveryMethod per run: subreddit, author, post, or url. You can submit several values of that kind. Use separate runs for different search setups.

Can I get every comment in a thread?

A post ID or Reddit URL can be used for a run where comments are selected. The archive may not contain every comment or ancestor, so the Actor does not promise a complete nested tree.

Why is a field missing?

Many fields are optional. A value is included when the archive supplies it, and missing source facts are not filled in.

Does it read live or private Reddit content?

No. It retrieves public archived content. It is not a live feed, cannot access private communities, and cannot restore content absent from the archive, including deleted or removed records.

Do I need a Reddit login or API key?

No. The Actor retrieves public archive content without a Reddit login, OAuth or API key, or a customer-supplied source credential.

What happens when I leave a limit empty?

maxItems returns all available posts or comments until the source is exhausted. maxCommentsPerPost does the same for available comments under a post target. Use a limit when you want less data to review.

How can I keep a first run easy to review?

Use one target, a narrow date range, and a small maxItems value. For a post target with comments, set maxCommentsPerPost too.

📝 Changelog

0.0: Initial release

🆘 Support

For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡

Made with ❤️ by Maxime Dupré