# App Store + Google Play Rank Tracker (`constructive_calm/app-store-rank-tracker`) Actor

Daily top-chart snapshots across 150+ countries for Apple App Store and Google Play — Free, Paid, Grossing. Built-in rank deltas (1d/7d/30d), top movers, new entries, dropoffs, and statistical forecasts. Per-app enrichment (ratings, reviews, dev, category).

- **URL**: https://apify.com/constructive_calm/app-store-rank-tracker.md
- **Developed by:** [Omar Eldeeb](https://apify.com/constructive_calm) (community)
- **Categories:** Social media, Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 11 total users, 3 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $3.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/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 + Google Play Rank Tracker

Daily top-chart snapshots across **150+ countries** for both Apple App Store and Google Play — with built-in **rank deltas**, **top-mover detection**, **new-entry / dropoff alerts**, and **statistical rank forecasts**.

Built for mobile growth teams, ASO agencies, and investors who need Sensor Tower-grade rank tracking at a fraction of the cost.

***

### 1. What you get

For every country × chart × ranked app per run:

| Field | Description |
|---|---|
| `rank` | Current position on the chart (1 = top) |
| `app_id` | Numeric iTunes track ID (Apple) or package name like `com.openai.chatgpt` (Play) |
| `app_name`, `developer`, `url`, `icon_url` | Basic identity |
| `app_genre` | App's own Apple/Play genre (e.g. "Productivity") |
| `rating`, `rating_count`, `size_bytes`, `release_date`, `short_description`, `screenshot_urls` | When `perAppEnrichment` is on |
| `price`, `currency` | In LOCAL currency for paid apps |
| **`rank_change_1d`** | +ve = moved up, -ve = moved down vs. yesterday's snapshot (null on first run) |
| **`rank_change_7d`** | vs. ~7 days ago (null until ≥ 7 days of history) |
| **`rank_change_30d`** | vs. ~30 days ago (null until ≥ 30 days of history) |
| **`days_on_chart`** | Consecutive days in chart through current snapshot |
| **`peak_rank`** | Best rank in the rolling history window |
| **`forecast_rank_1d`, `forecast_rank_7d`** | Exponential-smoothing forecast (null until ≥ 5 snapshots) |

Plus auxiliary **mover events** (when `emitMovers` is on):

- `top-riser` (top 10 biggest positive deltas vs. prior snapshot)
- `top-faller` (top 10 biggest negative deltas)
- `new-entry` (apps that entered the chart)
- `dropoff` (apps that fell off the chart)

***

### 2. Coverage

- **Apple App Store** — all 175+ official storefronts, Top Free / Top Paid / Top Grossing, all-apps and category-filtered charts, via the official iTunes RSS feed (zero anti-bot, no auth).
- **Google Play** — all 130+ publishing regions, Top Free / Top Paid / Grossing, scraped via the `google-play-scraper` library. Residential proxy enabled by default.
- Up to **200 apps per chart**.
- Cross-platform **category filter** supports: games, social-networking, photo-video, business, productivity, finance, health-fitness, education, entertainment, lifestyle, music, news, shopping, sports, travel, utilities, weather, books, food-drink, navigation, medical, reference.

***

### 3. Use cases & copy-paste input recipes

#### 3.1 Indie dev — daily rank of my app's market

```json
{
    "platforms": ["apple", "googleplay"],
    "countries": ["us"],
    "chartTypes": ["top-free"],
    "resultsPerChart": 100,
    "perAppEnrichment": false,
    "emitMovers": false,
    "enableForecast": true
}
```

Cheap (~$9/mo on daily schedule), gives you a daily picture of who's ahead of you in Top Free US.

#### 3.2 Mobile growth team — G8 markets, all three charts

```json
{
    "platforms": ["apple", "googleplay"],
    "countries": ["us", "gb", "de", "fr", "jp", "kr", "ca", "au"],
    "chartTypes": ["top-free", "top-paid", "top-grossing"],
    "resultsPerChart": 100,
    "perAppEnrichment": true,
    "emitMovers": true,
    "enableForecast": true
}
```

Full Sensor Tower replacement for the big eight markets. ~$150/mo on daily schedule.

#### 3.3 Game studio — Games category in 20 mobile-first markets

```json
{
    "platforms": ["apple", "googleplay"],
    "countries": ["us", "cn", "jp", "kr", "tw", "hk", "br", "mx", "in", "id", "th", "vn", "ph", "my", "sg", "tr", "ru", "ae", "sa", "eg"],
    "chartTypes": ["top-free", "top-grossing"],
    "categories": ["games"],
    "resultsPerChart": 100,
    "perAppEnrichment": true,
    "emitMovers": true
}
```

Track the competitive landscape in mobile gaming across emerging + established markets.

#### 3.4 ASO agency — 150+ country sweep, metadata only

```json
{
    "platforms": ["apple"],
    "countries": [],
    "chartTypes": ["top-free"],
    "resultsPerChart": 50,
    "perAppEnrichment": true,
    "emitMovers": false,
    "enableForecast": false
}
```

Apple-only (lower cost, no proxy), all 175 Apple storefronts, 50 apps each. Output ready to feed client dashboards.

#### 3.5 Investor watch — tracking public mobile companies

```json
{
    "platforms": ["apple", "googleplay"],
    "countries": ["us", "gb", "de", "fr", "jp"],
    "chartTypes": ["top-free", "top-grossing"],
    "resultsPerChart": 200,
    "perAppEnrichment": true,
    "emitMovers": true,
    "enableForecast": true
}
```

Wider result depth (200 apps) means you catch apps like Duolingo, Roblox, Uber, Lyft, Airbnb ranking movements as early signals.

#### 3.6 Trend hunter — anomaly digest mode

```json
{
    "platforms": ["apple", "googleplay"],
    "countries": ["us", "gb", "de", "fr", "jp", "kr", "br", "in", "id", "mx"],
    "chartTypes": ["top-free"],
    "resultsPerChart": 200,
    "perAppEnrichment": false,
    "emitMovers": true,
    "enableForecast": false
}
```

Just the movers — find tomorrow's breakout apps. Filter dataset for `mover_type=new-entry` + `rank ≤ 20` to spot rapid-rise new apps.

***

### 4. How time-series works

The actor persists per-chart snapshot history in an Apify key-value store (one key per `platform/country/category/chart`). Each scheduled run:

1. Fetches the current chart.
2. Loads prior snapshots from KV (default 30 days rolling).
3. **Idempotency**: if a prior snapshot exists from the same hour, it's replaced (re-runs don't inflate history).
4. Computes deltas, movers, and forecasts against the merged history.
5. Writes the new snapshot back to KV.

