# Steam Reviews Scraper | $0.85/1K + Changes (`luminar/steam-reviews-scraper-change-monitor`) Actor

Export public Steam game reviews with recommendations, playtime, helpfulness, purchase context, and developer responses. Track scoped new and updated reviews with stable keys.

- **URL**: https://apify.com/luminar/steam-reviews-scraper-change-monitor.md
- **Developed by:** [Luka](https://apify.com/luminar) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.81 / 1,000 steam review delivereds

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

Export public Steam reviews with the fields you need to understand player feedback: recommendation, language, playtime, purchase context, helpfulness, Early Access status, and developer response. Use stable review keys for database upserts, or repeat the same watch to receive included `NEW` and `UPDATED` records.

- Review text and public Steam context in one Dataset
- Source-aware pagination, filters, limits, and one coverage row per game
- Monitoring without false deletion alerts when a bounded window changes

### 🚀 Start in 60 seconds

1. Keep the prefilled Counter-Strike 2 App ID `730`, or paste your own Steam App IDs or public Store URLs.
2. Keep **Export current reviews** and the 100-review limit for the first run.
3. Set Apify maximum total charge to at least `$0.09` for the prefilled run.
4. Click **Start** and open the Dataset. Use `stableId` as the upsert key.

```json
{
  "workflow": "export",
  "games": ["730"],
  "reviewOrder": "recent",
  "language": "all",
  "recommendation": "all",
  "purchaseType": "all",
  "lookbackDays": 365,
  "includeOffTopicActivity": false,
  "maxReviewsPerGame": 100,
  "maxReviews": 100,
  "maxBuyerChargeUsd": 1,
  "maxRuntimeSecs": 60,
  "firstRunBehavior": "emit_current_as_new",
  "stateNamespace": "default"
}
```

### 🎯 Choose the right workflow

| Goal | Workflow | What is delivered |
|---|---|---|
| One-time export | `export` | Current verified reviews plus included coverage rows |
| First watch with current reviews marked NEW | `monitor` + `emit_current_as_new` | Current reviews, matching NEW rows, and coverage |
| Quiet baseline | `monitor` + `seed_only` | Current reviews and coverage; no initial change rows |
| Repeat watch | Same `monitor` input and watch name | Current reviews plus NEW or UPDATED rows inside the same scope |

Every monitoring scope includes the games, order, filters, limits, and watch name. On the next run, keep that complete scope unchanged. Change the watch name only when you intentionally want a fresh baseline.

### 📦 What you get

Each paid `review` row includes a stable Steam review identity, original review text, recommendation, timestamps, language, playtime, purchase/free/Early Access flags, vote counts, public reviewer identity, review URL, game URL, and developer response when Steam publishes one. `change` and `coverage` rows are included without another charge.

```json
{
  "recordType": "review",
  "stableId": "steam:730:123456789",
  "reviewId": "123456789",
  "appId": "730",
  "review": "Original public review text.",
  "language": "english",
  "recommended": true,
  "playtimeAtReviewMinutes": 1840,
  "votesHelpful": 12,
  "developerResponse": null,
  "updatedAt": "2026-09-19T12:00:00.000Z",
  "reviewUrl": "https://steamcommunity.com/profiles/76561198000000000/recommended/730/",
  "sourceName": "Steam"
}
```

![Steam review export with review and coverage rows](https://api.apify.com/v2/key-value-stores/DJgPR6wwS2tIaLDQW/records/steam_reviews--37a0538752bbcecee2ce-actual-output.png)

### 🎛️ Input guide

| Input | Use it for | Limit or consequence |
|---|---|---|
| `games` | Steam App IDs or public Store URLs | 1–50 games |
| `reviewOrder` | Recently created or recently updated feedback | Part of monitoring scope |
| `language` | `all` or one Steam language code | Part of monitoring scope |
| `recommendation` | All, recommended, or not recommended | Filtered rows are not delivered or billed |
| `purchaseType` | All, Steam purchases, or other access | Uses Steam's published flag |
| `lookbackDays` | Recent or updated review window | 1–3,650 days |
| `includeOffTopicActivity` | Include periods Steam may identify as off-topic | Off by default |
| `maxReviewsPerGame` | Per-game cap | 1–5,000 |
| `maxReviews` | Whole-run cap | 1–5,000 current reviews |
| `maxBuyerChargeUsd` | Actor-level preflight budget | 0–100 USD; also set Apify maximum total charge |
| `maxRuntimeSecs` | Source-collection time | 10–60 seconds; delivery headroom is reserved |
| `firstRunBehavior` | Initial change rows | Reviews are still exported and billed in both modes |
| `stateNamespace` | Separate saved watches | 1–50 safe characters; up to 25,000 retained review fingerprints |

### 💰 Pricing

- `$0.005` per verified Steam game check, including a verified empty result
- `$0.00085` per delivered current review (`$0.85` per 1,000 review rows)
- `change` and `coverage` rows are included
- unavailable, blocked, malformed, or unverified targets are free

The prefilled one-game, 100-review maximum is `$0.09`. One game plus 1,000 delivered reviews is `$0.855`. Your final total is the verified game checks plus delivered current reviews; the Actor checks `maxBuyerChargeUsd` before collection and also respects Apify's maximum total charge.

### ✅ Coverage you can trust

`COMPLETE` means the verified requested review window ended before your cap. `CAPPED` means the requested per-game or run limit was reached first. `EMPTY_CONFIRMED` means a verified requested window contained no reviews. `PARTIAL`, `BLOCKED`, `FAILED`, and `NOT_VISITED` remain explicit instead of becoming a false empty result.

Monitoring reports `NEW` and `UPDATED` only. A review missing from a later bounded window is not evidence that it was deleted, so deletion events are never invented. State is committed only after review delivery is confirmed.

### 🔌 API and automation

Run the Actor from the Apify API, schedule the same saved input, or connect the Dataset to n8n, Make, Zapier, Sheets, a warehouse, or your own database. Use:

- `stableId` to upsert current review rows;
- `changeId` to deduplicate one included change event;
- `recordType` to route `review`, `change`, and `coverage` rows;
- the `OUTPUT` record for run totals, expected buyer charge, and per-game coverage.

For monitoring, keep the same complete input and `stateNamespace`. Avoid overlapping runs for one watch; a concurrent run fails safely.

### ⚠️ Not yet supported

- Game discovery, Store search, game metadata, private profiles, or account-only content
- Posting, replying, voting, moderation, or any other Steam account action
- Free-text sentiment classification; `recommended` is Steam's published recommendation flag
- A guaranteed full historical archive beyond the verified requested public window
- Deleted-review inference, overlapping runs for one watch, more than 5,000 reviews per run, or more than 25,000 retained review fingerprints

### ❓ FAQ and support

**Why are there more Dataset rows than paid reviews?**\
Included `change` and `coverage` rows make the result auditable. Filter by `recordType` when you need only current reviews.

**Does the Actor need my Steam account or API key?**\
No. It reads public Steam review data and never asks for login cookies, private tokens, or account access.

**Why is coverage CAPPED?**\
The per-game or total limit ended the verified window. Raise the appropriate limit and buyer charge cap if you need more rows.

**How do I monitor several independent products or teams?**\
Use a distinct `stateNamespace` for every independent watch and keep each watch's complete input stable.

For support, share the Apify run ID and the buyer-safe `OUTPUT` summary. Do not send passwords, cookies, private keys, or account data.

Steam and the Steam logo are trademarks and/or registered trademarks of Valve Corporation in the U.S. and/or other countries. This Actor is not affiliated with or endorsed by Valve.

# Actor input Schema

## `workflow` (type: `string`):

Export reviews once, or keep a named watch that adds included change records on repeat runs.

## `games` (type: `array`):

One game per line. Example: 730 or https://store.steampowered.com/app/730/. Up to 50 games.

## `reviewOrder` (type: `string`):

Choose newly created or recently updated reviews within the lookback window.

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

Use all or one Steam language code such as english, german, french, spanish, brazilian, schinese, or tchinese.

## `recommendation` (type: `string`):

Return all reviews, only recommended reviews, or only not-recommended reviews.

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

Filter by the source-published Steam purchase flag.

## `lookbackDays` (type: `integer`):

Review window from 1 to 3,650 days for recent or updated ordering.

## `includeOffTopicActivity` (type: `boolean`):

Include periods Steam may identify as off-topic review activity. Leave off for the standard review window.

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

Maximum current reviews to deliver for each game. Reaching this limit is reported as CAPPED.

## `maxReviews` (type: `integer`):

Total current-review limit across every game. Start with 100; raise it for larger exports up to 5,000.

## `maxBuyerChargeUsd` (type: `number`):

The run checks that this can cover all requested game checks and the review limit before collection. Also set Apify maximum total charge.

## `maxRuntimeSecs` (type: `integer`):

Limits source collection to 10–60 seconds, with at least 60 additional seconds reserved for safe delivery and state commit.

## `firstRunBehavior` (type: `string`):

Both options export and bill verified current reviews. This setting only changes whether the first run also returns included NEW records.

## `stateNamespace` (type: `string`):

Keep this name and the same review scope on repeat runs. Use a new name for a separate watch. Up to 25,000 review fingerprints are retained.

## Actor input object example

```json
{
  "workflow": "export",
  "games": [
    "730"
  ],
  "reviewOrder": "recent",
  "language": "all",
  "recommendation": "all",
  "purchaseType": "all",
  "lookbackDays": 365,
  "includeOffTopicActivity": false,
  "maxReviewsPerGame": 100,
  "maxReviews": 100,
  "maxBuyerChargeUsd": 1,
  "maxRuntimeSecs": 60,
  "firstRunBehavior": "emit_current_as_new",
  "stateNamespace": "default"
}
```

# Actor output Schema

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

The default Dataset contains review, change, and coverage records.

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

Summary of verified reviews, included changes, expected charge, and each requested game.

# 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 = {
    "workflow": "export",
    "games": [
        "730"
    ],
    "reviewOrder": "recent",
    "language": "all",
    "recommendation": "all",
    "purchaseType": "all",
    "lookbackDays": 365,
    "includeOffTopicActivity": false,
    "maxReviewsPerGame": 100,
    "maxReviews": 100,
    "maxBuyerChargeUsd": 1,
    "maxRuntimeSecs": 60,
    "firstRunBehavior": "emit_current_as_new",
    "stateNamespace": "default"
};

// Run the Actor and wait for it to finish
const run = await client.actor("luminar/steam-reviews-scraper-change-monitor").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 = {
    "workflow": "export",
    "games": ["730"],
    "reviewOrder": "recent",
    "language": "all",
    "recommendation": "all",
    "purchaseType": "all",
    "lookbackDays": 365,
    "includeOffTopicActivity": False,
    "maxReviewsPerGame": 100,
    "maxReviews": 100,
    "maxBuyerChargeUsd": 1,
    "maxRuntimeSecs": 60,
    "firstRunBehavior": "emit_current_as_new",
    "stateNamespace": "default",
}

# Run the Actor and wait for it to finish
run = client.actor("luminar/steam-reviews-scraper-change-monitor").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 '{
  "workflow": "export",
  "games": [
    "730"
  ],
  "reviewOrder": "recent",
  "language": "all",
  "recommendation": "all",
  "purchaseType": "all",
  "lookbackDays": 365,
  "includeOffTopicActivity": false,
  "maxReviewsPerGame": 100,
  "maxReviews": 100,
  "maxBuyerChargeUsd": 1,
  "maxRuntimeSecs": 60,
  "firstRunBehavior": "emit_current_as_new",
  "stateNamespace": "default"
}' |
apify call luminar/steam-reviews-scraper-change-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,luminar/steam-reviews-scraper-change-monitor"
        }
    }
}
```

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/gCjnBdRcT2N2tEXeZ/builds/f2Moq9bzWJOyg8IO4/openapi.json
