# Google Play Ratings by Country (`saffo/play-ratings-by-country`) Actor

Compares the star rating Google Play shows in each country for the apps you list, with star shares, price, spread and change since the last run, one report per app. Not affiliated with Google.

- **URL**: https://apify.com/saffo/play-ratings-by-country.md
- **Developed by:** [Anton Mendelson](https://apify.com/saffo) (community)
- **Categories:** Marketing, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 app rating reports

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

## Google Play Ratings by Country: Compare App Ratings Across Markets

Compares the star rating Google Play shows in each country for the apps you list, with star shares, price, spread and change since the last run, one report per app. Not affiliated with Google.

### What it does

For every app you list, the actor opens its [Google Play](https://play.google.com/store/apps) page once per country you choose and saves one report per app: the average rating Google Play shows in each country, the share of each star level, the local price, the change since your previous run, and a cross-country comparison (mean rating, best and worst country, spread). The pages are read live at run time.

Google Play computes the rating per storefront: on 6 November 2026, for example, com.booking read 4.7957 in the US, 4.7269 in Germany and 4.6715 in India. This actor puts those figures side by side in one row per app. It returns aggregate figures only: no review texts, reviewer names or developer details. It is not affiliated with or endorsed by Google.

### Who it is for

- App store optimisation (ASO) and app marketing teams who watch how their app is rated in each market and spot a country where it slips.
- Product managers launching in new markets who check how the app, and its competitors, are rated there before and after the launch.
- Analysts who benchmark travel apps, games or any other apps against competitors country by country.

### How to use it

1. Open the actor on [Apify Store](https://apify.com/saffo/play-ratings-by-country) and go to its Input tab.
2. Fill in `apps`; every other field has a default (see Input below).
3. Click **Start**. The run ends at the limits below, or earlier at the "Maximum cost per run" you set.
4. When the run ends, open the Output tab: view the results as a table, or export them as JSON, CSV or Excel.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `apps` | array | required | Google Play package names (com.booking) or app page URLs (https://play.google.com/store/apps/details?id=com.booking); duplicates are read once. |
| `countries` | array | `["US","GB","CA","AU","DE","FR","ES","IT","NL","PL","TR","IN","ID","JP","KR","BR","MX","SA","ZA","EG"]` | ISO 3166-1 alpha-2 country codes to compare (upper or lower case), 1 to 50; unknown codes end the run with a clear status message before any page is read. |
| `maxApps` | integer | `50` | Read at most this many apps from the apps list (1 to 200). |
| `compareWithPrevious` | boolean | `true` | Compare each country rating with the last report of the same app kept in the history store and fill ratingChange. |
| `historyStoreName` | string | `"play-ratings-by-country"` | Name of the key-value store in your account that keeps the last report per app for the comparison. |

Example input:

```json
{
  "apps": [
    "com.booking"
  ],
  "countries": [
    "US",
    "DE",
    "IN"
  ],
  "maxApps": 1
}
```

For a weekly comparison in the 20 default markets, leave `countries` out and run the actor on an [Apify schedule](https://docs.apify.com/platform/schedules) once a week. With `compareWithPrevious` on (the default), every report then shows the change since the week before:

```json
{
  "apps": ["com.booking", "com.tripadvisor.tripadvisor", "com.expedia.bookings"]
}
```

### Output

Each result is one dataset item:

| Field | Type | Description |
|---|---|---|
| `url` | string | Web address of the item: its own page, or the page it was read from. |
| `appId` | string | Package name of the app on Google Play. |
| `title` | string or null | Title of the item as shown on the page. |
| `found` | boolean | True when at least one country page of the app answered; false when Google Play has no page for this package name. |
| `category` | string or null | Google Play category id of the app (JSON-LD applicationCategory). |
| `ratingCount` | integer or null | Total number of ratings Google Play reports for the app; the same figure in every country. |
| `minInstalls` | integer or null | Lower bound of the install band Google Play shows, for example 500000000 for "500M+". |
| `countries` | array | One entry per requested country, in input order. |
| `crossCountry` | object | Comparison of the country ratings of this report. |
| `previousFetchedAt` | string or null | When the previous report used for ratingChange was read; null when there is none. |
| `fetchedAt` | string | When the page was read (ISO 8601, UTC). |

Each entry of `countries` holds `country`, `listed`, `rating`, `starShares` (`oneStar` to `fiveStar`), `price`, `currency` and `ratingChange`; `crossCountry` holds `countriesRated`, `meanRating`, `bestCountry`, `bestRating`, `worstCountry`, `worstRating` and `ratingSpread`.

Example output (real items from a test run):

```json
[
  {
    "url": "https://play.google.com/store/apps/details?id=com.booking",
    "appId": "com.booking",
    "title": "Booking.com: Hotels & Travel",
    "found": true,
    "category": "TRAVEL_AND_LOCAL",
    "ratingCount": 6525332,
    "minInstalls": 500000000,
    "countries": [
      {
        "country": "US",
        "listed": true,
        "rating": 4.7957,
        "starShares": {
          "oneStar": 1.8,
          "twoStar": 0.4,
          "threeStar": 1.6,
          "fourStar": 8.9,
          "fiveStar": 87.3
        },
        "price": 0,
        "currency": "USD",
        "ratingChange": 0
      },
      {
        "country": "DE",
        "listed": true,
        "rating": 4.7269,
        "starShares": {
          "oneStar": 2,
          "twoStar": 0.5,
          "threeStar": 1.8,
          "fourStar": 14.2,
          "fiveStar": 81.5
        },
        "price": 0,
        "currency": "EUR",
        "ratingChange": 0
      },
      {
        "country": "IN",
        "listed": true,
        "rating": 4.6715,
        "starShares": {
          "oneStar": 3.6,
          "twoStar": 0.9,
          "threeStar": 2.4,
          "fourStar": 11,
          "fiveStar": 82.1
        },
        "price": 0,
        "currency": "INR",
        "ratingChange": 0
      }
    ],
    "crossCountry": {
      "countriesRated": 3,
      "meanRating": 4.7314,
      "bestCountry": "US",
      "bestRating": 4.7957,
      "worstCountry": "IN",
      "worstRating": 4.6715,
      "ratingSpread": 0.1242
    },
    "previousFetchedAt": "2026-11-06T19:36:29.182Z",
    "fetchedAt": "2026-11-06T19:37:56.844Z"
  }
]
```

Download the dataset as JSON, CSV or Excel, or read it through the Apify API.

### Pricing

Pay per event: a small fee per run plus a fee per result saved. Platform usage is included in these prices.

| Event | When it is charged | Free plan | Bronze plan | Silver plan | Gold plan | Platinum plan | Diamond plan |
|---|---|---|---|---|---|---|---|
| Run started (`run-started`) | Flat fee once per run; covers starting the actor and loading the history store. | $0.025 | $0.02 | $0.018 | $0.016 | $0.016 | $0.016 |
| App rating report (`app-rating-report`) | One app compared across the requested countries and saved to the dataset; apps not found on Google Play are saved but not charged. | $0.0625 | $0.05 | $0.045 | $0.04 | $0.04 | $0.04 |

Example (lowest plan price): a run that saves 100 results costs $0.016 + 100 × $0.04 = **$4.016**. That is $40.00 per 1,000 results plus $0.016 per run. You pay only for results saved to the dataset; set "Maximum cost per run" in the run options and the actor stops there.

One report covers every country you ask for (up to 50), so the price per app does not grow with the number of countries. Apps that Google Play does not know are saved with `found: false` and are not charged. Examples: 10 apps in 20 countries cost $0.02 + 10 × $0.05 = $0.52 per run; the same run on a weekly schedule comes to four or five runs a month, $2.08 to $2.60.

### Limits

- One run saves at most 200 results and loads at most 11,000 pages. Larger jobs: split the start URLs over several runs.

- Default memory 512 MB; Apify datacenter proxy.

- When a limit is reached, the run ends normally and keeps every result saved so far; the status message says which limit it was.

- One run reads up to 200 apps in up to 50 countries, so at most 10,000 pages; the page limit above leaves room for retries.

- The actor reads at most 2 pages per second and 3 at a time to keep its load on Google Play low, so a run of 50 apps in 20 countries (1,000 pages) takes at least 8 minutes.

- Aggregate figures only: no review texts, reviewer names, developer details or descriptions.

- Google Play scales every country's star bars to the global number of ratings, so the report gives each star level as a share in percent, not as a count. `ratingCount` and `minInstalls` are global figures.

- A country where Google Play has no page for the app answers 404; that country shows `listed: false` with empty figures.

- If Google answers with a CAPTCHA, an unusual-traffic page or a sign-in page, or keeps answering "too many requests", the run stops reading and says so in its status message; the reports saved before stay in the dataset.

- Not affiliated with or endorsed by Google. Google Play is a trademark of Google LLC.

### Use with AI agents

AI agents can call this actor as a tool through the Apify MCP server. Add it to an MCP client (Claude Desktop, Cursor, VS Code and others):

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=saffo/play-ratings-by-country"
    }
  }
}
```

Or call it over HTTP and get the results in the response:

```sh
curl -X POST "https://api.apify.com/v2/acts/saffo~play-ratings-by-country/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"apps":["com.booking"],"countries":["US","DE","IN"],"maxApps":1}'
```

An agent can answer "Where is this app rated lowest?" by calling the actor with `apps` and `countries` and reading `crossCountry.worstCountry` and `crossCountry.worstRating` from the report.

### FAQ

#### How much does it cost?

You pay per event: from $0.04 per app rating report plus $0.016 per run. The Pricing section lists the price on every Apify plan. Platform usage is included, and the run stops at the maximum cost per run you set.

#### Can I use it from an AI agent or my own code?

Yes. Add it to any MCP client through the Apify MCP server, or call the Apify API; the examples under Use with AI agents show both. Results come back as JSON.

#### How many results can one run return?

Up to 200 results from at most 11,000 pages. For more, split the input over several runs.

#### Does it collect personal data?

No. It saves only the fields listed under Output and leaves out names, e-mail addresses, phone numbers and profiles of private persons.

#### Why does the rating differ by country?

Google Play computes the average rating per storefront from the ratings given in that country, so the same app can show 4.8 in one country and 4.6 in another on the same day. The actor reads the page of each country (the `gl` parameter) and reports each figure as Google Play shows it.

#### Why is ratingCount the same in every country?

Google Play reports the global total number of ratings on every storefront. For the same reason the star bars of each country add up to that global total, which is why the report turns them into shares.

### Support

Open an issue on the actor's Issues tab.

### Changelog

#### 0.1 (2026-11-06)

- First release: one report per Google Play app comparing the rating, star shares and price across up to 50 countries, with mean, best and worst country, spread and the change since the previous run.

# Changelog

This Actor's version history is a separate document: https://apify.com/saffo/play-ratings-by-country/changelog.md

# Actor input Schema

## `apps` (type: `array`):

Google Play package names (com.booking) or app page URLs (https://play.google.com/store/apps/details?id=com.booking); duplicates are read once.

## `countries` (type: `array`):

ISO 3166-1 alpha-2 country codes to compare (upper or lower case), 1 to 50; unknown codes end the run with a clear status message before any page is read.

## `maxApps` (type: `integer`):

Read at most this many apps from the apps list (1 to 200).

## `compareWithPrevious` (type: `boolean`):

Compare each country rating with the last report of the same app kept in the history store and fill ratingChange.

## `historyStoreName` (type: `string`):

Name of the key-value store in your account that keeps the last report per app for the comparison.

## Actor input object example

```json
{
  "apps": [
    "com.booking",
    "https://play.google.com/store/apps/details?id=com.tripadvisor.tripadvisor"
  ],
  "countries": [
    "US",
    "GB",
    "CA",
    "AU",
    "DE",
    "FR",
    "ES",
    "IT",
    "NL",
    "PL",
    "TR",
    "IN",
    "ID",
    "JP",
    "KR",
    "BR",
    "MX",
    "SA",
    "ZA",
    "EG"
  ],
  "maxApps": 50,
  "compareWithPrevious": true,
  "historyStoreName": "play-ratings-by-country"
}
```

# 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 = {
    "apps": [
        "com.booking",
        "https://play.google.com/store/apps/details?id=com.tripadvisor.tripadvisor"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("saffo/play-ratings-by-country").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 = { "apps": [
        "com.booking",
        "https://play.google.com/store/apps/details?id=com.tripadvisor.tripadvisor",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("saffo/play-ratings-by-country").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 '{
  "apps": [
    "com.booking",
    "https://play.google.com/store/apps/details?id=com.tripadvisor.tripadvisor"
  ]
}' |
apify call saffo/play-ratings-by-country --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,saffo/play-ratings-by-country"
        }
    }
}
```

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/B9MjVTtFSasXfS3WD/builds/x7BbuM9sGhHHtEpYg/openapi.json
