# Steam Reviews Scraper: Game Reviews & Sentiment (`recordsdata/steam-reviews-scraper`) Actor

Scrape Steam game reviews: text, recommended flag, helpful and funny votes, playtime at review, purchase type, with language, sentiment and sort filters, plus a game summary row (positive %, price, Metacritic). Tested on 9.9M CS2 reviews. Export CSV, Excel, JSON. No login or API key.

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

## Pricing

Pay per event

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

<p align="center">
  <img src="https://api.apify.com/v2/key-value-stores/AAm3a1h3Z9nYfrvh9/records/banner" alt="PunkRecordsData" width="100%" />
</p>

## 🎮 Steam Reviews Scraper: Game Reviews, Votes & Sentiment

> **Steam Reviews Scraper by PunkRecordsData exports user reviews for any Steam game by app ID or store URL. Each row has the review text, thumbs up or down, helpful and funny votes, reviewer playtime and purchase type. Filter by sentiment, language and sort order, add one summary row per game with positive percentage, price and Metacritic score, and export CSV, Excel, JSON or XML. No login, no API key. Priced at $0.01 per review.**

Steam Reviews Scraper reads Steam's own public review service and handles cursor pagination for you. In a cloud test on Counter-Strike 2 (app 730), which held 9,900,823 reviews at 85.8% positive (Very Positive) when measured, a 10-row run finished in under 5 seconds. It is built for game studios, market researchers, NLP teams and deal sites that need labeled player opinions in bulk.

### 🔎 What does Steam Reviews Scraper do?

- Scrape Steam reviews for one or many games in a single run, from app IDs (730) or store URLs.
- Export only positive or only negative reviews, or both.
- Filter Steam reviews by language: english, spanish, latam, brazilian, german, french, schinese and every other code Steam uses.
- Separate Steam purchases from activated keys with the purchase type filter.
- Sort by newest, recently updated or most helpful.
- Add a game summary row with total, positive and negative review counts, positive percentage, score label, price in USD, developers, publishers, genres, release date and Metacritic score.
- Stop a run at your own per-game cap or total item cap.

### 📊 What data can you extract from Steam reviews?

| Field | Description |
|---|---|
| recordType | `review` or `game-summary` |
| appId, gameName | Steam app ID and game title |
| reviewId | Unique Steam recommendation ID |
| recommended | true for thumbs up, false for thumbs down |
| reviewText | Review body (first 1,500 characters, whitespace cleaned) |
| language | Language the reviewer wrote in |
| votesHelpful, votesFunny, commentCount | Community reactions |
| steamPurchase, receivedForFree | How the reviewer got the game |
| earlyAccessReview | Written during Early Access |
| playtimeHoursTotal, playtimeHoursAtReview | Reviewer hours now and when the review was written |
| authorGamesOwned, authorReviewCount | Reviewer library size and review count (when the profile shows them) |
| createdAt, updatedAt | ISO timestamps |
| url | Link to the reviewer's review on Steam Community |
| scrapedAt | UTC time of collection |

Summary rows add: name, reviewScoreDesc, totalReviews, totalPositive, totalNegative, positivePercent, developers, publishers, releaseDate, priceFormatted, genres, metacritic (when the game has one) and headerImage.

Fields Steam does not return for a given row are left out of that row instead of being filled with placeholders. Rows are never padded with N/A or null values.

### 🧾 Steam review sample output

Real review row from a cloud run on Counter-Strike 2:

```json
{
  "recordType": "review",
  "appId": "730",
  "gameName": "Counter-Strike 2",
  "reviewId": "236844770",
  "recommended": true,
  "reviewText": "Man I love this game it brings so much joy to me. I have a hard time not killing my teammates but its very fun and I would always kill my teammates in another life time. I love team killing",
  "language": "english",
  "votesHelpful": 0,
  "votesFunny": 0,
  "commentCount": 0,
  "steamPurchase": true,
  "receivedForFree": false,
  "earlyAccessReview": false,
  "playtimeHoursTotal": 67.8,
  "playtimeHoursAtReview": 67.3,
  "authorGamesOwned": 52,
  "authorReviewCount": 2,
  "createdAt": "2026-10-04T03:53:14.000Z",
  "updatedAt": "2026-10-04T03:53:14.000Z",
  "url": "https://steamcommunity.com/profiles/76561198888619903/recommended/730/",
  "scrapedAt": "2026-10-04T05:11:25.107Z"
}
```

