# Steam Store Scraper (`axiomworks/steam-store-scraper`) Actor

Get structured data for Steam games and other apps from charts, keyword searches, or a list of app IDs. Each record can include descriptions, genres, tags, regional price details, review totals, and optional recent reviews. Chart and search results can include rank.

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

## Pricing

from $0.35 / 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

## Steam Store Scraper

**Returns:** one row per Steam app with title, appType, genres, tags, pricesByRegion, reviewScoreDesc, platforms, pcRequirements.
**Input:** `{"mode": "specials", "countries": ["us", "gb"], "maxItems": 10}`
**Best for:** price monitoring, release calendars, game market research.

```json
{"id": "730", "title": "Counter-Strike 2", "appType": "game", "isFree": true, "platforms": ["windows", "linux"], "requiredAge": 0, "reviewScoreDesc": "Very Positive", "website": "http://counter-strike.net/"}
```

### What does Steam Store Scraper do?

Steam Store Scraper collects public Steam app information. It can start from the current top sellers list, the new releases list, a keyword search, or a list of known Steam app IDs and URLs. For every app that Steam returns, the Actor requests the public app details JSON endpoint and produces one record with a stable Steam app ID. It can also request regional prices for your chosen country codes, review totals, and recent review text.

For example, a catalog analyst can compare the listed price of the same app in several storefront regions, while a researcher can follow the current top sellers chart and preserve the app IDs and rank in a dataset. All records retain the public Steam app page in `sourceUrl` so that you can inspect a result in context.

Each run reflects current public Steam data. It needs no login and is not affiliated with Valve or Steam.

### What data can you get?

The dataset has one item per unique Steam app ID. Most fields come from Steam's app details endpoint. Rank comes from search rows; ID-only runs have no rank and read tags from app pages. Search mode supports non-English keywords. Review summary fields come from Steam's public review endpoint. Recent review objects appear only when `includeReviews` is enabled. Some titles omit optional fields, and a regional price can be unavailable for a free game, an unreleased game, or a region where Steam does not expose a price.

| Field | Meaning |
| --- | --- |
| `id` | Stable numeric Steam app ID, represented as a string. |
| `sourceUrl` | Public Steam app page for this ID. |
| `title` | App name returned by Steam. |
| `appType` | Steam app classification such as game or software. |
| `isFree` | Whether Steam marks the app free. |
| `developers` | Names in the Steam developer list. |
| `publishers` | Names in the Steam publisher list. |
| `releaseDate` | Release date as displayed by Steam. |
| `releaseDateIso` | Release date as YYYY-MM-DD when Steam gives an exact date in either month-first or day-first English format, otherwise null. |
| `shortDescription` | Steam's short description text. |
| `genres` | Genre names from the app details response. |
| `tags` | Popular tag names attached to a chart or search row. |
| `headerImage` | Header image URL from app details. |
| `pricesByRegion` | Country-code keys with price and currency details, or `null` where no price is returned. |
| `reviewScoreDesc` | Steam's summary wording for the review score. |
| `totalPositive` | Positive review count returned by the review summary. |
| `totalNegative` | Negative review count returned by the review summary. |
| `rank` | One-based position in the chosen chart or search results, when applicable. |
| `metacriticScore` | Metacritic score when included in Steam app details. |
| `reviews` | Recent review ID, text, vote direction, and creation timestamp when requested. |
| `marketSegment` | Optional AI classification of market positioning. |
| `platforms` | Supported platforms (windows, mac, linux). |
| `categories` | Steam feature categories such as Single-player. |
| `supportedLanguages` | Languages listed on the store page. |
| `requiredAge` | Minimum age required. |
| `website` | Official game website. |
| `screenshots` | Up to 10 full-size screenshot URLs. |
| `dlcAppIds` | App IDs of DLC. |
| `recommendationsTotal` | Total user recommendations. |
| `comingSoon` | True if the game is not yet released. |
| `pcRequirements` | Windows minimum and recommended system requirements as original Steam HTML. |
| `macRequirements` | macOS requirements as original Steam HTML, or null. |
| `linuxRequirements` | Linux requirements as original Steam HTML, or null. |
| `achievementsTotal` | Total Steam achievements when published, otherwise null. |

`pricesByRegion` keeps numeric `initial` and `final` price values in Steam's minor currency units, the returned `currency`, `discountPercent`, and the store's `formatted` display text. A `null` region value means the endpoint did not provide a `price_overview`; it should not be read as a zero amount. Free status is reported separately in `isFree`.

