# Steam Game Pricing & Metacritic Scraper (`vexaloom-labs/steam-game-pricing-and-metacritic-scraper`) Actor

Browse Steam's featured and top-selling games, search by keyword, or look up specific games by App ID. Get price, discount, Metacritic score, genres, categories, platforms, and release date for each game.

- **URL**: https://apify.com/vexaloom-labs/steam-game-pricing-and-metacritic-scraper.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 Game Pricing & Metacritic Scraper

Steam's storefront is a catalog, a chart board, and a price list at the same time. This actor reads those public surfaces without a login, API key, cookie, or proxy setup, and returns one clean record per app: localized price and discount, Metacritic score, review totals, community tags, media, DLC, platforms, and release information.

### Five ways to build a dataset

| Mode | What it does |
|---|---|
| `search` | Matches one or more keywords against Steam's own store search and pages through the results. |
| `browse` | Walks a chart: top sellers, new releases, current specials, coming soon, weeklong deals, popular new releases, or the legacy featured mix. |
| `appDetail` | Looks up numeric App IDs, or store URLs pasted into the App ID field. |
| `urls` | Accepts full `store.steampowered.com/app/<id>/` URLs and resolves each one. |
| `featured` | Keeps the old behavior: top sellers, new releases, specials, and coming soon, in that order. |

Search and chart modes paginate through Steam's 50-result pages until `maxItems` is reached or the source runs out. Every record is deduplicated by App ID, so overlapping queries and chart pages do not create duplicates.

### What lands in each record

- **Identity** — `appId`, `appName`, `appType`, `appUrl`, `recordType`, `scrapedAt`
- **People** — `developer`, `publisher`, plus `developers[]` and `publishers[]`
- **Pricing** — `currentPrice`, `originalPrice`, `priceCurrency`, `priceInitialCents`, `priceFinalCents`, `discountPercent`, `isDiscounted`, `isFree`, `packages[]`, `packageOptions[]`
- **Critical reception** — `metacriticScore`, `metacriticUrl`, `recommendationsTotal`, `pressQuotes[]`
- **User reviews** — `reviewScore`, `reviewScoreDesc`, `totalReviews`, `totalPositive`, `totalNegative`, `positiveReviewPercent`
- **Classification** — `genres[]`, `categories[]`, `tags[]`, `controllerSupport`, `requiredAge`, `contentDescriptors[]`, `platforms`
- **Release** — `releaseDate`, `releaseDateIso`, `comingSoon`
- **Content** — `shortDescription`, `detailedDescription`, `website`, `supportedLanguages`
- **Media** — `headerImage`, `capsuleImage`, `capsuleImageV5`, `backgroundImage`, `backgroundRawImage`, `screenshots[]`, `screenshotThumbnails[]`, `movies[]`
- **Extras** — `achievementsTotal`, `dlcAppIds[]`, `dlc[]`, `supportUrl`, `supportEmail`

Steam does not publish every field for every app. Missing values are omitted from the record rather than written as `null`, `""`, or a made-up placeholder.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `mode` | select | `search` | `search`, `browse`, `appDetail`, `urls`, or `featured`. |
| `searchQueries` | string list | `["adventure"]` | One or more keywords for `search`. |
| `browseCategory` | select | `topSellers` | Chart used by `browse`; also `newReleases`, `specials`, `comingSoon`, `weeklongDeals`, `popularNew`, `featuredMix`. |
| `appIds` | string list | – | Numeric IDs or store URLs for `appDetail`. |
| `storeUrls` | string list | – | Full store URLs for `urls`. |
| `appTypeFilter` | select | `all` | Keep only `game`, `dlc`, `demo`, or `software`. |
| `sortBy` | select | `relevance` | `released`, `priceAsc`, `priceDesc`, `reviews`, `metacritic`, or `nameAsc`. |
| `onlyDiscounted` | boolean | `false` | Drop records that are not on sale. |
| `minDiscount` | integer | `0` | Minimum discount percentage (0–100). |
| `maxPrice` | number | – | Maximum final price in the storefront currency. |
| `minMetacritic` | integer | `0` | Minimum Metacritic score (0–100). |
| `country` | text | `us` | Two-letter Steam store country, e.g. `us`, `gb`, `de`, `ca`. Controls currency. |
| `language` | select | `english` | Steam store language for names, descriptions, and store-page text. |
| `includeTags` | boolean | `true` | Read the public store page for community tags and DLC names. |
| `includeReviewSummary` | boolean | `true` | Add Steam's positive/negative review totals and label. |
| `maxItems` | integer | `20` | Stop after this many saved records (1–1000). |

