# Steam Reviews Scraper – Game Reviews, Filters & Only-New Mode (`gazidev/steam-reviews-scraper`) Actor

Scrape Steam user reviews for any game by app ID, store URL or name. Filter by language, positive/negative, Steam purchase and date; get playtime, votes and helpfulness, plus a per-game summary with score, price and genres. Only-new mode for monitoring. No login.

- **URL**: https://apify.com/gazidev/steam-reviews-scraper.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Categories:** Other, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 1,000 reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Steam Reviews Scraper – Game Reviews, Filters & Only-New Mode

Scrape **Steam user reviews** for any game, DLC or software on Steam. Paste app IDs, Steam store URLs or simply game names, and get every review as clean JSON, CSV or Excel: recommendation (👍/👎), full review text, language, dates, helpful and funny votes, Steam's weighted helpfulness score, comment count, purchase flags and the reviewer's **playtime** at review time. A **summary row per game** adds the Steam review score ("Overwhelmingly Positive"), positive/negative totals, price, discount, genres and developers.

It reads Valve's public store endpoints, so it needs no login, no API key, no browser and no proxy. It costs **$0.20 per 1,000 reviews**.

### What it does

- **Any input:** app ID (`620`), store URL (`https://store.steampowered.com/app/1145360/Hades/`), community or SteamDB URL, or a game name (`Stardew Valley`, resolved via the Steam store search).
- **Steam's own filters:** language (30 Steam languages, or all), positive / negative, bought on Steam vs. keys and gifts, sort by most recent, recently updated or most helpful, `dayRange` for helpful reviews, and optional off-topic review-bomb activity.
- **Date range:** `reviewsAfter` / `reviewsBefore` (`2026-09-01` or `30 days`). Paging stops at the first review older than your range, so you do not pay for scanning old pages.
- **Full paging:** cursor paging with 100 reviews per request, duplicates removed. `maxReviewsPerApp: 0` downloads the complete review history.
- **Only-new mode** for monitoring: review IDs already delivered are remembered in a named key-value store. Scheduled runs return only reviews posted since the last run.
- **Per-game summary row:** review score, totals for your language/purchase filters, % positive, price and discount in your country, genres, developers, publishers, release date, Metacritic score, header image, and counts for this run (new negative reviews, languages).
- **Privacy by default:** reviewer Steam IDs, names and avatars are **not** output. Opt in to a pseudonymous hash or to the raw Steam ID if you need it.
- **Polite and robust:** honest User-Agent with a contact address, global throttling (max 2.5 review pages per second), retries with backoff on 429/5xx, per-game `error` rows instead of crashes.

### Use cases

- **Game developers and publishers:** track new negative reviews after a patch, export all reviews of your game for analysis, compare languages and regions.
- **Review monitoring:** schedule daily with `onlyNew` and send new reviews to Slack, Discord (via webhook), email or Google Sheets.
- **Market research:** compare competitors' sentiment, playtime at review, Early Access reviews and refund rates.
- **Sentiment analysis and LLM summaries:** clean review text + language + votes is ideal input for topic modelling or AI summaries ("what do players complain about?").
- **Academic research and datasets:** large, filterable review datasets with timestamps and playtime.

### Input example

```json
{
  "apps": [
    "https://store.steampowered.com/app/1145360/Hades/",
    "620",
    "Stardew Valley"
  ],
  "maxReviewsPerApp": 500,
  "sortBy": "recent",
  "languages": ["english", "german"],
  "reviewType": "negative",
  "purchaseType": "all",
  "reviewsAfter": "30 days",
  "onlyNew": false,
  "includeAppSummary": true,
  "authorIdMode": "omit"
}
```

The default input reads the 100 most recent reviews of Hades and Portal 2 in about 3 seconds.