Real game summary row from the same run:

```json
{
  "recordType": "game-summary",
  "appId": "730",
  "name": "Counter-Strike 2",
  "reviewScoreDesc": "Very Positive",
  "totalReviews": 9900823,
  "totalPositive": 8497082,
  "totalNegative": 1403741,
  "positivePercent": 85.8,
  "developers": ["Valve"],
  "publishers": ["Valve"],
  "releaseDate": "Aug 21, 2012",
  "priceFormatted": "Free",
  "genres": ["Action", "Free To Play"],
  "url": "https://store.steampowered.com/app/730/"
}
```

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

Pay per event. You pay only for rows saved to your dataset.

| Event | Price (Free plan) | Charged for |
|---|---|---|
| Review row | $0.01 | One user review |
| Game summary | $0.012, down to $0.01 on Gold and above | One summary row per game |

1,000 reviews cost $10. A 10-row test (1 summary plus 9 reviews) measured 9 review events and 1 game summary event, about $0.10 on the Free plan. You are not charged for failed or empty lookups: an unknown app ID, a failed request, or a filter that matches no reviews saves no billable row. The `maxItems` field and your Apify run budget both stop the run cleanly when the limit is reached.

### 🚀 How to scrape Steam reviews in 3 steps

1. Open the actor and click **Try for free**.
2. Paste one or more Steam app IDs or store URLs, choose sentiment, language, sort order and a per-game cap.
3. Click **Start**, then download the dataset as CSV, Excel, JSON or XML.

The app ID is the number in any Steam store URL: `store.steampowered.com/app/730/` is app 730.

### ⚙️ Steam Reviews Scraper input

| Field | Default | What it does |
|---|---|---|
| appIds | \["730"] | Steam app IDs or store URLs |
| reviewType | all | all, positive or negative |
| purchaseType | all | all, steam or non\_steam\_purchase |
| language | all | Steam language code |
| sortBy | recent | recent, updated or all (most helpful) |
| maxReviewsPerGame | 200 | Review rows per game, up to 50,000 |
| includeGameSummary | true | Add one summary row per game |
| maxItems | none | Total rows across all games, summary rows included |

Example input for the 500 most helpful negative English reviews of Counter-Strike 2:

```json
{
  "appIds": ["730"],
  "reviewType": "negative",
  "language": "english",
  "sortBy": "all",
  "maxReviewsPerGame": 500,
  "includeGameSummary": false
}
```

Free Apify users are limited to 10 rows per run as a preview. Paid users can request up to 1,000,000 rows.

### 📦 Steam Reviews Scraper output

Results go to the default dataset in two row types, `review` and `game-summary`. The Overview view shows the key columns; the full dataset has every field. Download as CSV, Excel, JSON or XML, or read it through the API. A run with no matching reviews finishes as SUCCEEDED with a clear status message and no charge. A run where Steam requests fail and no rows are delivered ends as FAILED, so you never pay for a silent block.

### ⚖️ Steam Reviews Scraper vs alternatives

Prices measured from the public Apify Store listings on 2026-10-04 (per 1,000 review rows, Free plan, start fees listed separately):

| Actor | Per 1,000 reviews | Start fee |
|---|---|---|
| This actor | $10.00 | none |
| automation-lab steam-game-reviews-scraper | $0.58 | $0.003 |
| memo23 steam-reviews-scraper | $1.00 | $0.005 |
| shahidirfan steam-reviews-scraper | $0.99 | $0.0005 |
| logiover steam-game-reviews-scraper | $3.00 | $0.00005 |

On raw price per review this actor is the most expensive of the group, so if you only need review text at the lowest cost, a cheaper actor is the better pick. What this one adds: reviewer playtime at review time and library size, the purchase-type and sentiment filters together, a game summary row (positive percentage, price, Metacritic) next to the reviews, no start fee, and rows with no placeholder values or duplicate review IDs.

### 💡 Use cases for Steam review data

- **Patch sentiment tracking**: pull negative reviews after each update, sorted by helpfulness.
- **Competitive analysis**: compare positive percentage and complaint themes across rival games.
- **NLP and ML training**: recommended-labeled text, weighted by playtime at review.
- **Store and deal sites**: keep live review scores beside game listings.

