# App Store Rankings Scraper — Apple & Google Play Charts (`funny_ground/app-store-rankings-scraper`) Actor

Collect current Apple App Store and Google Play rankings by country, chart type, and category. Export chart positions and available app metadata to CSV/JSON. Optional details; no historical rankings.

- **URL**: https://apify.com/funny_ground/app-store-rankings-scraper.md
- **Developed by:** [Coor Yu](https://apify.com/funny_ground) (community)
- **Categories:** SEO tools, Developer tools, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 app rankings

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?

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

## App Store Rankings Scraper — Apple & Google Play Charts

Scrape **Apple App Store and Google Play rankings** by country, chart type, and category into one export-ready dataset. Use ready-to-run defaults or compare Top Free, Top Paid, and Top Grossing charts where the storefront provides them. No Apple/Google account, storefront API key, browser, or proxy subscription is required; programmatic Apify calls still require Apify authentication.

**Start with the defaults:** request the current **US Top Free chart**, up to **20 apps per store** — **40 ranking rows** in total. At the current 256 MB allocation, 40 stored rankings incur **$0.025 in Actor event fees, including one startup event**. Store availability can produce fewer rows.

### Quick start: no input required

1. Click **Try for free / Start**.
2. Keep the defaults, or choose countries, charts and categories from the named dropdowns.
3. Run and download the **App rankings** dataset as JSON, CSV, Excel, or another Apify export format.

An API call with `{}` uses the same defaults as the form. No field is required.

#### Compare game charts in two markets

```json
{
  "countries": ["us", "jp"],
  "categories": ["games"],
  "maxItemsPerChart": 50
}
```

Apple and Google Play are both selected by default. Category IDs are mapped automatically. This example requests 4 charts and up to 200 rows. If all 200 rankings are stored at the current 256 MB allocation, Actor event fees are **$0.105**. This is not a guarantee that every selected chart returns its requested row count.

#### One country, one store, one category

```json
{
  "stores": ["google_play"],
  "countries": ["de"],
  "chartTypes": ["top_paid"],
  "categories": ["business"],
  "maxItemsPerChart": 20
}
```

The Google Play text language is chosen automatically from the country. You do not need to fill it in.

### Pricing: simple, with platform usage included

| Charge | Price |
|---|---:|
| One stored ranking row | **$0.0005** — **$0.50 per 1,000 rankings** |
| Actor start | **$0.005 per GB of allocated memory, minimum one event** |
| Optional app details | **Included**, no extra event fee |

The run-start event is charged automatically even when no ranking is returned. Failed charts, skipped charts and diagnostic summaries are **not** charged as ranking results. Only actual ranking rows stored in the default dataset incur the result fee.

Startup billing is memory-based, not universally a fixed per-run fee. The current supported allocation is 256 MB, which incurs the minimum one startup event. At that allocation, the event-fee formula is **$0.005 + stored ranking rows × $0.0005**; the examples below use that setting.

| Stored rows in one run | Total event price |
|---:|---:|
| 1 | $0.0055 |
| 40 (default maximum) | $0.025 |
| 100 | $0.055 |
| 1,000 | $0.505 |

There are no paid upstream Actors, external data-provider API keys, or residential proxy requirements. Normal platform usage during the run is included in the event price. Apify may separately charge standard post-run dataset access or retention usage under your plan. The [Apify Pricing tab](https://apify.com/funny_ground/app-store-rankings-scraper/pricing) is authoritative if prices change.

Use Apify's **Maximum charge per run** control to set a spending cap. The Actor checks the remaining budget before fetching more charts, reduces requested row counts to the affordable amount, and stops without deliberately writing an extra over-budget row. The minimum supported run cap is **$0.0055**, enough for the run start and one ranking.

### Input: five everyday controls

| Field | What you choose | Default |
|---|---|---|
| `stores` | Apple App Store, Google Play, or both | Both |
| `countries` | Countries by name; multiple markets supported | United States |
| `chartTypes` | Top Free, Top Paid, Top Grossing | Top Free |
| `categories` | Named categories shared between both stores | Overall |
| `maxItemsPerChart` | Apps per chart, 1–200 | 20 |

Additional options are in separate sections:

- **`includeAppDetails`**: off by default. Enable to add richer metadata at the **same event price**. It is slower, especially for Google Play.
- **`language`**: `auto` by default. Choose a language only if you need to override local Google Play text. It does not change the ranking market.
- **`maxConcurrency`**: 2 by default; runtime is capped at 3 to keep requests and memory predictable. Legacy API values up to 10 remain accepted.

#### Category selection

Use named choices such as `games`, `business`, `education`, `finance`, `shopping`, `entertainment`, `health_and_fitness`, `food_and_drink`, `travel`, `productivity`, `social`, `music`, or `game_puzzle`. The form shows readable names instead of numeric or platform-specific codes.

Cross-store categories are comparable, **not identical taxonomies**:

- **Overall** maps to Apple's all-apps chart and Google Play's **Apps** chart. Android **Games** have a separate chart: select `games` to include them.
- **Photography** maps to Apple's Photo & Video category and Google's Photography category.
- **Books**, **News**, **Utilities** and other common categories map to the closest named store categories.
- Mainland China charts use **Apple only**. Google Play is unavailable there; the Actor does not relabel another country's or global Android chart as CN.
- A country or category may not have every chart. Unavailable charts are listed in the run summary, while successful charts remain available.

#### Existing API integrations

The original `stores`, `countries`, `chartTypes`, `maxItemsPerChart`, `includeAppDetails`, `language`, and `maxConcurrency` inputs remain supported. Explicit `appleCategories` and `googleCategories` arrays still work and override the common `categories` menu **only for their own store**. These legacy fields are hidden from the basic form.

```json
{
  "stores": ["apple", "google_play"],
  "countries": ["us"],
  "chartTypes": ["top_free"],
  "appleCategories": ["ALL", "6014"],
  "googleCategories": ["APPLICATION", "GAME"],
  "maxItemsPerChart": 20
}
```

The no-input default is **20 apps per chart**, with automatic language selection. Set `maxItemsPerChart` and `language` explicitly if your integration requires different values.

### Output: a real chart position, not an app estimate

Each row is one app's observed position in one store/country/chart/category snapshot. Useful fields include:

- `rank`, `store`, `country`, `chartType`, `chartCategory`, `chartKey`
- `appId`, `bundleId` or `packageName`, `title`, `developer`, `url`, `icon`
- Available price, currency, rating and summary fields
- `scrapedAt` and the public `sourceUrl`
- With enrichment: version, update/release dates, rating/review counts, description and Android install ranges, where exposed by the source
- `detailsIncluded`: whether enrichment was actually returned, not merely requested

Ratings in basic Google Play charts may already be present; Apple's additional rating fields generally require app enrichment. Descriptions are limited to 10,000 characters. Android install ranges are store-published estimates, not exact download counts. Revenue is not inferred from the Top Grossing chart.

The same app can legitimately appear several times across countries or charts. It is billed once for each stored chart position, not once globally. Use `chartKey` and `scrapedAt` to group snapshots and `appId` to join the same app across charts.

### Run summary and reliability

The **Run summary** output links to the `OUTPUT` record. It includes normalized settings, per-chart result counts, actual enrichment counts, errors, warnings and a stop reason when relevant.

- Transient chart requests get at most two attempts; permanent HTTP errors are not repeatedly retried.
- Detail lookups are best-effort. A failed enrichment request preserves the available ranking row with `detailsIncluded=false`.
- Mixed chart availability produces `OUTPUT.status=partial` rather than discarding successful data.
- If every chart fails with no results and no spending/time stop, the run fails with specific errors.
- Maximum **100 chart requests**, **200 apps per chart**, **256 MB memory**, and **two minutes of collection**. Large inputs may finish partially; split them into smaller runs when this is reported.
- Ranking data is fetched live from public storefront endpoints. Store refresh delays, fewer-than-requested rows and future upstream format changes remain possible.

This Actor does not retrieve historical rankings, app reviews, private analytics, or exact downloads/revenue. It does not bypass authentication. All billed ranking results are available in the dataset; summaries are stored separately.

### FAQ

**Can I get historical App Store rankings?** No. Each run captures the chart currently exposed by the storefront. Compare your own saved snapshots for rank changes over time.

**Does Top Grossing provide app revenue?** No. It provides a chart position where available, not sales, revenue, or exact download counts.

**Why can one app appear multiple times?** Each store, country, category, and chart is a separate observation and billable ranking row.

For related public-catalog research, see [Shopify Products Scraper](https://apify.com/funny_ground/shopify-products-scraper) and [WooCommerce Products Scraper](https://apify.com/funny_ground/woocommerce-store-products-scraper). Use data in accordance with storefront terms and applicable laws.

# Actor input Schema

## `stores` (type: `array`):

Choose Apple App Store, Google Play, or both. No store URLs needed.

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

Select countries by name. Additional two-letter country codes are accepted. UK is normalized to GB. Mainland China charts use Apple only, because Google Play is unavailable there. Each selected country creates separate charts.

## `chartTypes` (type: `array`):

Choose one or more charts. Top Grossing is the store's published chart, not an estimate of downloads or revenue.

## `categories` (type: `array`):

One category menu works for both stores: native category IDs are mapped automatically. Overall means all iOS apps and the Android Apps chart; choose Games separately for Google Play games. Some categories are approximate cross-store equivalents. You can select more than one.

## `maxItemsPerChart` (type: `integer`):

Keep 20 for a quick, inexpensive sample. Increase up to 200 for deeper charts. This is a per-chart cap, not a total run cap. Stores may return fewer apps. For example, 2 stores × 1 country × 1 chart × 1 category × 20 = up to 40 billable rankings.

## `includeAppDetails` (type: `boolean`):

Optionally add ratings/counts, app versions, update dates, descriptions, and Android install ranges when available. Included in the ranking price, with no extra paid event. Missing detail pages keep the ranking row with detailsIncluded=false.

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

Auto chooses a local language for each country, falling back to English. Ranking market is always controlled by Countries, not by language. Apple localizes from its storefront.

## `maxConcurrency` (type: `integer`):

Keep the default. Legacy API values from 1–10 are accepted, but execution is capped at 3 to protect reliability and memory usage.

## `appleCategories` (type: `array`):

Optional compatibility override for Apple only. Use ALL or documented numeric genre IDs. Omit to use the simple App categories menu. Existing API inputs remain supported.

## `googleCategories` (type: `array`):

Optional compatibility override for Google Play only. Omit to use the simple App categories menu. Existing API inputs remain supported.

## Actor input object example

```json
{
  "stores": [
    "apple",
    "google_play"
  ],
  "countries": [
    "us"
  ],
  "chartTypes": [
    "top_free"
  ],
  "categories": [
    "overall"
  ],
  "maxItemsPerChart": 20,
  "includeAppDetails": false,
  "language": "auto",
  "maxConcurrency": 2
}
```

# Actor output Schema

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

Normalized Apple App Store and Google Play chart rows in the default dataset.

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

Counts and per-chart errors for this run.

# 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 = {
    "stores": [
        "apple",
        "google_play"
    ],
    "countries": [
        "us"
    ],
    "chartTypes": [
        "top_free"
    ],
    "categories": [
        "overall"
    ],
    "maxItemsPerChart": 20,
    "language": "auto",
    "maxConcurrency": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("funny_ground/app-store-rankings-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 = {
    "stores": [
        "apple",
        "google_play",
    ],
    "countries": ["us"],
    "chartTypes": ["top_free"],
    "categories": ["overall"],
    "maxItemsPerChart": 20,
    "language": "auto",
    "maxConcurrency": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("funny_ground/app-store-rankings-scraper").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 '{
  "stores": [
    "apple",
    "google_play"
  ],
  "countries": [
    "us"
  ],
  "chartTypes": [
    "top_free"
  ],
  "categories": [
    "overall"
  ],
  "maxItemsPerChart": 20,
  "language": "auto",
  "maxConcurrency": 2
}' |
apify call funny_ground/app-store-rankings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,funny_ground/app-store-rankings-scraper"
        }
    }
}
```

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/Qr6UcwyJz3xjef9Bh/builds/LUL1McBWAPtriaOiE/openapi.json