| Field | Default | Notes |
|---|---|---|
| `apps` | 2 samples | App IDs, store/community/SteamDB URLs or game names |
| `maxReviewsPerApp` | 100 | Per game and language, 0 = all |
| `maxItems` | 0 | Total cap across games, 0 = no limit |
| `sortBy` | `recent` | `recent`, `updated`, `all` (most helpful) |
| `languages` | `all` | Steam language names; ISO codes (`de`, `pt-br`) also work |
| `reviewType` | `all` | `positive`, `negative` |
| `purchaseType` | `all` | `steam`, `non_steam_purchase` |
| `reviewsAfter` / `reviewsBefore` | – | `2026-09-01` or `30 days` |
| `dayRange` | 0 | Only with `sortBy: all`, max 365 |
| `includeOffTopicActivity` | false | Include reviews from detected review bombs |
| `onlyNew` / `stateKey` | false / – | Monitoring memory |
| `includeAppSummary` | true | One summary row per game (charged once per game) |
| `country` | `us` | Price currency and store search country |
| `authorIdMode` | `omit` | `omit`, `hashed`, `raw` |

### Output example

One row per review. The **Reviews**, **Game summaries** and **Errors** views are in the Output tab.

```json
{
  "type": "review",
  "appId": "1145360",
  "appName": "Hades",
  "recommendationId": "236570899",
  "votedUp": true,
  "recommendation": "Recommended",
  "review": "i like it",
  "language": "english",
  "createdAt": "2026-09-30T19:55:18Z",
  "updatedAt": "2026-09-30T19:55:18Z",
  "votesUp": 0,
  "votesFunny": 0,
  "weightedVoteScore": 0.5,
  "commentCount": 0,
  "steamPurchase": true,
  "receivedForFree": false,
  "refunded": false,
  "writtenDuringEarlyAccess": false,
  "primarilySteamDeck": false,
  "authorPlaytimeAtReviewHours": 16.3,
  "authorPlaytimeForeverHours": 26.0,
  "authorPlaytimeLastTwoWeeksMinutes": 1559,
  "authorLastPlayed": "2026-10-02T01:45:10Z",
  "authorNumGamesOwned": 0,
  "authorNumReviews": 3,
  "developerResponse": null,
  "appReviewsUrl": "https://steamcommunity.com/app/1145360/reviews/",
  "fetchedAt": "2026-10-03T09:40:34Z"
}
```

Also included: `timestampCreated` / `timestampUpdated` (Unix), playtime in minutes (`authorPlaytimeForeverMinutes`, `authorPlaytimeAtReviewMinutes`) and `developerRespondedAt`.

Summary row per game:

```json
{
  "type": "app-summary",
  "appId": "1145360",
  "appName": "Hades",
  "developers": ["Supergiant Games"],
  "genres": ["Action", "Indie", "RPG"],
  "releaseDate": "Sep 17, 2020",
  "priceFormatted": "$6.24",
  "discountPercent": 75,
  "metacriticScore": 93,
  "reviewScoreDesc": "Overwhelmingly Positive",
  "totalPositive": 151727,
  "totalNegative": 2485,
  "totalReviews": 154212,
  "positivePercent": 98.39,
  "totalsFilter": {"languages": ["english"], "purchaseType": "all"},
  "reviewsDelivered": 2,
  "deliveredNegative": 0,
  "storeUrl": "https://store.steampowered.com/app/1145360/"
}
```

- Errors: rows with `"type": "error"`, `input`, `appId`, `error`. Not charged.
- The key-value store record `OUTPUT` holds the run summary: per game reviews scanned / saved / already seen / outside the date range.

### Pricing

Pay per event. You pay only for rows saved.

| Event | Price |
|---|---|
| Review | **$0.0002** ($0.20 / 1,000) |
| Game summary (optional, once per game per run) | $0.002 |
| Actor start | $0.00005 |

Compared with other Store Actors (public Store prices, 2026-10-01):

| Actor | Price per 1,000 reviews |
|---|---|
| **Steam Reviews Scraper (this Actor)** | **$0.20** |
| automation-lab Steam reviews | $0.57 |
| memo23/steam-reviews-scraper | $1.00 |

Set **Maximum cost per run** in the run options to cap spending. The Actor stops cleanly when the limit is reached, and in only-new mode the reviews it could not save are returned on the next run.

### FAQ

