# Steam Reviews Scraper (`deriverge/steam-reviews-scraper`) Actor

User reviews of any Steam game with full text, verdict, helpful votes, dates, purchase and Steam Deck flags and the reviewer's playtime. Filter by language, verdict, purchase type and date, add game details with price and review score, or get only new reviews.

- **URL**: https://apify.com/deriverge/steam-reviews-scraper.md
- **Developed by:** [deriverge s.r.o.](https://apify.com/deriverge) (community)
- **Categories:** E-commerce, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.23 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

Steam Reviews Scraper returns the user reviews of any Steam game, one row per review: the full text, whether the reviewer recommends the game, helpful and funny votes, post and edit dates, Steam purchase, free copy, early access and Steam Deck flags, and the hours the reviewer had played. Enter app IDs, store links or game names in **Games** and click **Start**; 7,464 English reviews of 6 games took 21 seconds in October 2026. Reviewer names, Steam IDs and profiles are not collected. It costs $0.45 per 1,000 reviews on the Free plan ($0.225 on Business), and the $5 of monthly credit in Apify's Free plan covers about 11,000 reviews.

### What data does it return?

| Field | Description |
|---|---|
| `reviewId`, `key` | Steam's recommendation ID of the review, and the row key `review:<reviewId>` that new-only mode compares. |
| `appId`, `gameName` | Steam app ID of the game, and its name when **Include game details** is on (otherwise `null`). |
| `text` | The whole review as written, with line breaks. Reviews without any text are left out. |
| `recommended` | `true` for a positive review (thumbs up), `false` for a negative one. |
| `language` | Language of the review in Steam's naming, such as `english`, `schinese` or `brazilian`. |
| `votesHelpful`, `votesFunny`, `helpfulnessScore` | How many users marked the review helpful or funny, and Steam's weighted helpfulness score from 0 to 1. |
| `commentCount` | Number of comments under the review. |
| `createdAt`, `updatedAt` | When the review was posted and last edited, ISO 8601 UTC. Equal when it was never edited. |
| `steamPurchase`, `receivedForFree`, `writtenDuringEarlyAccess`, `primarilySteamDeck` | Whether the reviewer bought the game on Steam, marked it as received for free, wrote during early access, or played mostly on a Steam Deck. |
| `playtimeAtReviewHours`, `playtimeTotalHours`, `playtimeLastTwoWeeksHours` | Hours played when writing the review, in total so far and in the last two weeks, to one decimal. |
| `authorGamesOwned`, `authorReviewCount` | How many games the reviewer owns and how many reviews they wrote. These two counts are all the actor keeps about the reviewer. Steam stopped returning the games count on 22 October 2026, so `authorGamesOwned` is empty in new runs. |
| `type` | `review` for review rows, `game` for the optional game rows described below. |

With **Include game details** on, each game also gets one row of `type` `game` with `name`, `kind` (such as `game` or `dlc`), `developers`, `publishers`, `releaseDate` as the store writes it, `priceInitial`, `priceFinal`, `discountPercent` and `currency` for the store country, `metacriticScore`, `genres`, `categories`, `platforms`, `supportedLanguages`, `dlcCount`, `achievementsTotal`, and the review summary: `reviewScoreLabel` (such as `Very Positive`), `totalPositive`, `totalNegative`, `totalReviews` and `positiveShare` in percent.

### How to scrape Steam reviews

1. In **Games**, enter Steam app IDs (`413150`), store links (`https://store.steampowered.com/app/570/Dota_2/`) or names (`Hades`), one per line. To review a whole genre or series, put words into **Search terms**, which takes the top matches of each term from the Steam store search.
2. Set **Maximum reviews per game**. Reviews are read 100 at a time in the **Order** you pick: newest first, recently updated or most helpful.
3. Narrow by **Review language** (`all` or one Steam language such as `english` or `german`), **Review type** (recommended or not) and **Purchase type** (bought on Steam or with a key from elsewhere). Steam applies these filters itself, so only matching reviews are read.
4. Add **Published after** to get reviews from a date on. With newest first, reading stops once it reaches that date.
5. Turn on **Include game details** if you also want prices, genres and the review score, and click **Start**. Rows land in the **Output** tab and can be exported as CSV, Excel or JSON.

An API input for recent negative English reviews of two games:

```json
{
  "apps": ["730", "https://store.steampowered.com/app/1145350/"],
  "maxReviewsPerApp": 1000,
  "language": "english",
  "reviewType": "negative",
  "sort": "recent",
  "publishedAfter": "2026-09-01",
  "includeGameDetails": true
}
```

### Example output

A review of Hades from a run on 11 October 2026 with the prefilled input. **Include game details** was off, so `gameName` is `null`.

```json
{
  "type": "review",
  "key": "review:237457959",
  "appId": 1145360,
  "gameName": null,
  "reviewId": "237457959",
  "language": "english",
  "text": "Probably one of the best games ever, and certainly one of the best of its genre.  Perfect mesh of story and game mechanics, winding down now but still loving it after 110 hours.  Wonderful knowing Hades 2 is waiting for me after I finish.",
  "recommended": true,
  "votesHelpful": 0,
  "votesFunny": 0,
  "helpfulnessScore": 0.5,
  "commentCount": 0,
  "createdAt": "2026-10-11T12:12:40.000Z",
  "updatedAt": "2026-10-11T12:12:40.000Z",
  "steamPurchase": true,
  "receivedForFree": false,
  "writtenDuringEarlyAccess": false,
  "primarilySteamDeck": false,
  "playtimeAtReviewHours": 110.3,
  "playtimeTotalHours": 112.6,
  "playtimeLastTwoWeeksHours": 100.3,
  "authorGamesOwned": 763,
  "authorReviewCount": 41
}
```

### How much does it cost to scrape Steam reviews?

| | Free plan | Starter | Scale | Business |
|---|---|---|---|---|
| 1,000 reviews | $0.45 | $0.36 | $0.2925 | $0.225 |
| Game details, per 1,000 | $2.00 | $1.60 | $1.30 | $1.00 |

You pay only for the events in the table. There is no start fee, and compute time and proxies are included.

10,000 reviews cost $4.50 on the Free plan and $2.25 on Business. A game row costs $0.002 and is charged only when **Include game details** is on and the store page was read. Reviews removed by your filters or already returned in new-only mode are not charged.

### Limits

- One run reads up to 500 pages of 100 reviews per game, so at most 50,000 reviews of each game. Counter-Strike 2 had 2,630,032 English reviews in October 2026; to follow such a game, read the newest reviews on a schedule.
- Up to 3 games are read at the same time. A request that meets a server error or HTTP 429 is repeated twice after a pause.
- A name in **Games** takes the game with exactly that name, ignoring case and punctuation: `Hades` gives Hades (1145360), although the store search lists Hades II first. Without an exact match the first search result is used, and the `notes` of the `SUMMARY` record name it, so use the app ID when the name is ambiguous.
- Up to 10 games per search term come from the store's quick search. With a higher **Maximum games per search term**, up to 50, the actor reads the store's search result pages instead, 25 games per page. The search matches names, so `roguelike` finds games with that word in the title.
- There is a start date in **Published after** but no end date. For a closed period, use newest first and drop later reviews from the output.
- Reviews with an empty text are skipped: Combolands had 1,417 English reviews and 1,407 with text.
- The review summary of a game row (`totalReviews`, `reviewScoreLabel`) counts only reviews that match your language, review type and purchase type filters.
- `releaseDate` is store text such as `Aug 21, 2012` or `Coming soon`, and the language of descriptions and genres follows **Store language**.
- With **Day range for most helpful**, Steam limits the most helpful order to the last 365 days at most.

### Watching a game for new reviews

Set a **Watch name** or save the input as a task, turn on **Return only rows new since the last run**, choose newest first and schedule the run daily. Each run returns only reviews that no earlier run of the watch returned, so you pay for new reviews only. Reviews that **Maximum rows** or your spending limit cut off are not counted as seen, and the next run returns them. Keep **Maximum reviews per game** above the number of reviews a game gets between two runs, because only the newest ones are read. With game details on, the game row comes in every run and is charged each time, and the `CHANGES` record lists changes of its price, review score and review count since the last run.

### FAQ

#### Is it legal to scrape Steam reviews?

Steam reviews are public on every store page. The actor reads them through the review endpoint that Valve documents for developers and the public store API, without logging in. It keeps no reviewer name, Steam ID or profile link, only playtime and two counts. Review texts are written by users and can quote anything, and you are responsible for how you use them.

#### Why does the review score differ from the store page?

The store page shows the score of all reviews in all languages, or of reviews in your language. The game row follows the filters of your run, so a run limited to `english` and negative reviews reports the totals for that slice.

#### Which language names does Steam use?

Steam names languages in English and in lower case: `english`, `german`, `french`, `spanish`, `russian`, `brazilian` for Brazilian Portuguese, `schinese` and `tchinese` for Simplified and Traditional Chinese, `koreana` for Korean and `japanese`. In the prefilled run of 150 reviews on 11 October 2026, 41 were in English, 37 in Russian and 36 in Simplified Chinese.

### Related scrapers

- [Google Play Reviews Scraper](https://apify.com/deriverge/google-play-reviews-scraper)
- [App Store Reviews Scraper](https://apify.com/deriverge/app-store-reviews-scraper)

### Support

This actor is built and maintained by deriverge s.r.o., a software company based in the Czech Republic. If a run fails or a field you need is missing, please open an issue in the **Issues** tab or write to us at info@deriverge.com. We respond in English and Czech. Runs can be scheduled in Apify Console or started from the **API** tab, which has examples for Python, JavaScript and cURL and works with Make, Zapier, n8n and the Apify MCP server. If the actor saves you time, a short review helps other people find it.

# Changelog

This Actor's version history is a separate document: https://apify.com/deriverge/steam-reviews-scraper/changelog.md

# Actor input Schema

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

Steam app ids, store links or game names, in any mix. A name is looked up in the store and the first match is used.

## `queries` (type: `array`):

Search the Steam store and take the top matches of each term as games.

## `maxResultsPerQuery` (type: `integer`):

How many top matches of each search term to take as games. Up to 10 come from the store's quick search; above 10 the actor reads Steam's search result pages, 25 games per page, in the order the store shows them.

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

Two-letter country code for prices and availability, for example us, gb, de, cz.

## `storeLanguage` (type: `string`):

Language of game descriptions, genres and categories, as Steam names it: english, german, french, czech and so on.

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

Read a hundred at a time in the order you choose. Popular games have hundreds of thousands.

## `language` (type: `string`):

all, or one Steam language name such as english, german, schinese, russian, french.

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

All reviews, only recommended, or only not recommended, filtered on the store side.

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

All reviews, only from players who bought the game on Steam, or only from keys and other sources.

## `sort` (type: `string`):

Newest first is what a monitor wants; most helpful first is what the store page shows.

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

With the most helpful order, only reviews from the last N days count, up to 365.

## `publishedAfter` (type: `string`):

Drop reviews written before this date (YYYY-MM-DD). With newest first the run stops at that date.

## `includeGameDetails` (type: `boolean`):

One row per game with price, genres, developers, release date, Metacritic score and the review summary. Charged per game.

## `newOnly` (type: `boolean`):

Keeps a snapshot per watch name (or per saved task) and returns only reviews that were not there before. Schedule it daily and you have a review alert that bills only for what is new.

## `watchName` (type: `string`):

Name of the snapshot used by the new-only mode, for example "our-games". Runs from a saved task get a snapshot automatically even without a name.

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

Hard cap on returned rows in the run.

## Actor input object example

```json
{
  "apps": [
    "413150",
    "https://store.steampowered.com/app/570/Dota_2/",
    "Hades"
  ],
  "maxResultsPerQuery": 10,
  "country": "us",
  "storeLanguage": "english",
  "maxReviewsPerApp": 50,
  "language": "all",
  "reviewType": "all",
  "purchaseType": "all",
  "sort": "recent",
  "includeGameDetails": false,
  "newOnly": false,
  "maxItems": 10000
}
```

# Actor output Schema

## `rows` (type: `string`):

One row per review with text, verdict, votes, dates, playtime and purchase flags; one row per game with price, genres and the review summary on request.

## `changes` (type: `string`):

Reviews that appeared since the previous snapshot of the same watch name or task, and price and score changes of games.

## `summary` (type: `string`):

Games read, reviews found, what was charged, games that could not be read and notes.

# 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": [
        "413150",
        "https://store.steampowered.com/app/570/Dota_2/",
        "Hades"
    ],
    "maxReviewsPerApp": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("deriverge/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": [
        "413150",
        "https://store.steampowered.com/app/570/Dota_2/",
        "Hades",
    ],
    "maxReviewsPerApp": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("deriverge/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": [
    "413150",
    "https://store.steampowered.com/app/570/Dota_2/",
    "Hades"
  ],
  "maxReviewsPerApp": 50
}' |
apify call deriverge/steam-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,deriverge/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/bYLtL1DF2NIftsmps/builds/cDC5TiibhRsi5WIQW/openapi.json
