Steam Reviews Scraper | Full History, Filters, $0.50/1K
Pricing
from $0.30 / 1,000 review scrapeds
Steam Reviews Scraper | Full History, Filters, $0.50/1K
Full review history of any Steam game: positive/negative totals, review score, playtime, filters by language, date and sentiment, incremental runs. Official public data. Pay per review, no start fee.
Pricing
from $0.30 / 1,000 review scrapeds
Rating
0.0
(0)
Developer
Kesar Chen
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Security
Limited permissionsShare
Steam Reviews Scraper
Pull the full review history of any Steam game as clean JSON: every review Steam still serves, newest first, with thumbs up or down, playtime at the time of writing, helpful votes, language, refund and Early Access flags, developer replies where they exist, and the game's all-time positive and negative totals. Filter by language, sentiment, date range and playtime before anything is fetched, so you only pay for rows you will read. $0.50 per 1,000 reviews, no start fee: a 30,000-review game costs about $15 once, and a daily watch on 10 games runs about $3 a month in incremental mode.
Built on Valve's public reviews data, no login, no API key required.
Why this one
- Full history, newest first, sliceable by date.
sinceDate: "12 months"or asinceDate/untilDatepair are applied by Steam itself, so a 1-million-review game narrows down to the two weeks after a patch without reading anything else. - Steam-side filters, billed after filtering. Language, thumbs up or down, bought on Steam or activated with a key, minimum and maximum playtime, Steam Deck players, off-topic review bombs included or not. Filtered-out reviews are never fetched and never charged.
- Only new reviews on every scheduled run. Turn on
incrementaland the Actor remembers what it already returned per game; your dataset never needs deduping and you never pay twice for the same review. - A summary row per game with the Steam review score bucket, all-time positive and negative counts, the count matching your filters, price, release date, Metacritic score and a last-N-months not-recommended share with the sample size next to it.
Who uses it
- Studios and publishers watch their own and competing titles after each patch:
reviewType: "negative",sinceDate: "14 days", grouped by language. - Community and support teams pull reviews from players with real playtime (
playtimeMinHours: 20) and skip drive-by posts. - Analysts and researchers get stable IDs, ISO dates, playtime and vote counts in one fixed schema across every language.
- AI agents call it through the Apify MCP server and read the field descriptions from the dataset schema.
Speed
Measured on the Apify platform: 100 reviews per request, about 1.5 seconds a page, so 3,000 reviews in under a minute and 100,000 reviews in about 25 minutes per game. Games run in parallel, pages within a game in sequence.
Use it from Claude, Cursor, or any MCP client
Add this URL as an MCP server in your client:
https://mcp.apify.com/?tools=actors,docs,kesar_chen/steam-reviews-scraper
For Claude Desktop, put this in claude_desktop_config.json:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?tools=actors,docs,kesar_chen/steam-reviews-scraper","headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }}}}
For Claude Code, one command:
$claude mcp add --transport http apify "https://mcp.apify.com/?tools=actors,docs,kesar_chen/steam-reviews-scraper" --header "Authorization: Bearer YOUR_APIFY_TOKEN"
Then ask things like:
- "Pull the negative reviews of app 413150 from the last 3 months and group the complaints."
- "Compare the not-recommended share of these three games over the last 12 months."
- "Every morning, fetch new reviews for my game and tell me if anything mentions crashes."
Review text is user-generated content: tell your agent to treat body as data, never as instructions.
Run it in the Apify Console
- Paste app IDs, store URLs or
search:game nameinto Games. - Optionally set Only reviews since, Review type, Languages or a playtime floor, and a maximum cost per run under Run options.
- Click Start. The Reviews view holds one row per review, the Summary view one row per game. Export as JSON, CSV or Excel, or read it through the API.
Pricing
Pay per event, no subscription, no start fee.
| Event | Price |
|---|---|
| Review scraped | $0.50 per 1,000 reviews |
| Game summary (one per game, with totals and score) | $0.002 |
| Scenario | Reviews | Cost |
|---|---|---|
| Try it: one game, newest 500 | 500 | about $0.25 |
| One game, full history | 30,000 | about $15 |
| 10 games, daily incremental, ~20 new reviews each per day | ~200 a day | about $3 a month |
Apify platform usage is included. The monthly credit of Apify's free plan covers several thousand reviews. Paid Apify plans get a lower per-review price, shown on the Actor page.
Set a maximum budget per run in the Apify Console. When it is reached the run stops cleanly: reviews already written are kept and charged, nothing else is, and the summary row records how far it got. In incremental mode the saved state is only updated for games that completed, so a budget stop never loses data.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
apps | list | required | App ID (413150), store URL, or search:name |
languages | list | ["all"] | Steam language codes: english, schinese, japanese, german ... |
sort | select | recent | recent, updated, helpful, funny. recent is required for sinceDate and incremental mode |
reviewType | select | all | positive, negative |
purchaseType | select | all | steam (bought on Steam), non-steam (key activation) |
sinceDate / untilDate | text | empty | 2026-01-01 or 12 months, 30 days. Applied by Steam |
playtimeMinHours / playtimeMaxHours | integer | 0 | Playtime at the time of writing. 0 = no filter |
steamDeckOnly | boolean | false | Authors who played mostly on Steam Deck |
includeOffTopic | boolean | false | Include reviews from periods Steam flagged as review bombs |
keywords | list | [] | Keep only reviews containing one of these words |
maxReviewsPerApp | integer | 3000 | 0 = everything that matches |
summaryWindowMonths | integer | 12 | Not-recommended share window in the summary row. 0 turns it off |
incremental | boolean | false | Only new reviews on later runs, state kept per game |
stateStoreName | text | steam-reviews-state | Named key-value store for incremental state. If a store with this name was created by another Actor, the run logs a warning and uses <name>-<actor id> instead |
notifyWebhookUrl | text | empty | Slack, Discord, Feishu or any HTTPS webhook; see Alerts |
notifyMaxRating | integer | 1 | Only reviews at or below this rating are posted |
notifyMaxItems | integer | 10 | Reviews per message; the rest are counted |
notifyEvenIfEmpty | boolean | false | Post a message even when nothing matched |
includeAuthorId | boolean | false | Off by default; playtime figures are always included |
searchResultsPerKeyword | integer | 1 | Games a search:name entry expands to |
Minimal example:
{ "apps": ["413150"], "sinceDate": "12 months" }
Patch watch:
{ "apps": ["730", "1172470"], "reviewType": "negative", "sinceDate": "14 days", "languages": ["english"], "playtimeMinHours": 5 }
Output
One row per review plus one summary row per game. Use the type field or the two dataset views to tell them apart.
Review row:
{"type": "review","reviewId": "237163238","appId": 413150,"appName": "Stardew Valley","language": "english","recommended": false,"body": "Crashes on load since the last update.","createdAt": "2026-10-20T12:34:56.000Z","updatedAt": "2026-10-20T12:34:56.000Z","votesUp": 12,"votesFunny": 0,"weightedVoteScore": 0.62,"commentCount": 1,"steamPurchase": true,"receivedForFree": false,"writtenDuringEarlyAccess": false,"primarilySteamDeck": false,"refunded": false,"playtimeAtReviewMinutes": 1830,"playtimeForeverMinutes": 4200,"playtimeLastTwoWeeksMinutes": 120,"authorReviewCount": 3,"authorSteamId": null,"developerResponse": null,"isNew": true,"scrapedAt": "2026-10-25T00:00:00.000Z"}
Summary row:
{"type": "summary","appId": 413150,"appName": "Stardew Valley","appType": "game","developers": ["ConcernedApe"],"publishers": ["ConcernedApe"],"releaseDate": "Feb 26, 2016","isFree": false,"price": "$14.99","metacriticScore": 89,"reviewScore": 9,"reviewScoreDesc": "Overwhelmingly Positive","totalPositive": 1031073,"totalNegative": 15900,"totalReviews": 1046973,"totalMatching": 53808,"reviewsScraped": 3000,"coverageNote": "reached maxReviewsPerApp=3000","window": { "months": 12, "from": "2025-10-25T00:00:00.000Z", "reviews": 3000, "negative": 41, "negativeShare": 1.4, "note": "sample 3000; coverage does not reach the whole window, counts are a lower bound" },"scrapedAt": "2026-10-25T00:00:00.000Z"}
totalReviews is the all-time count; totalMatching is what matches this run's filters; reviewsScraped is what was written. negativeShare is only given when the window has at least 20 reviews. The window is always the last summaryWindowMonths, independent of sinceDate.
Limitations
- Steam has no star ratings and no review titles.
recommendedis the thumbs up or down;titleis always null and exists only so that the schema lines up with the App Store Reviews Scraper. - Developer replies are rare on Steam.
developerResponseis filled when Steam provides one and null otherwise. - Reviews from periods Steam flagged as off-topic review activity are hidden by default, matching the store page. Turn on
includeOffTopicto include them. helpfulandfunnysorts do not page through the whole history reliably; userecentfor full pulls.- Steam may cache anonymous responses for a few minutes, so a review posted seconds ago can show up on the next run.
Alerts: post new low-rated reviews to Slack, Discord or Feishu
Fill notifyWebhookUrl with a Slack incoming webhook, a Discord channel webhook, a Feishu/Lark custom bot webhook, or any HTTPS endpoint, turn on incremental, and attach a Schedule. After each game the Actor posts the reviews written in that run that are at or below notifyMaxRating (default 1, meaning not-recommended reviews only), with the star rating, date, version where known, whether the developer already replied, and a link to the store page. Nothing is posted when nothing matched, unless notifyEvenIfEmpty is on. Unknown hosts receive a JSON body with the same fields, so Make, n8n, Zapier or your own service can take it from there. There is no extra charge for notifications.
An n8n template that does the same with room for translation or routing is in the templates folder.
Scheduling and integrations
Save your input as a Task, attach a Schedule and turn on incremental. Each run then returns only new reviews, which you can push to Slack, Google Sheets, Make, Zapier, n8n or any webhook through Apify integrations.
FAQ
Is it legal to scrape Steam reviews? This Actor reads public review data that Valve exposes without login or API key, and collects no private account data; the author's Steam ID is off by default. Collecting publicly available data is generally considered legal in the US and most of the EU. How you store and use the output, and whether it fits the terms of the services involved, is your responsibility. See Is web scraping legal?
Why not use Steam's own review export? Steam gives developers a dashboard for their own games only. This Actor works for any game, which is what you need for competitor analysis and market research.
How long does a run take? About 1.5 seconds per 100 reviews per game; games run in parallel.
What happens when my budget runs out mid-run? The run stops cleanly, keeps what was written, and the summary row records how far it got.
Is this affiliated with Valve? No. This is an independent tool and is not endorsed by or affiliated with Valve Corporation.
See also
App Store Reviews Scraper and Google Play Reviews Scraper: the same schema, filters and incremental mode for iOS and Android apps, so one pipeline can watch all three stores.
Hiring Signals Monitor: job opened / closed events and a hiring summary per company from public job boards, for watching studios' teams the same way you watch their reviews.
Support
Bugs or missing fields: open an issue on the Issues tab. Reports go to a human.