**How many reviews can I get?**
All of them: Steam's cursor paging goes through the whole history (popular games have several hundred thousand reviews). Set `maxReviewsPerApp: 0` and a maximum cost per run. Throughput is about 250 reviews per second at most, because requests are throttled politely.

**Why are the totals in the summary different from the store page?**
`totalPositive` / `totalNegative` / `totalReviews` are Steam's numbers for your language and purchase-type filters (see `totalsFilter`). The store page usually shows English or Steam-purchase-only numbers. Choose `languages: ["all"]` and `purchaseType: "all"` for the widest totals.

**How does only-new mode work?**
Review IDs are stored per game and language in the named key-value store `steam-reviews-scraper-state` (key derived from your games and filters, or your `stateKey`). With `sortBy: recent` paging stops as soon as it reaches reviews delivered before, so scheduled runs are fast and cheap. With `sortBy: updated`, an edited review is returned again.

**Why are reviewer IDs not included?**
A Steam ID identifies a person, and most analyses do not need it. `authorIdMode: "hashed"` adds `authorIdHash`, a keyed HMAC-SHA256 that lets you count repeat reviewers without storing IDs (the secret salt stays in your Apify account). `authorIdMode: "raw"` adds `authorSteamId`, `authorProfileUrl` and `reviewUrl`; use it only if you have a lawful basis under GDPR or similar laws. Persona names and avatars are never output.

**Do I need a proxy or a Steam account?**
No. The Actor uses public JSON endpoints without login. If Steam ever answers with HTTP 429, the Actor waits and slows down automatically.