### 🔌 Run Steam Reviews Scraper via API and integrations

Call it from any language with the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/recordsdata~steam-reviews-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"appIds":["730"],"maxItems":10}'
```

Schedule runs in the Apify Console, or connect to Zapier, Make, n8n, Google Sheets, Slack and Airbyte. The actor is also available to AI agents through the Apify MCP server, with a default input that runs without extra setup.

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

The actor reads Steam's public review endpoints, the same data shown on every game's store page, at a respectful rate with no login. Review text belongs to its authors and reviewer names are not collected, only the public profile link Steam exposes with each review. Use the data in line with Valve's terms and the privacy laws that apply to you.

### ❓ Frequently asked questions

#### How do I find a Steam app ID?

It is the number in the store URL, for example 730 in `store.steampowered.com/app/730/`. You can also paste the full store URL into the input.

#### How many Steam reviews can I scrape per game?

Up to 50,000 per game per run through cursor pagination. Big games hold millions, so use sentiment, language or purchase filters to slice them.

#### What is playtime at review?

The hours the reviewer had in the game when they wrote the review, converted from Steam's minutes to hours. It helps you weigh veteran opinions against new players.

#### Why did my run return 0 results?

Usually the filters match nothing (for example a rare language on a small game), or the app ID does not exist. The run still ends with SUCCEEDED, a status message explaining why, and no charge. Try language `all` and reviewType `all`.

#### Why did my run fail?

If Steam requests fail and no rows were delivered, the run ends as FAILED with a message, and nothing is charged. Run it again later. If it keeps failing, open the Issues tab.

#### Do I get charged for game summary rows?

Yes, one summary row per game is a separate event ($0.012 on the Free plan). Set `includeGameSummary` to false to skip it. Summary rows count toward `maxItems`.

#### Can I scrape many games in one run?

Yes. Put several app IDs in `appIds`. The per-game cap applies to each game, and `maxItems` caps the whole run.

#### Does it need a Steam account or API key?

No. It uses public endpoints only.

#### Can I try it for free?

Yes. Free Apify users get a 10-row preview per run, and new accounts include free platform credit.

### 🧭 Want more gaming data? Other PunkRecordsData scrapers

- [Steam Charts Scraper](https://apify.com/RecordsData/steam-charts-scraper) for player counts and top games
- [Epic Games Store Scraper](https://apify.com/RecordsData/epic-games-store-scraper) for Epic catalog and prices
- [GOG Games Scraper](https://apify.com/RecordsData/gog-games-scraper) for GOG catalog and discounts

### 🙋 Support

Found a bug or missing field? Open the Issues tab on this actor's page or write to contact.punkrecordsdata@gmail.com. Custom solutions are available on request.

Last updated: 2026-10-03

# Actor input Schema

## `appIds` (type: `array`):

Steam app IDs or store URLs of the games to scrape reviews for, for example 730 (Counter-Strike 2), 570 (Dota 2) or https://store.steampowered.com/app/730/. Each game is scraped separately.

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

All, only positive or only negative reviews.

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

Filter by how the reviewer got the game.

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

Steam review language code to keep: all, english, spanish, latam, brazilian, german, french, russian, schinese, koreana and others. Use all for every language.

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

Order of reviews.

## `maxReviewsPerGame` (type: `integer`):

Maximum number of review rows to scrape for each game (1 to 50,000). Reviews are fetched newest, most helpful or recently updated first, per the Sort by option.

## `includeGameSummary` (type: `boolean`):

One row per game with total/positive/negative counts, price, developers and Metacritic score.

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

Maximum total rows to return across all games, including game summary rows. Free users are limited to 10 rows (preview). Paid users: optional, up to 1,000,000. Leave empty for no extra cap beyond the per-game limit.

## Actor input object example

```json
{
  "appIds": [
    "730"
  ],
  "reviewType": "all",
  "purchaseType": "all",
  "language": "all",
  "sortBy": "recent",
  "maxReviewsPerGame": 200,
  "includeGameSummary": true,
  "maxItems": 10
}
```

# Actor output Schema

## `overview` (type: `string`):

Key fields per row

## `fullData` (type: `string`):

Complete dataset with all fields

# 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 = {
    "appIds": [
        "730"
    ],
    "maxItems": 10
};

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

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

```

## MCP server setup

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