System requirements contain `minimum` and `recommended` keys, each nullable. Their values preserve Steam HTML, including lists and emphasis; sanitize it before rendering. Empty requirements objects become null. `achievementsTotal` is the published count, not player achievement progress. These fields reuse the app details response without extra requests.

### How to use

Choose a mode first. `topSellers`, `newReleases`, `specials` and `comingSoon` scan Steam's corresponding search chart. `search` uses `searchTerm` as a keyword phrase. `appDetails` accepts numeric IDs in `appIds`, app URLs in `startUrls`, or both. IDs repeated within the same input are emitted once. For chart and search modes, the Actor walks result pages in steps of 50 until it has enough distinct candidates or Steam reports the end of the results.

Set `maxItems` to the number of app records you need. The Actor stops pushing records at that limit. If Steam does not return enough valid apps, a run may have fewer records. The limit applies to output items, not to the number of requests: additional public requests are needed for app details, each selected region, and reviews. Choose a short country list for a quick chart snapshot, and add more regions when you need a broader comparison.

Review summaries are collected for every item because they make the overall score and review totals useful. Set `includeReviews` to true to collect review text as well. `maxReviewsPerGame` bounds the review objects attached to each app; it does not change the number of app records. If the review endpoint is temporarily unavailable, other app fields can still be returned. When a request is blocked or throttled, the Actor waits and tries a new proxy session. It logs a warning for an app that cannot be read, then continues to the next candidate.

The optional `marketSegment` is only produced when you set `enrichWithAI` to true; otherwise it is `null`. It uses a third-party AI processor, TypeSafe Jev, to classify the app from its short description, tags, and price. The value is one of `AAA`, `AA`, `indie`, `hobbyist/low-effort`, or `free-to-play live service`. It is an analytical judgment rather than a Steam field. If enrichment is unavailable or fails, the field is `null` and the ordinary record is still returned. The Actor caps Jev requests per run.

### Input

| Input | Description | Default |
| --- | --- | --- |
| `mode` | Select `topSellers`, `newReleases`, `specials` (discounted games), `comingSoon` (upcoming releases), `search`, or `appDetails`. | `topSellers` |
| `appIds` | Numeric Steam app IDs for `appDetails`. | Empty |
| `startUrls` | Steam app URLs for `appDetails`. | Empty |
| `searchTerm` | Keyword phrase required for `search`. | Empty |
| `countries` | One to ten two-letter storefront country codes. | `us`, `gb`, `de` |
| `includeReviews` | Include recent review text per app. | `false` |
| `maxReviewsPerGame` | Review objects per app, from 0 to 100. | `20` |
| `enrichWithAI` | Add an AI market segment to each app; costs extra per enriched result. | `false` |
| `maxItems` | Maximum output app records, from 1 to 1000. | `50` |
| `proxyConfiguration` | Apify proxy settings for requests to Steam. | Apify datacenter proxy |

For a small comparison of known apps, enter an input like this:

```json
{
  "mode": "appDetails",
  "appIds": ["730", "570", "1091500"],
  "countries": ["us", "br", "jp"],
  "includeReviews": false,
  "maxItems": 3
}
```

In a search run, set `mode` to `search` and provide `searchTerm`. A nonsense phrase can produce an empty dataset and a warning. A dead or malformed app URL fails with an input error or is skipped if Steam has no corresponding app details. The Actor never adds error objects to the dataset. If you supply both `appIds` and `startUrls`, their app IDs are combined in the order provided.

### Output

Here is a real item from a local appDetails run. This excerpt shows the shape of the record; the live dataset also carries the remaining fields in the table above. Values can change between runs as the Steam Store changes.

```json
{
  "id": "620",
  "sourceUrl": "https://store.steampowered.com/app/620/",
  "title": "Portal 2",
  "appType": "game",
  "isFree": false,
  "platforms": [
    "windows",
    "linux"
  ],
  "achievementsTotal": 51,
  "pcRequirements": {
    "minimum": "<strong>Minimum:</strong><br><ul class=\"bb_ul\"><li><strong>OS *:</strong> Windows 7 / Vista / XP<br></li><li><strong>Processor:</strong> 3.0 GHz P4, Dual Core 2.0 (or higher) or AMD64X2 (or higher)<br></li><li><strong>Memory:</strong> 2 GB RAM<br></li><li><strong>Graphics:</strong> Video card must be 128 MB or more and with support for Pixel Shader 2.0b (ATI Radeon X800 or higher / NVIDIA GeForce 7600 or higher / Intel HD Graphics 2000 or higher).<br></li><li><strong>DirectX:</strong> Version 9.0c<br></li><li><strong>Storage:</strong> 8 GB available space<br></li><li><strong>Sound Card:</strong> DirectX 9.0c compatible</li></ul>",
    "recommended": null
  }
}
```