To build time-series for analysis, set up a **scheduled run in Apify** (e.g. daily at 09:00 UTC) with the same input. The dataset for each run is timestamped, so you can query across runs or roll them up to a BigQuery / Looker / Metabase table via Apify's dataset API.

***

### 5. Cost & pricing (pay-per-event)

| Event | Price | When it fires |
|---|---|---|
| Actor run start | $0.01 | Once per run |
| Dataset item | $0.003 | Per ranked app pushed to the dataset |
| Per-app enrichment | $0.002 | Per app, only when `perAppEnrichment: true` |
| Mover event | $0.001 | Per mover/new-entry/dropoff row, only when `emitMovers: true` |

**Free trial**: the first 10 chargeable events per run are free, so you can preview output before paying for enrichment/mover events.

**Typical monthly costs** (daily scheduled run):

- Indie dev, 1 country × 100 apps × 1 chart: **~$9/mo**
- Mobile growth team, 8 countries × 100 × 3 charts + enrichment + movers: **~$150/mo**
- ASO agency, 150 countries × 50 apps × 1 chart, Apple only: **~$270/mo**

Compare to Sensor Tower ($500–2000/mo), data.ai (same), Appfigures (from $10 but single-country).

***

### 6. Data-freshness notes

- **Apple** refreshes its top charts every few minutes. Our RSS fetch reflects whatever Apple published at query time.
- **Google Play** charts update hourly. Google Play regional charts can lag US by 1-2 hours in some countries.
- **Scheduling**: for daily deltas, pick a time and stick with it. Running at the same UTC hour every day produces the cleanest rank-change signals.

***

### 7. Google Play reliability notes

Google Play has no official charts API — the data is scraped from public store pages. To keep scraping stable at scale:

- **Use residential proxies** (enabled by default in the proxy config). Datacenter proxies trigger CAPTCHAs quickly.
- **Unsupported countries** (some very small territories): the actor logs a skip warning and moves on rather than erroring out the whole run.
- **Partial failures** (a country returns 503/CAPTCHA after retries): that chart is skipped with a warning. Other countries in the same run are unaffected.
- **Apple side** is always reliable — it's the official iTunes RSS feed, no proxy needed.

***

### 8. Input reference

See the Input tab in the Apify Console. All fields have inline docs, including empty-value behavior, cross-field dependencies, and cost hints.

***

### 9. Dataset schema

Every row is one ranked-app snapshot or one mover event. Both shapes share the common fields `snapshot_ts`, `platform`, `country`, `chart_type`, `category`, `app_id`, `app_name`, `rank`. Mover rows additionally carry `mover_type` and `prior_rank`; regular rows carry the delta, days-on-chart, peak, and forecast fields.

For visualizations, the Console's built-in dataset views expose three preset filters: **overview** (all ranked-app snapshots), **enriched** (with ratings + details), and **movers** (anomaly events only). You can also export CSV / JSON / Excel directly from the Console, or hit the dataset REST API to feed BI tools.

# Actor input Schema

## `platforms` (type: `array`):

