# Steam Reviews Scraper — With Playtime | $5/1K (`datawell/steam-reviews-scraper`) Actor

Steam reviews with the hours each reviewer had played when writing — what separates an informed verdict from a rage post. Filter by language, sentiment and purchase type to exclude free keys. Plus game details, prices and owner estimates. For developers and market research.

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

## Pricing

$5.00 / 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.

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 Reviews & Game Data Scraper

Extract Steam reviews, game details, prices and player estimates. No API key, no
login, no Steam account required.

Every review row carries **how long the reviewer had played when they wrote it** —
the field that separates an informed verdict from a five-minute rage post.

***

### Why this scraper

**Playtime per reviewer.** Steam exposes it; most scrapers drop it. With
`playtimeHoursAtReview` you can filter out reviews written after 12 minutes, weight
sentiment by hours played, or find the reviewers who actually know the game.

**Purchase type filtering.** Separate genuine Steam purchases from review keys and
gifts. If you are measuring sentiment, free copies distort it — one setting removes them.

**Owner estimates included.** Steam never publishes ownership numbers. Game mode
adds estimated owners, average playtime and peak concurrent players.

***

### What you can extract

| Mode | What you get |
|---|---|
| **Reviews of a game** | Every public review with full text, verdict, votes, language, and the reviewer's playtime and library size |
| **Game details and stats** | Price, discount, genres, developers, review score, Metacritic, owner estimates, achievements, platforms |
| **Search the Steam store** | Find games by keyword with price, release date and rating |
| **Review score summary only** | Just the numbers — total, positive, negative, percentage — without pulling individual reviews |

***

### Quick start

1. Pick a mode.
2. Paste an App ID (`730`) or a store URL (`https://store.steampowered.com/app/730/`).
3. Set **Maximum results**.
4. Click **Start**, then download as CSV, Excel or JSON.

***

### Example inputs

**All recent reviews of a game**

```json
{
  "mode": "reviews",
  "appIds": ["730"],
  "maxItems": 5000,
  "sortBy": "recent"
}
```

**Negative German reviews from the last 30 days**

```json
{
  "mode": "reviews",
  "appIds": ["730"],
  "language": "german",
  "reviewType": "negative",
  "dayRange": 30,
  "maxItems": 1000
}
```

**Honest sentiment — real purchases only, no free keys**

```json
{
  "mode": "reviews",
  "appIds": ["1245620"],
  "purchaseType": "steam",
  "sortBy": "all",
  "maxItems": 2000
}
```

**Compare several games side by side**

```json
{
  "mode": "games",
  "appIds": ["730", "570", "1245620", "1172470"],
  "country": "de"
}
```

**Find every game in a genre**

```json
{
  "mode": "search",
  "searchQuery": "roguelike deckbuilder",
  "maxItems": 500
}
```

***

### Output fields

#### Reviews

| Field | Description |
|---|---|
| `review` | Full review text |
| `recommendation` | Recommended or Not Recommended |
| `votedUp` | Same as a boolean |
| `playtimeHoursAtReview` | **Hours played when the review was written** |
| `playtimeHoursTotal` | Hours played overall |
| `playtimeHoursLast2Weeks` | Hours played recently — is the reviewer still active? |
| `authorName`, `authorSteamId`, `authorProfileUrl` | Who wrote it |
| `authorGamesOwned`, `authorReviewCount` | How experienced the reviewer is |
| `createdAt`, `updatedAt` | When it was posted and last edited |
| `votesHelpful`, `votesFunny`, `commentCount` | Community response |
| `helpfulnessScore` | Steam's own weighting, 0 to 1 |
| `steamPurchase` | False for keys, gifts and review copies |
| `receivedForFree`, `refunded`, `writtenDuringEarlyAccess` | Context flags |
| `primarilySteamDeck` | Played mostly on a Steam Deck |
| `language` | Language of the review |

#### Games

| Field | Description |
|---|---|
| `name`, `url`, `type`, `isFree` | Identity |
| `priceInitial`, `priceFinal`, `discountPercent`, `priceCurrency` | Pricing for the chosen country |
| `totalReviews`, `positiveReviews`, `negativeReviews`, `positivePercent` | Review breakdown |
| `reviewScoreDesc` | Steam's wording, e.g. Very Positive |
| `metacriticScore`, `metacriticUrl` | Critic score |
| `ownersEstimate` | Estimated ownership range |
| `averagePlaytimeForever`, `averagePlaytime2Weeks`, `ccu` | Engagement |
| `developers`, `publishers`, `genres`, `categories` | Classification |
| `releaseDate`, `comingSoon` | Release status |
| `achievementCount`, `dlcCount`, `requiredAge` | Extras |
| `platformWindows`, `platformMac`, `platformLinux` | Availability |