#### Daily test / smallest useful run

```json
{
  "mode": "search",
  "searchQueries": ["Hades"],
  "maxItems": 1,
  "includeTags": false,
  "includeReviewSummary": false
}
```

#### Browse current specials, deep discounts only

```json
{
  "mode": "browse",
  "browseCategory": "specials",
  "onlyDiscounted": true,
  "minDiscount": 50,
  "maxPrice": 20,
  "maxItems": 25
}
```

#### Look up specific games

```json
{
  "mode": "appDetail",
  "appIds": ["1245620", "570", "730"],
  "maxItems": 3
}
```

#### Localized prices from pasted URLs

```json
{
  "mode": "urls",
  "storeUrls": [
    "https://store.steampowered.com/app/1245620/",
    "https://store.steampowered.com/app/1091500/"
  ],
  "country": "de",
  "language": "german",
  "maxItems": 2
}
```

### Compatibility with saved tasks

Older tasks keep working. The actor still reads the former input keys and maps them in code:

- `searchQuery` → `searchQueries`
- `appId` → `appIds`
- `urls` / `startUrls` → `storeUrls`
- `appType` → `appTypeFilter` (including the old empty-string value, which means `all`)
- `mode: "featured"` → the featured top sellers / new releases / specials / coming soon mix

The current production prefill (`mode=featured`, `searchQuery=adventure`, `maxItems=20`) still runs and returns records.

### FAQ

**Do I need a Steam account, API key, cookie, or proxy?**
No. The actor reads Steam's public store endpoints and product pages. No credentials are required and no proxy configuration is needed.

**Why is `metacriticScore` missing for some games?**
Steam only publishes a Metacritic score for a subset of titles. When the store has no score, the field is omitted.

**Why is `discountPercent` missing on a game that is on sale?**
The field is written only when Steam reports a non-zero discount at the moment of the run. A zero discount is not treated as a sale.

**Why do prices differ from my region?**
Steam localizes prices by store country. Set `country` to the storefront you want; `priceCurrency` and the formatted price follow that storefront.

**What is the difference between `tags` and `genres`?**
`genres` and `categories` come from Steam's app metadata. `tags` are the community tags shown on the public store page, capped at the 20 Steam displays.

**How fresh is the data?**
Every run reads Steam live. Prices, discounts, chart positions, review totals, and tags reflect the moment the actor runs.

**Are review numbers the same as Metacritic?**
No. `reviewScore` and the review totals are Steam user reviews. `metacriticScore` is the critic score Steam displays from Metacritic.

**Can I get more than 50 results from a chart?**
Yes. Search and chart modes page through 50-result pages up to `maxItems` (maximum 1000) or until the chart/search is exhausted. Steam's featured new-releases block is a fixed 30-item list, and the featured mix is a fixed set of featured blocks; those are source limits, not pagination bugs.

### Data source

Public Steam Store pages: `store.steampowered.com/api/appdetails`, `featuredcategories`, `search/results`, the product page, and `ajaxappreviews`. The actor is independent and not affiliated with Valve or Steam.

# Actor input Schema

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

Choose how to find games: keyword search, a Steam chart, specific App IDs, or pasted store URLs.