Which app stores to scrape. Select one or both. Apple uses the official iTunes RSS feed (zero anti-bot, no proxy needed). Google Play uses the public store (residential proxy recommended — enable the proxy section below). To scrape both Apple and Google Play, add 'googleplay' after 'apple'.

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

Two-letter country codes (lower-case) to scrape. Examples: us, gb, de, fr, jp, kr, cn, br, in, ae. LEAVE EMPTY to scrape all 159 supported countries (curated intersection of Apple 184 App Store storefronts and Google Play 130+ regions). Countries supported by only one platform are skipped on the other with a debug log, not an error. Start with 1-2 countries to preview before expanding.

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

Which top charts to pull per country. Free = free apps ranked by downloads, Paid = paid apps ranked by revenue from purchases, Grossing = apps ranked by total revenue including IAP + subscriptions (usually dominated by games).

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

Optional category filter. LEAVE EMPTY to scrape the all-apps chart for each country (most common). When set, the actor pulls one chart per (country × chart type × category). Supported names: games, social-networking, photo-video, business, productivity, finance, health-fitness, education, entertainment, lifestyle, music, news, shopping, sports, travel, utilities, weather, books, food-drink, navigation, medical, reference. Unknown names are ignored with a warning. Each added category multiplies runtime and cost.

## `resultsPerChart` (type: `integer`):

How many ranked apps to pull per chart. IMPORTANT: Apple's RSS feed caps at 100 rows per chart regardless of this setting (Apple-side limit — requesting 200 still returns 100). Google Play supports up to 200 per chart. Each ranked app = $0.003 dataset charge, so 100 countries × 3 charts × 100 results = 30,000 rows ≈ $90. Start small (25-50) to preview.

## `perAppEnrichment` (type: `boolean`):

If enabled, each ranked app also gets enriched with rating (stars), rating count, developer name, genre, app size, screenshot URLs, short description, and release date. Apple uses the iTunes Lookup API (batched, fast — adds only a few seconds). Google Play requires a per-app fetch (slower: roughly 1-2 seconds per app with residential proxy). Adds $0.002 per enriched app. RECOMMENDED for mobile-growth / agency use cases. First 100 enrichment calls per run are free (trial). Off by default so you can gauge base-run cost before opting in.

## `emitMovers` (type: `boolean`):

If enabled, after each snapshot the actor emits mover events vs. the prior snapshot: top 10 risers, top 10 fallers, new entries to the chart, and dropoffs from the chart. Mover rows are pushed to the same dataset as snapshots ($0.003 per row) plus a supplementary $0.001 mover-event charge for the analytical signal. Never fires on the first run (needs prior snapshot history). REQUIRES scheduled runs to build history.

## `enableForecast` (type: `boolean`):

If enabled, each result includes `forecast_rank_1d` and `forecast_rank_7d` computed via exponential smoothing over the last 30 snapshots. Forecasts are only populated once at least 5 snapshots of history exist (otherwise fields are null). FREE — no per-event charge.

## `historySnapshots` (type: `integer`):

How many prior snapshots to persist in the key-value store per (platform, country, category, chart) for delta and forecast computation. Default 30 = ~one month of daily history. Higher values give smoother forecasts but use more KV storage.

## `proxyConfiguration` (type: `object`):

Proxy used for Google Play requests. Apple RSS is called directly without proxy. Residential proxies STRONGLY recommended for Google Play — datacenter proxies trigger CAPTCHAs quickly. Leave default to use Apify residential proxies automatically.

## Actor input object example

```json
{
  "platforms": [
    "apple"
  ],
  "countries": [
    "us"
  ],
  "chartTypes": [
    "top-free"
  ],
  "categories": [],
  "resultsPerChart": 25,
  "perAppEnrichment": false,
  "emitMovers": true,
  "enableForecast": true,
  "historySnapshots": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Snapshot rows (one per ranked app per chart) plus mover events (risers, fallers, new entries, dropoffs) when enabled.

# 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 = {
    "platforms": [
        "apple"
    ],
    "countries": [
        "us"
    ],
    "chartTypes": [
        "top-free"
    ],
    "categories": [],
    "resultsPerChart": 25,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("constructive_calm/app-store-rank-tracker").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 = {
    "platforms": ["apple"],
    "countries": ["us"],
    "chartTypes": ["top-free"],
    "categories": [],
    "resultsPerChart": 25,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("constructive_calm/app-store-rank-tracker").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 '{
  "platforms": [
    "apple"
  ],
  "countries": [
    "us"
  ],
  "chartTypes": [
    "top-free"
  ],
  "categories": [],
  "resultsPerChart": 25,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call constructive_calm/app-store-rank-tracker --silent --output-dataset

```

## MCP server setup

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

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/tGEqhKU5jWvFBPMN3/builds/9hLGabGLF3w09X1gk/openapi.json