***

### Input notes

- **Games** accept an App ID or a full store URL — no need to extract the number.
- **Several games** split the `maxItems` budget evenly between them.
- **Store country** changes prices and currency: `us`, `de`, `gb`, `br`, `jp`.
- **Sort order** `recent` gives newest first, `all` gives most helpful first.

***

### Performance

| Run | Results | Time |
|---|---|---|
| Reviews | 150 | ~2 s |
| Reviews | 5,000 | ~1 min |
| Game details | 3 games | ~4 s |

Reviews paginate 100 at a time; game details need three requests per title
(store, review summary, owner estimates).

***

### Limits

- **Public data only.** Private profiles and unreleased games return little.
- **Owner estimates are estimates.** They come from SteamSpy's sampling, not Steam.
- **Review counts are snapshots** at the time of scraping.
- **Very large runs** may hit rate limits — raise **Delay between requests** to 1–2 seconds.

***

### FAQ

**Do I need a Steam account or API key?**
No. Everything runs against public store endpoints.

**Can I get every review of a big game?**
Yes, though popular titles have millions. Use `dayRange` or `language` to narrow it.

**Why do some reviews show zero playtime?**
The reviewer's profile is private. The review text is still returned.

**Can I filter out review keys and gifts?**
Yes — set **How the game was obtained** to Steam purchases only.

**What formats can I export?**
CSV, Excel, JSON, XML, or straight from the Apify API.

***

### Legal and responsible use

This Actor reads publicly available data from Steam's public store endpoints. It
does not bypass authentication or access private content.

You are responsible for how you use the results, including GDPR obligations when
the data concerns people in the EU. Review text and profile names are personal
data — do not republish them without a lawful basis.

# Actor input Schema

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

Pick what you want to collect. The fields below apply depending on this choice.

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

App IDs (730) or store URLs (https://store.steampowered.com/app/730/). Used in the review and game modes.

## `searchQuery` (type: `string`):

What to search for in the Steam store, e.g. 'roguelike deckbuilder'. Used in search mode.

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

Total number of records to collect. With several games, the budget is split evenly between them.

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

Only reviews written in this language. Use 'all' for every language.

## `reviewType` (type: `string`):

Filter by recommendation. Useful for pulling only complaints or only praise.

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

'Steam purchases only' filters out review keys and gifts, which is the honest signal for sentiment analysis.

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

'Recent' returns newest first, 'helpful' returns the most upvoted, 'updated' the most recently edited.

## `dayRange` (type: `integer`):

Restrict reviews to a recent window. Leave empty for the full history.

## `includeGameName` (type: `boolean`):

Costs one extra request per game, but makes multi-game exports readable.

## `includeOwnerEstimates` (type: `boolean`):

Game mode only. Adds estimated owners and average playtime from SteamSpy — numbers Steam itself does not publish.

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

Two-letter country code controlling prices and currency, e.g. us, de, gb, br.

## `requestDelaySeconds` (type: `integer`):

Seconds to wait between calls. Raise this if a very large run starts hitting limits.

## Actor input object example

```json
{
  "mode": "reviews",
  "appIds": [
    "730"
  ],
  "maxItems": 100,
  "language": "all",
  "reviewType": "all",
  "purchaseType": "all",
  "sortBy": "recent",
  "includeGameName": true,
  "includeOwnerEstimates": true,
  "country": "us",
  "requestDelaySeconds": 0
}
```

# Actor output Schema

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

Scraped reviews, games or search hits. Review rows carry the reviewer's playtime; game rows carry prices, review scores and owner estimates.

## `resultsCsv` (type: `string`):

The same rows as a CSV download, ready for Excel or Google Sheets.

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datawell/steam-reviews-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"] }

# Run the Actor and wait for it to finish
run = client.actor("datawell/steam-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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"
  ]
}' |
apify call datawell/steam-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=datawell/steam-reviews-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/J08PT8L5GrQUTNeVV/builds/ohUoO9CCmudpi7HPx/openapi.json