## `searchQueries` (type: `array`):

One or more game names or keywords. Used when mode is Search by keyword.

## `browseCategory` (type: `string`):

Which storefront chart to browse. Used when mode is Browse a Steam chart.

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

Numeric App IDs or store URLs, one per line. Used when mode is Look up App IDs.

## `storeUrls` (type: `array`):

Full store URLs, one per line. Used when mode is Paste store URLs.

## `appTypeFilter` (type: `string`):

Keep only games, DLC, demos, or software. 'All' keeps every app type Steam returns.

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

How Steam should order search and chart results before filtering.

## `onlyDiscounted` (type: `boolean`):

Drop records that are not currently on sale.

## `minDiscount` (type: `integer`):

Keep records whose discount is at least this percentage. 0 disables the filter.

## `maxPrice` (type: `number`):

Keep records whose final price is at or below this amount in the storefront currency. Leave empty for no limit.

## `minMetacritic` (type: `integer`):

Keep records with a Metacritic score at or above this value. 0 disables the filter.

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

Two-letter Steam store country code, e.g. us, gb, de, ca. Controls currency and regional availability.

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

Language Steam uses for app names, descriptions, and store-page text.

## `includeTags` (type: `boolean`):

Read the public store page for its community tags and DLC names. Adds one request per record.

## `includeReviewSummary` (type: `boolean`):

Add Steam's positive/negative review totals and review label. Adds one request per record.

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

Stop after this many records have been saved.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "Hades"
  ],
  "browseCategory": "topSellers",
  "appIds": [
    "1245620"
  ],
  "storeUrls": [
    "https://store.steampowered.com/app/570/"
  ],
  "appTypeFilter": "all",
  "sortBy": "relevance",
  "onlyDiscounted": false,
  "minDiscount": 0,
  "minMetacritic": 0,
  "country": "us",
  "language": "english",
  "includeTags": false,
  "includeReviewSummary": false,
  "maxItems": 1
}
```

# Actor output Schema

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

All scraped Steam store records.

# 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": "search",
    "searchQueries": [
        "Hades"
    ],
    "browseCategory": "topSellers",
    "appIds": [
        "1245620"
    ],
    "storeUrls": [
        "https://store.steampowered.com/app/570/"
    ],
    "appTypeFilter": "all",
    "sortBy": "relevance",
    "onlyDiscounted": false,
    "minDiscount": 0,
    "minMetacritic": 0,
    "country": "us",
    "language": "english",
    "includeTags": false,
    "includeReviewSummary": false,
    "maxItems": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/steam-game-pricing-and-metacritic-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": "search",
    "searchQueries": ["Hades"],
    "browseCategory": "topSellers",
    "appIds": ["1245620"],
    "storeUrls": ["https://store.steampowered.com/app/570/"],
    "appTypeFilter": "all",
    "sortBy": "relevance",
    "onlyDiscounted": False,
    "minDiscount": 0,
    "minMetacritic": 0,
    "country": "us",
    "language": "english",
    "includeTags": False,
    "includeReviewSummary": False,
    "maxItems": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/steam-game-pricing-and-metacritic-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": "search",
  "searchQueries": [
    "Hades"
  ],
  "browseCategory": "topSellers",
  "appIds": [
    "1245620"
  ],
  "storeUrls": [
    "https://store.steampowered.com/app/570/"
  ],
  "appTypeFilter": "all",
  "sortBy": "relevance",
  "onlyDiscounted": false,
  "minDiscount": 0,
  "minMetacritic": 0,
  "country": "us",
  "language": "english",
  "includeTags": false,
  "includeReviewSummary": false,
  "maxItems": 1
}' |
apify call vexaloom-labs/steam-game-pricing-and-metacritic-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vexaloom-labs/steam-game-pricing-and-metacritic-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/OES3JKkI5b2ZDKZB9/builds/OXfVT16eHbhbNWgJb/openapi.json
