# Steam Games Sale Prices Scraper (`automation-lab/steam-game-sale-price-tracker`) Actor

Track regional Steam regular prices, sale prices, discounts, platforms, and timestamped source URLs by game search, app ID, or app URL.

- **URL**: https://apify.com/automation-lab/steam-game-sale-price-tracker.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **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/platform/actors/running/actors-in-store#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 Games Sale Prices Scraper

Extract current **steam games sale prices** for searches, exact app IDs, or Steam store app URLs. Each observation includes the regional regular price, current price, discount percentage, currency, platforms, image, source URL, and collection timestamp.

Use scheduled runs to maintain deal feeds, monitor a wishlist, compare regional storefront prices, or append price observations to a research warehouse. The Actor reads public Steam store JSON endpoints and needs no Steam login.

### What does this Steam price tracker do?

The Actor resolves two practical input routes:

1. Search Steam by game name or keyword.
2. Check exact Steam apps by numeric ID or app URL.

Search inputs return up to ten relevant Steam apps per query. Exact IDs are useful for stable watchlists. Both routes use the same regional and language settings and produce the same typed dataset record.

Set `onlyOnSale` to `true` when you want only active discounts. Leave it `false` to keep full-price observations as a baseline for later scheduled comparisons.

### Who is it for?

- Deal-site operators building a current Steam discount feed.
- Game publishers and analysts comparing public storefront prices.
- Wishlist owners monitoring a defined set of Steam app IDs.
- Data teams appending timestamped price observations to a warehouse.
- Automation builders sending discounted records to Slack, email, Sheets, or a webhook.

