# Steam Game Scraper - Reviews, Players & Owners (`maydit/steam-game-intelligence-scraper`) Actor

Steam game scraper with no API key: merge store details, reviews, live player counts, and SteamSpy owner estimates into one row per game. Export CSV or JSON.

- **URL**: https://apify.com/maydit/steam-game-intelligence-scraper.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** E-commerce, Developer tools
- **Features:** Limited permissions
- **Stats:** 16 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 results

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

![Put a game's market signals together — illustrative workflow](https://api.apify.com/v2/key-value-stores/YGxD9JRpduom8Q5Zd/records/steam-game-intelligence-scraper-dbb236910568.png?signature=opANbUT1eCBWW1dcZ55B)

### Put a game's market signals together

For game-market research: combine Steam store details, review signals and current player counts, with optional SteamSpy ownership estimates. Optional review text is saved as separate review records alongside game rows.

[Open this Actor in Console](https://console.apify.com/actors/a6QAP6terwrvApVPq/input) · [First run](#try-this-actor) · [Results](#result-preview) · [Cost](#usage-and-pricing) · [Full guide](#full-guide)

### Try this Actor

#### One game before adding review text

1. Keep the sample app ID **730**, review text **off**, and a **10-record** cap. The first sample requests one game, its public store fields and the selected optional source signals. No API key is required.
2. Open the dataset and `SUMMARY`. Game rows have `type: "game"`; when you later enable review text, individual reviews have `type: "review"` and their own `reviewId`. Both row types count toward the total result cap.
3. Export a market snapshot with `appId`, the observation time and source links. Player counts are observations at collection time; SteamSpy owner counts are estimates. Missing metrics are not zero.

```json
{
  "appIds": [
    "730"
  ],
  "includeReviews": false,
  "maxReviewsPerGame": 8,
  "includeSteamSpy": true,
  "includePlayerCount": true,
  "country": "us",
  "maxResults": 10,
  "maxRunSeconds": 240
}
```

For a search-only Console run, clear the prefilled app ID before adding search terms. API input containing only searchTerms does not add the demo. Search requests return a bounded top-ten match window per term, not an exhaustive catalog. Omitted API cap defaults remain unchanged; the explicit sample above sets the ten-record cap.

### Result preview

The dataset view highlights these columns:

- **Record type** · `type`
- **Steam app ID** · `appId`
- **Game** · `name`
- **Price** · `price`
- **Discount (%)** · `discountPercent`
- **Released** · `releaseDate`

Use the original source links and the field definitions below when interpreting the results. CSV works well for flat columns; JSON preserves nested values.

### Usage and pricing

Base result rate on the FREE tier: **$3 per 1,000 results**. The [Pricing tab](https://apify.com/maydit/steam-game-intelligence-scraper/pricing) shows your plan's result rate and any Actor Start charge. Set a small result limit for the first run; the requested limit is not a guarantee of that many results.

**First-run cost:** At the FREE-tier base rate, **one saved game row costs $0.00305** including one $0.00005 start event at the default memory. If you later save one game plus eight review rows, the nine rows cost **$0.02705** at that rate. The ten-record sample cap allows at most $0.03005 in these result/start events. Your plan and the Store Pricing tab govern actual charges.

***

### Full guide

> Combine available Steam store details, review summaries and current player counts with optional SteamSpy ownership estimates. Optional review text is exported as separate review rows. No API key is required.

#### What it does

This Steam game scraper collects a bounded observation of the selected public sources for supported Steam app IDs and returns a game row when usable source data is available. Instead of a single-purpose price-and-reviews export, it merges **four public Steam data sources** - store details, user reviews, live concurrent player counts, and SteamSpy ownership estimates - so you get pricing, ratings, player activity, and owner estimates together in one dataset. Run it with no API key, query by Steam app ID or by search term, and export everything to CSV or JSON for market research, competitor analysis, or investment due diligence.

Use it as a Steam data API alternative: it returns game details, reviews, player counts, and ownership figures in one call, ready to drop into a spreadsheet, BI tool, or dashboard.

#### Who it's for

- **Indie game developers** benchmarking competitors, genres, and pricing before launch
- **Publishers** tracking portfolio performance and rival titles
- **Game-market analysts** building genre, pricing, and player-trend datasets
- **Investors and VCs** running due diligence on studios and titles
- **Marketing and UA teams** sizing audiences and monitoring review sentiment
- **Competitive-research teams** watching what similar games do on discounts, tags, and player retention

#### What you get (output)

Each game returns one merged row with the fields below. Review rows are returned separately when review enrichment is enabled.

| Field | Description |
|---|---|
| `name` | Game title |
| `gameType` | Type of app (game, DLC, etc.) |
| `isFree` | Whether the title is free-to-play |
| `price` | Current price |
| `discountPercent` | Active discount percentage |
| `releaseDate` | Store release date |
| `developers` | Developer(s) |
| `publishers` | Publisher(s) |
| `genres` | Steam genres |
| `categories` | Steam categories (e.g., multiplayer, controller support) |
| `shortDescription` | Store short description |
| `metacriticScore` | Metacritic score |
| `reviewScoreDesc` | Steam review summary label (e.g., "Very Positive") |
| `totalPositive` | Count of positive reviews |
| `totalNegative` | Count of negative reviews |
| `currentPlayers` | Live concurrent player count |
| `ownersEstimate` | SteamSpy owner estimate |
| `ownersEstimateMin` | Lower bound of the owner estimate |
| `ownersEstimateMax` | Upper bound of the owner estimate |
| `steamSpyCcu` | SteamSpy concurrent-user figure |
| `topTags` | Top community tags |
| `headerImage` | Store header image URL |
| `storeUrl` | Steam store page URL |

**Review rows** (when reviews are enabled): individual review records tied to each game, so you can export Steam reviews to CSV or JSON for sentiment work.

#### Input / how to query

Two ways to select games, plus optional enrichment toggles:

**Modes**

- **By app ID** - pass one or more Steam app IDs to scrape exactly the titles you want
- **By search term** - pass search terms to discover matching games, then scrape them

**Filters and options**

- `app IDs` - target specific Steam titles directly
- `search terms` - discovery mode for finding games by keyword
- `include reviews` - add per-game review rows and review counts
- `include SteamSpy` - add owner estimates and SteamSpy CCU
- `include player count` - add live concurrent player counts
- `country` - set the country/region for pricing
- `max run seconds` - wall-clock budget for the run (default 240, roughly 100 games with every enrichment on). When it is reached the Actor stops cleanly and finishes successfully with the games it already has, and records `stoppedEarlyOnTimeLimit: true` in the run's `SUMMARY`. Raise it, together with the run timeout, for a deliberately large pull

Enable only the enrichment you need. Turn everything on for a full market-intelligence snapshot; keep it minimal for a fast price-and-rating pull.

#### Example use cases

1. **Indie competitor benchmark** - feed a list of 50 rival app IDs, enable reviews + SteamSpy + player count, and export a single CSV comparing price, discount, review score, owner estimates, and live players across your genre.
2. **Sales and revenue estimation** - combine SteamSpy owner estimates with price and review counts to model a title's approximate sales and revenue for a pitch deck or investment memo.
3. **Genre trend dataset** - use search-term discovery to inspect the bounded top-ten match window for each keyword (e.g., "roguelike deckbuilder"), then build a dataset of tags, pricing, and player activity.
4. **Live player-count monitoring** - schedule daily runs on a watchlist of app IDs to track concurrent players over time and spot momentum shifts.
5. **Review sentiment export** - enable reviews on a set of titles to export Steam reviews to JSON for sentiment analysis or feature-request mining.

#### Recurring use and scheduling

For monitoring, run this on a schedule (Apify **Schedules**) - daily or weekly against a fixed list of app IDs. Live `currentPlayers`, `discountPercent`, review counts, and SteamSpy figures all change over time, so recurring runs build a trend history for prices, players, ratings, and ownership.

Keep game observations and review records in separate destination tables. For a latest-game table, upsert by `appId`; for a time series, keep `appId` plus `scrapedAt`. For review records, upsert by `appId` plus `reviewId`. Do not deduplicate all row types by appId alone: that would collapse distinct reviews. This destination upsert is part of your workflow; the Actor does not update earlier datasets. Retain the source run ID so failed delivery can replay the same dataset without launching another collection.

#### FAQ

##### How do I scrape Steam game data without an API key?

Run this actor - it reads public Steam storefront and SteamSpy data directly, so no Steam API key is required. Just provide app IDs or search terms and it returns the merged dataset.

##### How can I export Steam reviews to CSV or JSON?

Enable the **include reviews** option. The actor returns individual review rows alongside each game, and every Apify dataset exports to CSV, JSON, Excel, and other formats.

##### How do I estimate a Steam game's sales and revenue from reviews?

Enable **include SteamSpy** to get `ownersEstimate` (with min/max bounds). Combine those owner estimates with `price` and the positive/negative review counts to model approximate sales and revenue in your own spreadsheet.

##### How do I get SteamSpy owner estimates in bulk?

Pass a list of app IDs (or discover them with search terms), enable **include SteamSpy**, and each row returns `ownersEstimate`, `ownersEstimateMin`, `ownersEstimateMax`, and `steamSpyCcu`.

##### How can I track live concurrent player counts for Steam games?

Enable **include player count** to get `currentPlayers` per title, then schedule the run daily or hourly on a watchlist to track concurrent players over time.

##### What is the best tool to research Steam competitors for my indie game?

Use search-term discovery to find rival titles in your genre, then enable reviews, SteamSpy, and player count to compare pricing, discounts, ratings, owner estimates, and live players side by side in one export.

##### How do I pull Steam price, discount, and Metacritic data for many games at once?

Pass multiple app IDs (or search terms) in a single run. Each row returns `price`, `discountPercent`, and `metacriticScore` along with the rest of the store details - no per-game API calls to manage.

##### How do I get Steam store, reviews, players, and ownership data in one dataset?

That is exactly what this scraper is built for. Enable all three enrichments and each game row merges store details, review counts, live `currentPlayers`, and SteamSpy ownership estimates together.

##### Is there a Steam API alternative that returns game details, reviews, and player counts together?

Yes - this actor merges Steam store details, review data, live player counts, and SteamSpy ownership into one row per game, without requiring a Steam API key, so it works as a drop-in data source for research pipelines.

##### How do I collect Steam data for market analysis or investment research?

Query the titles or genres you care about, enable SteamSpy and player-count enrichment, and export the merged dataset. The owner estimates, pricing, review scores, and player counts give you the inputs for market sizing and due diligence.

#### Data source and notes

- **Sources:** Public Steam storefront endpoints (`appdetails`, `appreviews`, and current-players data) plus **SteamSpy** for ownership estimates. No Steam API key is used.
- **Public data:** All fields come from publicly accessible Steam and SteamSpy data.
- **Estimates are estimates:** `ownersEstimate`, `ownersEstimateMin/Max`, and `steamSpyCcu` are SteamSpy's modeled figures, not official Steam sales numbers. Treat them as directional, not exact.
- **Live values change:** `currentPlayers`, `price`, `discountPercent`, and review counts are point-in-time; schedule recurring runs to build history.
- **Regional pricing:** set the `country` option to control the currency/region of price fields.

#### Found this useful?

If this actor saved you time, a short review on the Apify Store genuinely helps. Reviews are how the next person decides whether a tool is worth trying.

Something broken, missing a field, or a source you want covered? Open an issue on the **Issues** tab and it will get looked at - that is the fastest route to getting it changed.

##### Saved rows and run charge limits

The Actor writes results one at a time and stops when Apify reports the run charge limit. `SUMMARY.stoppedOnChargeLimit` distinguishes that stop from an empty source. Saved-row counts include only rows accepted by the dataset. This Actor has no native saved-baseline or change-only input. For recurring comparisons, retain each completed run's dataset in your own destination and compare stable record identities. Review SUMMARY and source coverage before interpreting absent records; a cap or failed check is not evidence that a record was removed.

### Help with your run

Open the **Issues** tab on this Actor with the run URL, the input field that caused trouble and what you expected to receive. Remove API keys and private information before posting.

[Explore more Mayd-It Actors](https://apify.com/maydit)

### Understand your run

Open **Run report** in the run’s Output tab for saved-record counts, reported source issues and limits, and suggested next steps. Use **CSV export** to take the saved results into a spreadsheet. The existing JSON results and detailed machine-readable summary remain available.

The report reflects this run’s recorded coverage. A successful run or a saved result does not establish that every possible source record was collected.

# Actor input Schema

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

Steam app IDs to analyze, e.g. 730 (CS2), 292030 (The Witcher 3). Find the ID in any Steam store URL: store.steampowered.com/app/<ID>/.

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

Search the Steam store by keyword instead of (or in addition to) app IDs. Each term returns Steam's top 10 matches only - there is no pagination - and the results are merged with any app IDs you passed, with duplicates removed.

## `includeReviews` (type: `boolean`):

Also output the most recent written reviews for each game as separate records (with playtime, votes, language, refunded flag).

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

How many recent reviews to pull per game, newest first, from 1 to 2000 (only applies when review texts are enabled). Games with fewer reviews return fewer, and review rows count toward Max results - so a high value here can be cut short by that cap.

## `includeSteamSpy` (type: `boolean`):

Enrich each game with SteamSpy data: estimated owner range, daily peak CCU, and top community tags. Adds ~1s per game (SteamSpy rate limit).

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

Adds currentPlayers, the live concurrent player count Steam reports right now. A valid but empty game returns 0; a title Steam will not report on comes back null rather than failing the run.

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

Lowercase two-letter country code that sets the pricing region and currency (us, de, jp, gb, br). An unrecognized code does not error - Steam silently falls back to USD, so a typo returns dollars.

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

Hard ceiling on total records written per run, counting game rows and review rows together. With review texts off this is roughly one record per game; with them on, each game costs 1 + its review count, so raise this before raising Max reviews per game.

## `maxRunSeconds` (type: `integer`):

Wall-clock budget for this run, in seconds. When it is reached the Actor stops cleanly and finishes successfully with the rows it already collected, instead of being killed mid-run. Each game costs three or four paced requests (about 2.5 s), so 100 games need roughly 250 s. Raise it (and the run timeout in Run options) for a deliberately large job.

## Actor input object example

```json
{
  "appIds": [
    "730"
  ],
  "searchTerms": [
    "roguelike deckbuilder",
    "survival horror"
  ],
  "includeReviews": false,
  "maxReviewsPerGame": 8,
  "includeSteamSpy": true,
  "includePlayerCount": true,
  "country": "us",
  "maxResults": 10,
  "maxRunSeconds": 240
}
```

# Actor output Schema

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

One row per Steam game, merging store details, reviews, live player counts and SteamSpy owner estimates.

## `runReport` (type: `string`):

Readable summary of saved records, reported source coverage, limits and next steps. Available when this run saves its SUMMARY.

## `csvExport` (type: `string`):

Download saved dataset records as a CSV file for spreadsheets and other tools.

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

Totals for the run, including how many records were requested versus returned and whether the run stopped early on its time budget.

# 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"
    ],
    "maxReviewsPerGame": 8,
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/steam-game-intelligence-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"],
    "maxReviewsPerGame": 8,
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("maydit/steam-game-intelligence-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"
  ],
  "maxReviewsPerGame": 8,
  "maxResults": 10
}' |
apify call maydit/steam-game-intelligence-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/steam-game-intelligence-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/a6QAP6terwrvApVPq/builds/10QFkpMliGyQ5Bp1c/openapi.json
