# Steam Store & Reviews Scraper (`tortuga/steam-scraper`) Actor

Scrape Steam games and user reviews: search results, app details (price, discounts, tags, genres, release date, developer, platforms) and reviews with votes, playtime and language.

- **URL**: https://apify.com/tortuga/steam-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** E-commerce, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 reviews

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Store & Reviews Scraper

Scrape Steam games and user reviews: search results, app details (price, discounts, tags, genres, release date, developer, platforms) and reviews with votes, playtime and language.

Steam Store & Reviews Scraper reads the public JSON endpoints behind `store.steampowered.com` and turns them into a clean dataset. Three modes cover the whole funnel: **search** a keyword and get every result with price, discount and review score; pull **details** for any app ID (price in your region, user tags, genres, categories, release date, developers, Metacritic, achievements, DLC); or collect **reviews** with helpful/funny votes, playtime, purchase type and language, plus a per-app review summary (total positive/negative, "Very Positive"). No Steam account or API key is needed and mature (age-gated) games work. Download JSON, CSV or Excel, or use the API from Python, Node, n8n or Google Sheets. You pay only for the items you get.

### What data does Steam Store & Reviews Scraper extract?

Every item has a `type` field: `review`, `summary`, `app` or `search`.

#### Review items (`type: "review"`, mode `reviews`)

| Field | Description |
|---|---|
| `appId`, `appName` | Steam app ID and name |
| `recommendationId` | Steam's review ID |
| `url` | Public review page on steamcommunity.com |
| `language` | Steam language code (`english`, `schinese`, `russian`, ...) |
| `text` | Review text |
| `votedUp` | `true` = Recommended, `false` = Not recommended |
| `votesUp`, `votesFunny`, `commentCount` | Helpful votes, funny votes and comments |
| `weightedVoteScore` | Steam's helpfulness score (0-1) |
| `steamPurchase`, `receivedForFree`, `writtenDuringEarlyAccess`, `refunded`, `primarilySteamDeck` | Purchase and context flags |
| `createdAt`, `updatedAt` | ISO 8601 UTC timestamps |
| `playtimeForeverMinutes`, `playtimeAtReviewMinutes`, `playtimeLastTwoWeeksMinutes`, `lastPlayedAt` | Reviewer playtime in this game |
| `numGamesOwned`, `numReviews` | Reviewer's public library size and review count |
| `authorSteamId` | Public numeric Steam ID printed on every review (no profile is fetched) |
| `reactions` | `[{type, count}]` award reactions on the review |

#### Review summary items (`type: "summary"`, one per app in mode `reviews`)

`appId`, `appName`, `url`, `reviewScore` (0-9), `reviewScoreDesc` (`Very Positive`), `totalPositive`, `totalNegative`, `totalReviews`, `positivePercent`. The totals respect your language/type/purchase filters.

#### App items (`type: "app"`, mode `details`)

| Field | Description |
|---|---|
| `appId`, `name`, `url`, `appType` | Identity; `appType` is `game`, `dlc`, `demo`, `music`, ... |
| `isFree`, `price`, `originalPrice`, `currency`, `discountPercent`, `priceFormatted` | Price in the region given by **Country code** (`price` is a number, e.g. `59.99`) |
| `releaseDate`, `comingSoon` | Release date text as shown on the store and the coming-soon flag |
| `developers`, `publishers` | Lists of names |
| `genres`, `categories` | Store genres (`Action`) and categories (`Multi-player`, `Steam Achievements`) |
| `tags`, `tagsDetailed` | Top 20 user tags in Steam's order; `tagsDetailed` adds `id` and `count` |
| `platforms` | Subset of `windows`, `mac`, `linux` |
| `metacriticScore`, `metacriticUrl`, `recommendationsTotal` | Critic score and total Steam recommendations |
| `headerImage`, `capsuleImage`, `screenshots`, `movies` | Media URLs (trailers as HLS/DASH streams) |
| `shortDescription`, `aboutTheGame`, `website` | Plain-text descriptions |
| `supportedLanguages`, `fullAudioLanguages` | Interface languages and those with full audio |
| `achievementsCount`, `dlcCount`, `dlcAppIds`, `packages` | Achievements, DLC and purchasable package IDs |
| `requiredAge`, `contentDescriptors`, `controllerSupport` | Age rating, mature-content notes and controller support |

#### Search items (`type: "search"`, mode `search`)