The `id` is a stable join key across runs. `rank` is a position in that run's list. `reviews` is empty because review text was disabled.

The dataset is plain JSON and exports to CSV or spreadsheets through Apify.

### How much does it cost?

The Actor is charged per result record. Market segment enrichment is off by default. When you turn on `enrichWithAI`, it has its own event and is charged only when that field was actually produced. Opening the Pricing tab on the Actor page shows the current terms. A run with zero records has no result records to charge. `maxItems` is the simplest way to cap the number of output records for a run.

The number of HTTP requests is not the number of result events. One app can involve its details request, regional price lookups, and a review request, while still producing one result record. When the Actor skips an unavailable app, it does not push a placeholder item. The dataset and run log show what was produced.

### Use with AI agents (MCP)

You can make this Actor available as a tool through Apify MCP. Configure an MCP server URL with the Store path in the `tools` parameter:

```text
https://mcp.apify.com/?tools=axiomworks/steam-store-scraper
```

An agent can ask for a bounded chart snapshot, a specific app comparison, or a keyword search. Give the agent the mode, target IDs or phrase when relevant, country codes, and an item limit. Example prompts include “Collect the first ten Steam top sellers and show their titles, genres, and US and GB prices” and “Compare the Steam Store details for app IDs 730 and 570 in US and JP regions.” A search prompt can say “Find up to fifteen Steam apps for the phrase tactical strategy and include review score descriptions.”

The MCP tool presents the input descriptions and the output schema. Values such as `marketSegment` are judgments by a third-party AI processor, so treat them as optional classifications. If you need exact public fields, ask the agent to use `title`, `appType`, `releaseDate`, `pricesByRegion`, and the review totals as returned. The stable `id` helps your agent merge records from separate runs without relying on names, which can change or collide.

### Integrations and API

Apify stores results in the run's default dataset. You can use scheduled runs for repeated snapshots and retrieve dataset items in your application. Keep API tokens in your environment.

Python:

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("axiomworks/steam-store-scraper").call(run_input={"mode": "topSellers", "maxItems": 10})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/steam-store-scraper').call({ mode: 'topSellers', maxItems: 10 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

cURL:

```bash
curl -X POST 'https://api.apify.com/v2/acts/axiomworks~steam-store-scraper/run-sync-get-dataset-items' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"mode":"topSellers","maxItems":10}'
```

If you need to compare snapshots over time, save each run's creation time alongside its dataset and join items on `id`. For regional analysis, keep the country code, currency, formatted display text, and numeric price together. For review analysis, distinguish Steam's aggregate `totalPositive` and `totalNegative` from the small sample of recent `reviews` requested in a run.

### FAQ

**Can I pass a Steam app URL?** Yes. Use `appDetails` mode and put it in `startUrls`. The Actor extracts the numeric ID from a public `store.steampowered.com/app/...` URL. Other URL shapes are rejected so that a typo does not silently fetch a different site.

**Where do tags come from?** Chart and search runs use Steam's tag map. ID-only runs read tags from the public app page; unavailable tags remain empty.

**Why is a regional price null?** Steam may not provide `price_overview` for an app in a given country. This is common for free apps and can also happen with availability or release status. Read `isFree` and `releaseDate` separately rather than treating missing price data as free.

**Are the review totals the same as the returned review list?** No. The totals describe Steam's aggregate summary. The `reviews` array contains at most `maxReviewsPerGame` recent review objects when enabled. It is a sample and should not be used to recompute the total score.

**Can I request more than one country?** Yes. Supply two-letter country codes in `countries`, up to ten. Each app record gets one key per requested code in `pricesByRegion`. The Actor does not convert values between currencies.

**Does an empty search create items?** No. The Actor warns that the search returned no results and completes with an empty dataset. It does not add an artificial record describing the error.

### Is it legal to scrape Steam?

This Actor reads public Steam Store endpoints without a login. Whether a particular use is permitted depends on your jurisdiction, Steam's current terms, and what you do with the data. Consider request volume, attribution, rights in descriptions and images, and any restrictions that apply to your project. This documentation is practical product guidance, not legal advice. The Actor uses modest request pacing and backs off when the public endpoint throttles or blocks a request.