**Is it legal? Is it allowed by Steam?**
The Actor reads only public data from endpoints Valve documents for third parties ([User Reviews – Get List](https://partner.steamgames.com/doc/store/getreviews)). Valve's [Steam Web API Terms of Use](https://steamcommunity.com/dev/apiterms) do not prohibit commercial use; they cap use at 100,000 calls per day and forbid implying that Valve endorses you. This Actor is not affiliated with or endorsed by Valve; Steam is a trademark of Valve Corporation. It uses no Steam account. Review texts are written by Steam users and belong to them: quote responsibly, and check the [Steam Subscriber Agreement](https://store.steampowered.com/subscriber_agreement/) and your local law for your use case.

**What if Valve changes the endpoint?**
Valve marks the `appreviews` endpoint as superseded by `IUserReviewsService/GetAppReviews`. It still works, and the Actor will be switched over if it is ever turned off; the output format stays the same.

### Use with AI agents / Apify MCP

- **Apify MCP server:** add `gazidev/steam-reviews-scraper` to your MCP client (Claude Desktop, Cursor, VS Code) via `https://mcp.apify.com?actors=gazidev/steam-reviews-scraper`. An agent can call it with `{"apps":["Hollow Knight"],"reviewType":"negative","reviewsAfter":"30 days"}` and summarise what players complain about.
- **API:** `POST https://api.apify.com/v2/acts/gazidev~steam-reviews-scraper/run-sync-get-dataset-items?token=...` with the input JSON returns the reviews directly; works as a tool for LangChain, LlamaIndex or n8n.
- **Scheduled monitoring:** create a Task with `onlyNew: true` and `sortBy: recent`, schedule it daily, and connect the Slack, Google Sheets or webhook integration.

### More review and app data

- [App Store Reviews Scraper & Monitor](https://apify.com/gazidev/app-store-review-monitor): Apple App Store reviews across all countries, only-new alerts.
- [App Store Scraper](https://apify.com/gazidev/app-store-scraper): app details and search results from the Apple App Store.

# Actor input Schema

## `apps` (type: `array`):

One per line: a numeric app ID (`620`), a Steam store or community URL (`https://store.steampowered.com/app/1145360/Hades/`, `steamcommunity.com/app/570/reviews`) or a game name (`Stardew Valley`, resolved with the Steam store search; the best match is used).

## `maxReviewsPerApp` (type: `integer`):

Per game and language. 0 = all reviews (popular games have hundreds of thousands; set a maximum cost per run). You pay only for reviews saved.

## `maxItems` (type: `integer`):

Stop after this many reviews across all games (0 = no limit).

## `sortBy` (type: `string`):

Steam's `filter` parameter. Use **Most recent** for monitoring and date ranges. **Recently updated** also returns edited reviews again in only-new mode.

## `languages` (type: `array`):

Steam review languages (`english`, `german`, `schinese`, `brazilian` …). Leave `all` for every language. Several languages are read one after another; ISO codes like `en`, `de`, `pt-br` also work.

## `reviewType` (type: `string`):

Only recommended or only not-recommended reviews.

## `purchaseType` (type: `string`):

Steam's `purchase_type` filter.

## `reviewsAfter` (type: `string`):

Keep reviews created on or after this date (updated date when sorting by Recently updated). Absolute (`2026-09-01`) or relative (`30 days`). Paging stops at the first older review.

## `reviewsBefore` (type: `string`):

Keep reviews created before this date.

## `dayRange` (type: `integer`):

Steam's `day_range`: with sort *Most helpful*, only reviews from the last N days (max 365, 0 = off).

## `includeOffTopicActivity` (type: `boolean`):

Steam hides reviews posted during detected off-topic review bombs by default. Turn on to include them.

## `onlyNew` (type: `boolean`):

Remembers the review IDs already delivered (named key-value store `steam-reviews-scraper-state`) and returns only reviews that appeared since the previous run. Schedule it hourly or daily for alerts to Slack, email or Sheets. The first run returns the latest reviews up to the limits.

## `stateKey` (type: `string`):

Optional. By default the memory is tied to this list of games and filters. Set a name to keep the memory when you edit the input.

## `includeAppSummary` (type: `boolean`):

One `app-summary` row per game: Steam review score (e.g. Very Positive), positive/negative totals for your filters, % positive, price and discount, genres, developers, release date, Metacritic, plus counts for this run. Charged once per game.

## `country` (type: `string`):

2-letter country code for the price in the summary row and for name search (`us`, `gb`, `de`, `tr`).

## `authorIdMode` (type: `string`):

Steam IDs identify people, so they are left out by default. **Hashed** adds `authorIdHash` (HMAC-SHA256 with a secret salt kept in your account) to count repeat reviewers without storing IDs. **Raw** adds `authorSteamId`, `authorProfileUrl` and `reviewUrl`; only use it if you have a lawful basis (GDPR) to process them. Playtime and review counts are always included.

## `hashSalt` (type: `string`):

Only for the hashed mode: your own secret salt, e.g. to get the same hashes in several Apify accounts.

## `maxConcurrency` (type: `integer`):

Requests are throttled globally (about 2.5 review pages per second, appdetails every 1.6 s) whatever this value is.

## `requestTimeoutSecs` (type: `integer`):

Failed requests (429, 5xx, timeouts) are retried up to 4 times with backoff.

## `proxyConfiguration` (type: `object`):

Usually not needed: these public JSON endpoints are plain HTTP and do not need residential IPs. Add a proxy only if your runs get HTTP 429/403.

## Actor input object example

```json
{
  "apps": [
    "https://store.steampowered.com/app/1145360/Hades/",
    "620"
  ],
  "maxReviewsPerApp": 50,
  "maxItems": 0,
  "sortBy": "recent",
  "languages": [
    "all"
  ],
  "reviewType": "all",
  "purchaseType": "all",
  "dayRange": 0,
  "includeOffTopicActivity": false,
  "onlyNew": false,
  "includeAppSummary": true,
  "country": "us",
  "authorIdMode": "omit",
  "maxConcurrency": 2,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `reviews` (type: `string`):

No description

## `summaries` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "apps": [
        "https://store.steampowered.com/app/1145360/Hades/",
        "620"
    ],
    "maxReviewsPerApp": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/steam-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "apps": [
        "https://store.steampowered.com/app/1145360/Hades/",
        "620",
    ],
    "maxReviewsPerApp": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("gazidev/steam-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "apps": [
    "https://store.steampowered.com/app/1145360/Hades/",
    "620"
  ],
  "maxReviewsPerApp": 50
}' |
apify call gazidev/steam-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/steam-reviews-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/wUcTeOwb2l85XD6Tn/builds/Siu7ZxDelxy8Jcj8U/openapi.json