`searchTerm`, `appId` (or `packageId`/`bundleId` for bundles), `name`, `url`, `price`, `originalPrice`, `currency`, `priceFormatted`, `isFree`, `discountPercent`, `releaseDate`, `reviewSummary` (`Overwhelmingly Positive`), `reviewPositivePercent`, `reviewCount`, `platforms`, `thumbnail`, `tagIds`.

### How to use Steam Store & Reviews Scraper

1. Pick a **Mode**: `reviews`, `details` or `search`.
2. For `reviews` and `details`, paste **App IDs** or store URLs (`570`, `https://store.steampowered.com/app/730/Counter-Strike_2/`), one per line. For `search`, enter **Search terms**.
3. Set **Max items** (and optionally **Max reviews per app**) to cap the run and the cost.
4. Optionally filter reviews by **Review language**, **Review type** (positive/negative) and **Purchase type**, or set **Country code** for prices.
5. Click **Start**. Results appear in the **Dataset** tab; export from there or use the API.

### Input example

```json
{
  "mode": "reviews",
  "appIds": ["570", "https://store.steampowered.com/app/730/Counter-Strike_2/"],
  "maxItems": 2000,
  "maxReviewsPerApp": 1000,
  "reviewsFilter": "recent",
  "reviewLanguage": "english",
  "reviewType": "all",
  "purchaseType": "all"
}
```

```json
{ "mode": "details", "appIds": ["1091500", "367520"], "countryCode": "de" }
```

```json
{ "mode": "search", "searchTerms": ["hollow knight", "roguelike deckbuilder"], "maxItems": 200 }
```

### Output example

```json
{
  "type": "review",
  "appId": 570,
  "appName": "Dota 2",
  "recommendationId": "234729359",
  "url": "https://steamcommunity.com/profiles/76561199800017251/recommended/570/",
  "language": "english",
  "text": "Still the deepest MOBA there is. 2000 hours and counting.",
  "votedUp": true,
  "votesUp": 12,
  "votesFunny": 1,
  "weightedVoteScore": 0.61,
  "commentCount": 0,
  "steamPurchase": true,
  "receivedForFree": false,
  "writtenDuringEarlyAccess": false,
  "refunded": false,
  "primarilySteamDeck": false,
  "createdAt": "2026-09-07T21:16:37Z",
  "updatedAt": "2026-09-07T21:16:37Z",
  "playtimeForeverMinutes": 121955,
  "playtimeAtReviewMinutes": 121952,
  "playtimeLastTwoWeeksMinutes": 88,
  "lastPlayedAt": "2026-09-07T21:19:12Z",
  "numGamesOwned": 41,
  "numReviews": 3,
  "authorSteamId": "76561199800017251",
  "reactions": []
}
```

```json
{
  "type": "app",
  "appId": 1091500,
  "name": "Cyberpunk 2077",
  "url": "https://store.steampowered.com/app/1091500/",
  "appType": "game",
  "isFree": false,
  "price": 59.99,
  "originalPrice": 59.99,
  "currency": "USD",
  "discountPercent": 0,
  "releaseDate": "Dec 9, 2020",
  "comingSoon": false,
  "developers": ["CD PROJEKT RED"],
  "publishers": ["CD PROJEKT RED"],
  "genres": ["RPG"],
  "categories": ["Single-player", "Steam Achievements", "Full controller support"],
  "tags": ["Cyberpunk", "Open World", "Nudity", "RPG", "Futuristic"],
  "platforms": ["windows", "mac"],
  "metacriticScore": 86,
  "recommendationsTotal": 800000,
  "achievementsCount": 57,
  "dlcCount": 2,
  "requiredAge": 17,
  "supportedLanguages": ["English", "French", "German"]
}
```

### How to scrape Steam reviews for a game

Set **Mode** to `reviews` and paste the app ID (the number in the store URL, `store.steampowered.com/app/570/...`). Reviews are read newest first, 100 per page, until **Max items**, **Max reviews per app** or the end of the list is reached, so a full history export of a game with 50,000 reviews takes 500 requests. Use **Review language** `english` to keep only English text, **Review type** `negative` to mine complaints, and **Reviews order** `all` to get Steam's most-helpful reviews first. The `summary` item gives the global totals so you can compute the positive ratio without downloading everything.

### Does it work without a Steam account or API key?

