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

Scrape Steam player reviews and game store data to JSON/CSV: review text, playtime, recommended/not recommended, helpfulness votes, purchase type, plus prices, genres, developers and review-score summaries.

- **URL**: https://apify.com/fetchsmith/steam-reviews-scraper.md
- **Developed by:** [Fetch Smith](https://apify.com/fetchsmith) (community)
- **Categories:** E-commerce, Social media, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 result items

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Steam Reviews Scraper

Scrape **Steam player reviews** and **Steam store data** into JSON, CSV or Excel — no login, no browser, no proxy needed.

Give it Steam store URLs, numeric App IDs, or just game names to search for. You get every review with its full text, the reviewer's **playtime**, whether they recommend the game, helpfulness votes, whether it was a real Steam purchase, and (optionally) the game's name, developer, publisher, genres and release date attached to every row.

**Pay per result: $0.0005 per review or game record. No start fee** — a run that returns nothing costs nothing.

### What you can do with it

- **Track sentiment after a patch or a price change** — pull reviews sorted by most recent, filter to `negative`, and diff week over week.
- **Find bug reports in the wild** — set `keyword` to `crash`, `stutter`, `controller` or `refund` and get only the reviews that mention it.
- **Filter out drive-by reviews** — `minPlaytimeHours: 10` keeps only reviewers who actually played the game.
- **Competitive research** — `dataType: "games"` returns price, discount, genres, developer, Metacritic score, the full review-score summary (total positive/negative, % positive) and, optionally, the **live concurrent player count**.
- **Localised research** — `language: "schinese"`, `"russian"`, `"brazilian"` … or `"all"` for every language at once.
- **Feed an LLM / dataset pipeline** — clean flat rows, stable `reviewId`, ISO-8601 timestamps.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `dataType` | string | `reviews` | `reviews` = player reviews; `games` = store record for each game |
| `apps` | array | — | Steam store URLs (`https://store.steampowered.com/app/1145360/Hades/`) or numeric App IDs (`1145360`) |
| `searchTerms` | array | — | Find games by name instead of / as well as URLs |
| `maxReviewsPerApp` | integer | `200` | Reviews per game before moving to the next one (max 5000) |
| `maxResults` | integer | `2000` | Hard cap on rows pushed — also caps what you are charged |
| `language` | string | `english` | Steam language code, or `all` |
| `reviewType` | string | `all` | `positive` / `negative` to keep only thumbs-up / thumbs-down |
| `purchaseType` | string | `all` | `steam` excludes key activations and free weekends |
| `sortBy` | string | `recent` | `recent`, `updated`, or `all` (Steam's helpfulness ranking) |
| `dayRange` | integer | — | With `sortBy: "all"`, restrict to the last N days (1–365) |
| `minPlaytimeHours` | integer | — | Keep only reviewers with at least this many hours in the game |
| `keyword` | string | — | Keep only reviews whose text contains this word/phrase |
| `country` | string | `us` | Two-letter code for store prices and availability |
| `includeGameInfo` | boolean | `true` | Attach game name/developer/publisher/genres/release date to every review |
| `includePlayerCount` | boolean | `false` | `games` mode: also fetch the live concurrent player count |
| `searchLimit` | integer | `10` | Games taken from each search term |

#### Example input

```json
{
  "dataType": "reviews",
  "apps": ["https://store.steampowered.com/app/1145360/Hades/"],
  "maxReviewsPerApp": 200,
  "language": "english",
  "reviewType": "negative",
  "minPlaytimeHours": 5,
  "keyword": "crash"
}
```

### Output

#### Review row (`dataType: "reviews"`)

```json
{
  "type": "review",
  "appId": 1145360,
  "reviewId": "234888482",
  "review": "Best roguelike I have ever played, and the story actually lands.",
  "language": "english",
  "recommended": true,
  "createdAt": "2026-09-10T03:35:39.000Z",
  "updatedAt": "2026-09-10T03:37:38.000Z",
  "votesUp": 0,
  "votesFunny": 0,
  "weightedVoteScore": 0.5,
  "commentCount": 0,
  "steamPurchase": true,
  "receivedForFree": false,
  "writtenDuringEarlyAccess": false,
  "refunded": false,
  "playtimeForeverHours": 3.9,
  "playtimeAtReviewHours": 3.9,
  "playtimeLastTwoWeeksHours": 3.7,
  "authorSteamId": "76561197974061804",
  "authorName": "BobbyRunout",
  "authorProfileUrl": "https://steamcommunity.com/id/BobbyRunout/",
  "authorNumGamesOwned": 1180,
  "authorNumReviews": 100,
  "reviewUrl": "https://steamcommunity.com/profiles/76561197974061804/recommended/1145360/",
  "gameName": "Hades",
  "developers": ["Supergiant Games"],
  "publishers": ["Supergiant Games"],
  "genres": ["Action", "Indie", "RPG"],
  "releaseDate": "Sep 17, 2020",
  "storeUrl": "https://store.steampowered.com/app/1145360/",
  "scrapedAt": "2026-09-10T06:03:39.139Z"
}
```

#### Game row (`dataType: "games"`)

```json
{
  "type": "game",
  "appId": 367520,
  "name": "Hollow Knight",
  "appType": "game",
  "storeUrl": "https://store.steampowered.com/app/367520/",
  "isFree": false,
  "priceCurrency": "GBP",
  "price": 12.79,
  "priceInitial": 12.79,
  "discountPercent": 0,
  "releaseDate": "24 Feb, 2017",
  "developers": ["Team Cherry"],
  "publishers": ["Team Cherry"],
  "genres": ["Action", "Adventure", "Indie"],
  "platforms": ["windows", "mac", "linux"],
  "metacriticScore": 90,
  "reviewScoreDesc": "Overwhelmingly Positive",
  "totalReviews": 560648,
  "totalPositive": 543211,
  "totalNegative": 17437,
  "positivePercent": 96.9,
  "currentPlayers": 4132,
  "country": "gb"
}
```

### FAQ

**Do I need a Steam API key or a proxy?**
No. This Actor only reads Steam's public store endpoints over plain HTTP. No login, no key, no residential proxy, so runs are fast and cheap.

**Can I get *all* reviews of a huge game?**
Yes — the Actor paginates with Steam's review cursor. Set `maxReviewsPerApp` (up to 5000 per game) and `maxResults` for the overall cap. Remember you are charged per row returned, so set both deliberately.

**Why did I get fewer reviews than `maxReviewsPerApp`?**
Either the game genuinely has fewer reviews in that language/filter combination, or your `keyword` / `minPlaytimeHours` filters removed the rest. Filtered-out reviews are **not** charged. The run's status message says which case it was.

**Does `dayRange` work with the "most recent" sort?**
No — Steam only honours a day range in its helpfulness ranking, so set `sortBy: "all"` when you use `dayRange`. The other sorts are already chronological, so filter by `createdAt` on your side instead.

**I set `sortBy: "all"` and got way fewer reviews than expected — why?**
Steam silently caps its helpfulness ranking to the **last 30 days** if you don't also set `dayRange`. For a true all-time "most helpful" pull, set `dayRange: 365` explicitly alongside `sortBy: "all"`.

**My search term matched a soundtrack or DLC, not the game — is that a bug?**
No, that's Steam's own search behaviour: `storesearch` returns soundtracks and some DLC as regular `type: "app"` results alongside the base game. If you're using `searchTerms`, check the `name`/`appId` in your results, or switch to `apps` with the exact App ID to avoid ambiguity.

**Which languages can I ask for?**
Any Steam language code: `english`, `schinese`, `tchinese`, `japanese`, `koreana`, `russian`, `german`, `french`, `spanish`, `latam`, `brazilian`, `polish`, `turkish`, `italian`, `thai`, `vietnamese`, … or `all`.

**What happens if a game is delisted or region-locked?**
The run finishes successfully with a clear status message naming the App IDs Steam returned nothing for, instead of failing. You are only charged for rows you actually receive.

***

Source code: https://github.com/Fetchsmith/fetchsmith/tree/main/actors/steam-reviews-scraper
More tools: [fetchsmith.com](https://fetchsmith.com/tools) · Built and maintained with AI assistance.

# Actor input Schema

## `dataType` (type: `string`):

reviews = player reviews for the given games; games = the store record for each game (price, genres, developer, review score summary, optional live player count).

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

Steam store URLs or numeric App IDs, e.g. https://store.steampowered.com/app/1145360/Hades/ or 1145360.

## `searchTerms` (type: `array`):

Find games by name instead of (or as well as) giving URLs. Each match is then scraped according to 'What to scrape'.

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

Reviews only: how many reviews to fetch per game before moving to the next one (max 5000).

## `maxResults` (type: `integer`):

Hard cap on rows pushed to the dataset across all games — also caps what you are charged.

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

Steam language code for the reviews to return: english, schinese, russian, german, french, spanish, japanese, brazilian, ... or "all" for every language.

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

positive = thumbs-up reviews only, negative = thumbs-down only.

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

steam = reviews from players who bought the game on Steam (excludes key activations and free weekends).

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

recent = newest first, updated = most recently edited first, all = Steam's helpfulness ranking. Note: Steam itself defaults 'all' to only the last 30 days unless you also set 'Last N days' below.

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

With Sort = Most helpful, restrict to reviews from the last N days (1-365). Steam applies a 30-day window by default in that mode if you leave this blank, so set it to 365 for a true all-time 'most helpful' pull. Ignored in the other sort modes, which are already chronological.

## `minPlaytimeHours` (type: `integer`):

Keep only reviews from players with at least this many hours in the game — a cheap way to drop drive-by reviews.

## `keyword` (type: `string`):

Keep only reviews whose text contains this word or phrase (case-insensitive), e.g. "crash", "controller", "price".

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

Two-letter country code used for store prices and availability (us, gb, de, ...).

## `includeGameInfo` (type: `boolean`):

Adds gameName, developers, publishers, genres, releaseDate and storeUrl to each review row (one extra request per game).

## `includePlayerCount` (type: `boolean`):

Game details only: also fetch the current concurrent player count for each game (one extra request per game).

## `searchLimit` (type: `integer`):

How many games to take from each search term (max 50).

## Actor input object example

```json
{
  "dataType": "reviews",
  "apps": [
    "https://store.steampowered.com/app/1145360/Hades/"
  ],
  "searchTerms": [],
  "maxReviewsPerApp": 200,
  "maxResults": 2000,
  "language": "english",
  "reviewType": "all",
  "purchaseType": "all",
  "sortBy": "recent",
  "country": "us",
  "includeGameInfo": true,
  "includePlayerCount": false,
  "searchLimit": 10
}
```

# Actor output Schema

## `dataset` (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/"
    ],
    "searchTerms": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetchsmith/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/"],
    "searchTerms": [],
}

# Run the Actor and wait for it to finish
run = client.actor("fetchsmith/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/"
  ],
  "searchTerms": []
}' |
apify call fetchsmith/steam-reviews-scraper --silent --output-dataset

```

## MCP server setup

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