# Steam Localization Gap Finder (`kitsunefox/my-actor`) Actor

Find Steam games whose Japanese, Chinese, Korean or other-language players are unhappier than the global average. Gets the negative-review gap, translation complaints quoted from reviews, untranslated store pages and developer contacts.

- **URL**: https://apify.com/kitsunefox/my-actor.md
- **Developed by:** [kitsune fox](https://apify.com/kitsunefox) (community)
- **Categories:** Open source
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 game analyseds

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/actors/running/actors-in-store.md#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 Localization Gap Finder

Find Steam games whose **Japanese, Chinese, Korean, German (or any of 29 language) players are unhappier than the global player base**, and get the evidence in one row per game: the negative-review gap, translation complaints quoted straight from reviews, whether the store page is still untranslated, and the developer's public support email.

Built for localization vendors and freelance translators prospecting clients, publishers scouting regional problems before a port or a sale, and indie developers checking how their own game lands in a market they cannot read.

### What you get

One dataset row per analysed game:

| Field | Meaning |
|---|---|
| `opportunityScore` | Ranking score (see below). Higher = clearer localization problem |
| `languageNegativeRate` / `globalNegativeRate` | Share of negative reviews in the chosen language vs. all languages |
| `negativeGapPoints` | Difference in percentage points (only when the language has 5+ reviews) |
| `complaintHits` / `complaintHitsNegative` | Reviews mentioning translation, localization, machine translation, garbled text, "no X language", etc. |
| `complaintQuotes` | Up to N excerpts with `votedUp`, `playtimeHours` and the review ID, so you can cite real players |
| `storePageUntranslated` | `true` when the store page in the chosen language still shows the English short description |
| `languageListedAsSupported` | Whether the store lists that language as supported |
| `developer`, `publisher`, `supportEmail`, `supportUrl`, `website` | Public contact from the store page |
| `title`, `released`, `totalReviews`, `genres`, `priceUsd`, `isFree`, `url` | Game basics |

A `RUN_REPORT` record in the key-value store lists candidates, analysed, skipped and Steam requests made.

### How it works

1. **Discovery** (or your own `appIds`): pages Steam search for games that list your language as supported, carry the tags you choose (default `492` = Indie), were released within the last N months and have a total review count in your range. Indie-sized titles are the default because their developers still read support email.
2. **Reviews**: pulls recent reviews in your language plus the global summary from Steam's public `appreviews` endpoint.
3. **Complaint detection**: matches built-in translation-complaint keywords for the language (Japanese, Simplified/Traditional Chinese, Korean, German, French, Spanish, Portuguese, Russian, Polish, Italian, Turkish, Thai, Vietnamese, Ukrainian, Czech, Hungarian, Dutch, Nordic languages, Romanian, Greek, Bulgarian, Indonesian, Arabic). Add your own with `extraKeywords`.
4. **Store page check**: compares the short description in your language with the English one.
5. **Scoring** and output.

#### Opportunity score

```
score = gap_in_points (if language has 5+ reviews)
      + 20 x negative reviews mentioning translation
      +  2 x positive reviews mentioning translation
      + 15 if the store page is untranslated
      + 0.2 x min(language reviews, 50)
```

It is a ranking aid, not a verdict. Read the quotes before you write to anyone.

### Input examples

**Japanese, recent indie releases (default):**

```json
{ "language": "japanese", "steamTagIds": ["492"], "releasedWithinMonths": 18, "minReviews": 30, "maxReviews": 4000, "maxGames": 100 }
```

**Simplified Chinese, RPGs only, bigger titles:**

```json
{ "language": "schinese", "steamTagIds": ["122"], "minReviews": 500, "maxReviews": 50000, "maxGames": 200, "reviewPagesPerGame": 3 }
```

**Check specific games:**

```json
{ "language": "koreana", "appIds": ["1145360", "2379780"], "reviewPagesPerGame": 2, "maxQuotes": 10 }
```

Common Steam tag IDs: 492 Indie, 122 RPG, 19 Action, 21 Adventure, 9 Strategy, 4182 Simulation, 599 Roguelike, 1663 FPS, 1667 Horror, 4085 Anime, 3859 Multiplayer, 1685 Co-op, 597 Casual.

### Pricing

Pay per event. You are billed once per run start and once per **game that is actually pushed to the dataset**. Games below `minOpportunityScore`, and games Steam returned no data for, are not billed. Use `maxGames` as a hard cap and set a spending limit on the run.

### Limits and good manners

- Steam rate-limits aggressively. The Actor uses one global polite delay (default 0.35 s) and low concurrency; raising `concurrency` above 3 mostly buys you HTTP 429s.
- Discovery stops after 200 search pages or when releases fall outside your window.
- Reviews are fetched with Steam's default off-topic ("review bomb") filter enabled.
- The keyword lists catch most complaints but not all; a game with `complaintHits = 0` can still have a bad translation. The gap and the quotes together are the signal.
- Data comes from Steam's public store endpoints. Respect Steam's terms when you use the output, and do not spam developers.

### Support

Open an issue on the Actor page. Feature requests for new languages or keyword lists are welcome.

# Actor input Schema

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

Steam language code of the player community you care about. Built-in translation-complaint keywords exist for all listed languages.

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

Analyse only these games and skip discovery. Leave empty to discover games via the filters below.

## `steamTagIds` (type: `array`):

Numeric Steam tag IDs, e.g. 492 = Indie, 122 = RPG, 1663 = FPS, 4182 = Simulation, 599 = Roguelike. Games must carry all listed tags. Only used when appIds is empty.

## `releasedWithinMonths` (type: `integer`):

Discovery only looks at games released within this window.

## `minReviews` (type: `integer`):

Skip games with fewer total Steam reviews (all languages).

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

Skip games with more total reviews. Useful to focus on indie-sized titles that still answer their support email.

## `maxGames` (type: `integer`):

Hard cap on analysed games per run. Each analysed game is one billable event.

## `reviewPagesPerGame` (type: `integer`):

How many pages of recent reviews in the target language to scan for complaints. 1 is enough for indie titles.

## `maxQuotes` (type: `integer`):

How many complaint excerpts to keep per game in complaintQuotes.

## `extraKeywords` (type: `array`):

Added to the built-in keyword list for the chosen language (case-insensitive substring match).

## `minOpportunityScore` (type: `integer`):

Games scoring below this are analysed but not pushed (and not billed).

## `concurrency` (type: `integer`):

Parallel games. Keep low; Steam rate-limits aggressively.

## `requestDelaySeconds` (type: `string`):

Global polite delay between requests. Lower values risk HTTP 429.

## Actor input object example

```json
{
  "language": "japanese",
  "appIds": [],
  "steamTagIds": [
    "492"
  ],
  "releasedWithinMonths": 12,
  "minReviews": 30,
  "maxReviews": 3000,
  "maxGames": 20,
  "reviewPagesPerGame": 1,
  "maxQuotes": 3,
  "extraKeywords": [],
  "minOpportunityScore": 0,
  "concurrency": 2,
  "requestDelaySeconds": "0.35"
}
```

# 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 = {
    "appIds": [],
    "extraKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("kitsunefox/my-actor").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": [],
    "extraKeywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("kitsunefox/my-actor").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 '{
  "appIds": [],
  "extraKeywords": []
}' |
apify call kitsunefox/my-actor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kitsunefox/my-actor"
        }
    }
}
```

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/ElqgbAZhRqTz1bAqs/builds/BdzuGa7yPNxgQnyHg/openapi.json