Yes. Everything comes from the public store endpoints that the Steam website itself calls when you browse logged out; no Steam Web API key, account, session or cookies from your browser are needed. Mature (age-gated) games are handled automatically.

### How to get Steam game prices and discounts

Use **Mode** `details` with the app IDs and set **Country code** to the store region you care about (`us`, `gb`, `de`, `br`, `jp`, ...). Each app item carries `price`, `originalPrice`, `discountPercent` and `currency` for that region, plus `isFree` and `comingSoon`. Schedule the Actor to track sales over time. For a quick overview of many games, **Mode** `search` returns price, discount and review score for every result in one request per 100 games.

### Can I get Steam user tags, genres and Metacritic scores?

Yes. `details` mode returns the top 20 user-applied tags (`tags`, with vote counts in `tagsDetailed`), store `genres` and `categories`, `metacriticScore`, `recommendationsTotal`, `achievementsCount`, DLC IDs, supported languages, screenshots and trailer links.

### What does it cost?

Pay per item: a review costs a fraction of a cent (a summary item is charged as one review), an app-details item a little more because it needs two requests, and a search result sits in between. There is no start fee and no subscription; Apify's free plan is enough to collect tens of thousands of reviews.

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python/Node with the Apify client. See the **API** tab for ready-made snippets, or schedule the Actor to keep a review feed or price history fresh.

### Is it legal to scrape Steam?

This Actor collects only publicly available data that Steam shows to anyone without an account: store listings, prices and user reviews. It does not log in, does not open user profiles and does not collect names, avatars, emails or other personal details; the only per-reviewer field is the public numeric Steam ID that Steam prints on every review page. You are responsible for how you use the data and for complying with Steam's terms and applicable law.

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

## `mode` (type: `string`):

What to scrape. `reviews`: user reviews (plus one review-summary item) for each app in **App IDs**. `details`: one app item per app with price, tags, genres, release date and more. `search`: store search results for each term in **Search terms**.

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

Steam app IDs or store URLs, one per line: `570`, `https://store.steampowered.com/app/730/Counter-Strike_2/`. Used by the `reviews` and `details` modes. Find the ID in the store URL of the game.

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

Search queries for the `search` mode, one per line, e.g. `hollow knight`, `roguelike deckbuilder`. Each term returns the same list as the store search page, up to **Max items**.

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

Overall cap on dataset items for the run (reviews + summaries, apps, or search results). Keeps cost predictable.

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

Cap on reviews collected from each app in `reviews` mode. Leave empty to use only **Max items**.

## `reviewsFilter` (type: `string`):

`recent`: newest first (default, full history reachable). `updated`: by last edit. `all`: Steam's helpfulness order, which surfaces the most-voted reviews first.

## `reviewLanguage` (type: `string`):

Steam language code, e.g. `all`, `english`, `german`, `schinese`, `russian`, `brazilian`, `japanese`, `koreana`, `spanish`, `french`. Only reviews written in that language are returned.

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

Return all reviews, only recommended (thumbs up) or only not recommended (thumbs down).

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

`steam`: reviews by people who bought the game on Steam. `non_steam_purchase`: reviews from keys activated on Steam. `all`: both.

## `countryCode` (type: `string`):

Two-letter store region for prices and currency in `details` and `search` modes, e.g. `us`, `gb`, `de`, `br`, `jp`.

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

Apify Proxy is recommended for larger runs; Steam rate-limits the app-details endpoint per IP (about 200 requests per 5 minutes).

## Actor input object example

```json
{
  "mode": "reviews",
  "appIds": [
    "570",
    "https://store.steampowered.com/app/730/Counter-Strike_2/"
  ],
  "searchTerms": [
    "hollow knight"
  ],
  "maxItems": 500,
  "reviewsFilter": "recent",
  "reviewLanguage": "all",
  "reviewType": "all",
  "purchaseType": "all",
  "countryCode": "us",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `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 = {
    "appIds": [
        "570",
        "https://store.steampowered.com/app/730/Counter-Strike_2/"
    ],
    "searchTerms": [
        "hollow knight"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/steam-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": [
        "570",
        "https://store.steampowered.com/app/730/Counter-Strike_2/",
    ],
    "searchTerms": ["hollow knight"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/steam-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": [
    "570",
    "https://store.steampowered.com/app/730/Counter-Strike_2/"
  ],
  "searchTerms": [
    "hollow knight"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tortuga/steam-scraper --silent --output-dataset

```

## MCP server setup

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