The returned descriptions, images, and reviews can have rights held by Valve, publishers, or users. Receiving a field through an API does not transfer those rights. If you publish or redistribute the collected material, assess those rights for your use case. For analytics, keep the app ID and source URL with the copied fields so you can trace where they came from and review changes later.

### Feedback

Use the Apify Actor page to report a failed run, an unexpected field value, or a missing Steam app. Include the input mode, app ID or search phrase, country codes, and the relevant log lines. A concrete app ID and field name make a data issue easier to reproduce. Steam can change its endpoint responses, so examples from a recent run are helpful when reporting a change.

# Actor input Schema

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

Which Steam list to scrape. topSellers (default), newReleases, specials (discounted), comingSoon (upcoming) need no other field. search requires searchTerm. appDetails requires appIds or startUrls. Example: 'topSellers'. Unknown modes fail the run.

## `startUrls` (type: `array`):

Steam app page URLs, used only when mode is appDetails; combined with appIds. Format: https://store.steampowered.com/app/<numeric id>/, e.g. {"url": "https://store.steampowered.com/app/730/"}. Other URLs fail the run. Unknown apps are skipped.

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

Numeric Steam app IDs as strings, used only when mode is appDetails; combined with startUrls. Example: \["730", "570"]. Find the ID in the app page URL. Non-numeric values fail the run; IDs Steam does not know are skipped.

## `searchTerm` (type: `string`):

Keywords for Steam store search, used and required only when mode is search. Any language, e.g. 'strategy game' or 'ゾンビ'. No matches ends the run with 0 items and a message to change the term.

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

Maximum unique app records returned across the whole run (lists, search and all IDs share this budget), 1-1000, default 50. Example: 10. Each record is one result.

## `countries` (type: `array`):

Two-letter country codes for regional prices in pricesByRegion, 1-10 codes, e.g. \["us", "gb", "de"]. The first code also sets the storefront for lists and search. Default us, gb, de. Invalid codes fail the run.

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

If true, each record also gets recent review texts in the reviews array (up to maxReviewsPerGame). Review score summary fields are always returned. Slower when on. Default false.

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

Maximum review texts per app when includeReviews is true, 0-100, default 20. Ignored when includeReviews is false.

## `enrichWithAI` (type: `boolean`):

If true, adds marketSegment (AAA, AA, indie, hobbyist/low-effort, free-to-play live service) to each app using a third-party AI processor; billed as an extra event per enriched result. Default false.

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

Apify Proxy settings for requests to Steam. Default: Apify datacenter proxy. Blocked requests are retried on a fresh proxy session.

## Actor input object example

```json
{
  "mode": "topSellers",
  "startUrls": [
    {
      "url": "https://store.steampowered.com/app/730/"
    }
  ],
  "appIds": [
    "730",
    "570"
  ],
  "searchTerm": "strategy game",
  "maxItems": 10,
  "countries": [
    "us",
    "gb"
  ],
  "includeReviews": false,
  "maxReviewsPerGame": 3,
  "enrichWithAI": false,
  "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 = {
    "mode": "topSellers",
    "startUrls": [
        {
            "url": "https://store.steampowered.com/app/730/"
        }
    ],
    "appIds": [
        "730",
        "570"
    ],
    "searchTerm": "strategy game",
    "maxItems": 10,
    "countries": [
        "us",
        "gb"
    ],
    "includeReviews": false,
    "maxReviewsPerGame": 3,
    "enrichWithAI": false,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/steam-store-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 = {
    "mode": "topSellers",
    "startUrls": [{ "url": "https://store.steampowered.com/app/730/" }],
    "appIds": [
        "730",
        "570",
    ],
    "searchTerm": "strategy game",
    "maxItems": 10,
    "countries": [
        "us",
        "gb",
    ],
    "includeReviews": False,
    "maxReviewsPerGame": 3,
    "enrichWithAI": False,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/steam-store-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 '{
  "mode": "topSellers",
  "startUrls": [
    {
      "url": "https://store.steampowered.com/app/730/"
    }
  ],
  "appIds": [
    "730",
    "570"
  ],
  "searchTerm": "strategy game",
  "maxItems": 10,
  "countries": [
    "us",
    "gb"
  ],
  "includeReviews": false,
  "maxReviewsPerGame": 3,
  "enrichWithAI": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call axiomworks/steam-store-scraper --silent --output-dataset

```

## MCP server setup

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