This Actor tracks Steam store app prices. For Counter-Strike marketplace item listings, use [CS2 Steam Market Price Tracker](https://apify.com/automation-lab/cs2-steam-market-price-tracker) instead.

### Why use this Actor?

- **Two input routes:** keyword discovery and exact app watchlists.
- **Regional observations:** choose the country used for currency, price, and availability.
- **Monitoring-ready output:** every row includes `appId`, canonical URL, and `scrapedAt`.
- **Explicit sale state:** regular price, current price, discount percentage, and `isOnSale` are separate fields.
- **Lightweight execution:** public structured endpoints, no browser, login, or proxy configuration.
- **Typed exports:** use the dataset in JSON, CSV, Excel, XML, RSS, or integrations.

### What data can I extract?

| Field | Meaning |
| --- | --- |
| `appId` | Stable Steam application ID |
| `name` | Localized app or game name |
| `appType` | Steam item type such as `game` or `dlc` |
| `storeUrl` | Canonical timestampable source URL |
| `sourceInput` | Search query or app ID that produced the row |
| `sourceType` | `search` or `appId` |
| `searchRank` | One-based result position for search inputs |
| `country` | Country code used for the observation |
| `language` | Steam language used for metadata |
| `currency` | Currency returned by Steam |
| `regularPrice` | Undiscounted price in major currency units |
| `salePrice` | Current checkout price in major currency units |
| `discountPercent` | Current discount percentage, or zero |
| `isOnSale` | Whether a lower sale price is active |
| `isFree` | Whether Steam marks the app free to play |
| `platforms` | Windows, macOS, and Linux availability |
| `genres` | Localized genre labels |
| `releaseDate` | Localized Steam release-date text |
| `imageUrl` | Steam-hosted app image |
| `scrapedAt` | UTC observation timestamp |

Price fields can be `null` for unavailable apps, demos, free products, or store entries without a regional price.

### Getting started

1. Open the Actor input page.
2. Enter at least one `searchQueries` value or one `appIds` value.
3. Choose a two-letter `country`, such as `US`, `GB`, or `DE`.
4. Keep `onlyOnSale` off for baseline observations, or enable it for a deal-only feed.
5. Set `maxItems` to bound the dataset size.
6. Click **Start**.
7. Open the **Dataset** tab to preview or export records.

A safe first run is:

```json
{
  "appIds": ["620", "1091500"],
  "country": "US",
  "language": "english",
  "onlyOnSale": false,
  "maxItems": 2
}
```

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `searchQueries` | string\[] | `[]` | Names or keywords sent to Steam search |
| `appIds` | string\[] | `[]` | Numeric app IDs or Steam app URLs |
| `country` | string | `US` | Two-letter regional storefront country |
| `language` | string | `english` | Steam language name |
| `onlyOnSale` | boolean | `false` | Keep only active discounted apps |
| `maxItems` | integer | `50` | Maximum unique output rows, from 1 to 500 |

Duplicate apps are emitted once per run. Exact app IDs are processed before search results, so a watchlist remains prioritized when `maxItems` is small.

### Search Steam games

Use broad or title-specific searches:

```json
{
  "searchQueries": ["strategy games", "co-op games"],
  "country": "US",
  "language": "english",
  "maxItems": 15
}
```

Steam currently returns up to ten relevant items from its structured search response for each query. This Actor does not claim exhaustive catalog search pagination.

### Track an exact Steam watchlist

Exact IDs are more stable than titles for recurring schedules:

```json
{
  "appIds": [
    "620",
    "1091500",
    "https://store.steampowered.com/app/1245620/ELDEN_RING/"
  ],
  "country": "US",
  "maxItems": 3
}
```

Steam app URLs are normalized to their numeric IDs. Invalid IDs or non-Steam URLs fail fast instead of producing misleading empty rows.

### Output example

A current full-price observation has this shape:

```json
{
  "appId": 620,
  "name": "Portal 2",
  "appType": "game",
  "storeUrl": "https://store.steampowered.com/app/620/",
  "sourceInput": "Portal",
  "sourceType": "search",
  "searchRank": 1,
  "country": "US",
  "language": "english",
  "currency": "USD",
  "regularPrice": 9.99,
  "salePrice": 9.99,
  "regularPriceFormatted": "$9.99",
  "salePriceFormatted": "$9.99",
  "discountPercent": 0,
  "isOnSale": false,
  "isFree": false,
  "platforms": ["Windows", "Linux"],
  "genres": ["Action", "Adventure"],
  "releaseDate": "Apr 18, 2011",
  "imageUrl": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/620/header.jpg",
  "scrapedAt": "2026-08-13T12:00:00.000Z"
}
```

Steam can change prices at any time. Treat `scrapedAt`, `country`, and `currency` as part of every observation.

### How much does it cost to track Steam game prices?

Pricing uses one `start` event per run plus one `item` event for each saved app. Filtered, duplicate, unavailable, and failed records are not charged as items.

The current source configuration defines a **$0.0005 start event**. Item prices decrease by subscription tier; the BRONZE item price is **$0.0016118 per saved app**. At BRONZE, before platform subscription allowances:

- 10 saved apps: about $0.0166 total.
- 50 saved apps: about $0.0811 total.
- 100 saved apps: about $0.1617 total.

Apify displays the active tier and final estimated charge before a run. Steam endpoint behavior and the selected item count can affect runtime, but not the number of item events: one accepted dataset row equals one `item` event.

### Schedule price tracking

Apify schedules can run the same input hourly, daily, or weekly. For a stable monitoring workflow:

1. Store exact IDs in `appIds`.
2. Keep country and language unchanged between observations.
3. Leave `onlyOnSale` off if your downstream system needs full-price baselines.
4. Append each dataset to a warehouse keyed by `appId` and `scrapedAt`.
5. Compare the newest `salePrice` and `discountPercent` with the prior row.

The Actor reports current observations; it does not persist history or send alerts itself. Use Apify integrations, webhooks, or your own pipeline for comparison and notification.

### Export to Sheets or a data pipeline

From the Dataset tab, export JSON, CSV, Excel, XML, or RSS. You can also:

- Connect a Google Sheets integration after successful runs.
- Trigger a webhook when a scheduled run finishes.
- Pull dataset items into BigQuery, Snowflake, PostgreSQL, or a lake.
- Filter `isOnSale = true` downstream for a current deal feed.
- Join on `appId` to compare countries from separate runs.

Run one country per Actor execution so the regional context remains unambiguous.

### Use the Apify API

Replace `APIFY_TOKEN` with your token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~steam-game-sale-price-tracker/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"appIds":["620","1091500"],"country":"US","maxItems":2}'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/steam-game-sale-price-tracker').call({
  searchQueries: ['strategy games'],
  country: 'US',
  onlyOnSale: false,
  maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token="APIFY_TOKEN")
run = client.actor("automation-lab/steam-game-sale-price-tracker").call(run_input={
    "appIds": ["620", "1091500"],
    "country": "US",
    "maxItems": 2,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Actor to Claude Code through Apify MCP:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/steam-game-sale-price-tracker"
```

#### Claude Desktop

Add this server in Claude Desktop's MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/steam-game-sale-price-tracker"
    }
  }
}
```

#### Cursor

Add the same `mcpServers.apify` entry to Cursor's MCP settings.

#### VS Code

Add the same Apify MCP URL through your VS Code MCP extension or workspace MCP configuration.

Example prompts:

- “Check these Steam app IDs in the US store and return current discounts.”
- “Search Steam for co-op games and export a spreadsheet-ready price table.”
- “Run my Steam watchlist for Great Britain and show only active sales.”

### Limits and freshness

- Results are a snapshot of public Steam data at run time, not historical prices.
- Search returns the current bounded Steam search response, up to ten apps per query.
- Regional availability can differ; an app may be unavailable in the selected country.
- Steam may omit price data for free apps, demos, unreleased products, or bundles.
- `onlyOnSale` can legitimately return zero rows when none of the resolved apps is discounted.
- Store titles, release dates, genres, and formatted prices follow the selected Steam language.
- The Actor does not access wishlists or account-specific data and does not require login.

### Reliability and retries

Transient network failures, HTTP 429 responses, and temporary Steam 5xx responses are retried up to three times with backoff. Stable invalid input and unavailable apps are not retried blindly.

For large watchlists, split IDs across scheduled runs if Steam begins rate-limiting. The implementation intentionally uses conservative sequential detail requests and 256 MB memory.

### Legality and responsible use

The Actor accesses public Steam store endpoints. You are responsible for complying with Steam terms, Apify policies, and laws that apply to your use case. Do not use output to misrepresent Steam, Valve, publishers, or regional offers.

Prices and discounts can change between observation and purchase. Always link users to the canonical `storeUrl` and let Steam present the final current checkout terms.

### Troubleshooting

#### Why did a run return no rows?

Confirm that at least one query or app ID is supplied. If `onlyOnSale` is enabled, the resolved apps may not currently be discounted. Disable the filter to inspect baseline observations.

#### Why is a price null?

The selected country may not offer the app, or Steam may classify it as free, unreleased, a demo, or an item without a standard price. Try the canonical app page in the same regional context.

#### Why does search not return every matching game?

Steam's structured search surface returns a bounded set of relevant apps. Use exact app IDs for complete watchlists and stable scheduled monitoring.

#### Can I compare countries in one run?

A run has one country setting. Run the Actor once per country and join records by `appId` in your pipeline so each observation has clear regional context.

### Related Automation Lab Actors

- [Steam Scraper](https://apify.com/automation-lab/steam-scraper) — broader Steam search metadata and reviews.
- [CS2 Steam Market Price Tracker](https://apify.com/automation-lab/cs2-steam-market-price-tracker) — Counter-Strike marketplace items rather than game store apps.
- [Steam Workshop Scraper](https://apify.com/automation-lab/steam-workshop-scraper) — public Workshop projects and metadata.

### FAQ

#### Does it require a Steam API key?

No. It uses public Steam store JSON responses and requires no Steam account.

#### Does it store price history?

No. Each row is a timestamped current observation. Schedule runs and persist datasets in your destination to build history.

#### Can it monitor a wishlist?

Yes, if you provide the wishlist's public app IDs as `appIds`. The Actor does not log in or read private wishlist pages.

#### Are sale prices guaranteed at checkout?

No. Steam prices and availability can change. The dataset records what Steam returned at `scrapedAt`; users should verify the linked store page.

#### What counts as a charged item?

One accepted row saved to the default dataset. Duplicates, filtered full-price apps, unavailable apps, and request failures do not produce item charges.

# Actor input Schema

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

Steam game names or keywords. Steam returns up to 10 relevant apps per query.

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

Exact numeric Steam app IDs or store app URLs to track, such as 620 or https://store.steampowered.com/app/620/Portal\_2/.

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

Two-letter country code used by Steam for regional availability, currency, and prices.

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

Steam language name used for localized titles and metadata.

## `onlyOnSale` (type: `boolean`):

When enabled, omit full-price and free games so the dataset contains active discounts only.

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

Maximum unique Steam apps saved across all searches and app IDs.

## Actor input object example

```json
{
  "searchQueries": [
    "strategy games"
  ],
  "appIds": [
    "620",
    "1091500"
  ],
  "country": "US",
  "language": "english",
  "onlyOnSale": false,
  "maxItems": 15
}
```

# Actor output Schema

## `dataset` (type: `string`):

Default dataset containing all accepted Steam app price observations.

# 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 = {
    "searchQueries": [
        "strategy games"
    ],
    "appIds": [
        "620",
        "1091500"
    ],
    "country": "US",
    "language": "english",
    "onlyOnSale": false,
    "maxItems": 15
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/steam-game-sale-price-tracker").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 = {
    "searchQueries": ["strategy games"],
    "appIds": [
        "620",
        "1091500",
    ],
    "country": "US",
    "language": "english",
    "onlyOnSale": False,
    "maxItems": 15,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/steam-game-sale-price-tracker").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 '{
  "searchQueries": [
    "strategy games"
  ],
  "appIds": [
    "620",
    "1091500"
  ],
  "country": "US",
  "language": "english",
  "onlyOnSale": false,
  "maxItems": 15
}' |
apify call automation-lab/steam-game-sale-price-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/steam-game-sale-price-tracker"
        }
    }
}

```

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/ao7JstL1YltafLCyL/builds/j33e1RFU6pWwGI0xA/openapi.json
