# App Store & Google Play Charts & Keyword Rank Tracker (`signalscope-data/app-charts-tracker`) Actor

App Store & Google Play top charts and keyword rankings in any of 122 countries: rank, rank change, 7/30-day history, rating and version per app. Plus ASO keyword ideas and chart reports. $1 per 1,000 rows, spending cap per run, MCP-ready.

- **URL**: https://apify.com/signalscope-data/app-charts-tracker.md
- **Developed by:** [Bin](https://apify.com/signalscope-data) (community)
- **Categories:** Marketing, SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 chart entries

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 Top Charts & Keyword Rank Tracker (ASO)

Get **App Store and Google Play top charts and keyword search rankings** for any country and category, as JSON, CSV or Excel. Each row is one app at one rank, with rank change since your last run, 7- and 30-day history, rating, rating count and version. Also: ASO keyword ideas with popularity and difficulty scores, and cross-country chart reports. No login or API key needed.

**Price: $1 per 1,000 chart rows**, no subscription, no start fee. You set the spending cap (see [Price and budget control](#price-and-budget-control)).

### What you get

| Row | One row per | Main fields | Price |
|---|---|---|---|
| Chart / search rank | app × chart × country (or keyword) | `store`, `country`, `chart`, `category`, `rank`, `previousRank`, `rankChange`, `status` (new / up / down / same / dropped), `appName`, `developer`, `genre`, `rating`, `ratingCount`, `version`, `lastUpdated`, `rankHistory`, `rankChange7d`, `rankChange30d`, `bestRank`, `trend`; Google Play adds `installs`, `inAppPurchases`, `containsAds` | $0.001 |
| Keyword idea (`suggestKeywordsFor`) | keyword × store × country | `keyword`, popularity, difficulty, opportunity, top 5 apps, your app's rank | $0.003 |
| Chart report (`includeChartReport`) | store × chart × category, all countries of the run | top developers, global hits, local breakouts, #1 per country, new launches, paid / IAP / ads share, `sinceLastRun` | $0.02 |

Sample row (real output from a run on 2026-10-12, history fields shortened):

```json
{
  "store": "apple",
  "country": "us",
  "chart": "top-free",
  "category": "overall",
  "rank": 93,
  "appId": "401626263",
  "bundleId": "com.airbnb.app",
  "appName": "Airbnb",
  "developer": "Airbnb, Inc.",
  "genre": "Travel",
  "rating": 4.76,
  "ratingCount": 702927,
  "version": "26.41",
  "lastUpdated": "2026-10-07",
  "previousRank": null,
  "rankChange": null,
  "status": "first-run",
  "bestRank": 93,
  "rankHistory": [{ "at": "2026-10-11T17:29:45.512Z", "rank": 93 }]
}
```

The first run is your baseline (`status: "first-run"`); from the second run on, every row carries `previousRank`, `rankChange` and its status. Apple charts go to 100 positions, Google Play to 200 (see Notes & limits).

### Price and budget control

| Event | Price | Example |
|---|---|---|
| Chart or search rank row | $1 / 1,000 | One top-100 chart = $0.10 |
| Scored keyword idea | $3 / 1,000 | 50 keywords for one store and country = $0.15 |
| Chart report row | $0.02 | 2 stores, top free, any number of countries = $0.04 |

- **`maxRank`** caps rows per chart (default 100). **`mode: "changes"`** returns, and charges, only new entries, movers and dropouts.
- **Max cost per run**: set it in the run options (Console → Run options, or `maxTotalChargeUsd` in the API). When the cap is reached the Actor stops cleanly and keeps what it has already saved.
- The prefilled example (US + GB, both stores, top free, overall) returned **400 rows in 51 seconds = $0.40** (test run 2026-10-12).

### Use it from an AI agent (MCP) or the API

**MCP** (Claude, Cursor, VS Code, any MCP client) via the Apify MCP server:

```
https://mcp.apify.com/?tools=signalscope-data/app-charts-tracker
```

Claude Code: `claude mcp add --transport http apify "https://mcp.apify.com/?tools=signalscope-data/app-charts-tracker" --header "Authorization: Bearer YOUR_APIFY_TOKEN"`. Then ask, e.g., *"Where does Duolingo rank for 'learn spanish' in the US, UK and Germany App Store?"*

**REST API** (one call, returns the rows):

```bash
curl -X POST "https://api.apify.com/v2/acts/signalscope-data~app-charts-tracker/run-sync-get-dataset-items"   -H "Authorization: Bearer YOUR_APIFY_TOKEN" -H "Content-Type: application/json"   -d '{"stores":["apple"],"countries":["us"],"maxRank":20}'
```

Python / JavaScript clients and Make, Zapier, n8n, Google Sheets and webhook integrations work the same way as for any Apify Actor.

### More features

**Changes since the last run**: every run is compared with the previous one, so each app gets `previousRank`, `rankChange` and a status (new, up, down, same or dropped). Switch to **changes-only mode** to get just the breakouts, big movers and dropouts.

**30-day rank history and trends**. Schedule it daily and every chart row (and every keyword search row) carries its own history: **`rankHistory` (last 14 snapshots), rank 7 and 30 days ago with the change, 7-day average rank, best rank and date, `isNewBestRank`, days in the chart and a `trend` (rising / falling / stable)**. You get a weekly or monthly view on every row without keeping a database of your own.

**Chart reports across countries**. Turn on `includeChartReport` (or `chartReportOnly`) and get one row per chart that answers the market questions: **which developers own the chart, which apps are global hits, which are local breakouts (top 10 in one country only), what is #1 in each country**, how many charting apps launched in the last 90 days, paid / in-app purchase / ads share and ratings, plus what changed since yesterday.

**ASO keyword research**: Give it a seed word like `budget` and get the search terms people actually type in the App Store and Google Play (from the stores' own autocomplete), each with a **popularity score, a difficulty score, an opportunity score, the top 5 apps ranking for it and where your app ranks**.

**Keyword rank tracking (ASO)**. Give it search terms like `habit tracker` or `vpn` and get where every app ranks in **App Store and Google Play search results**, per country, with day-over-day rank changes. Also **track your own app (or competitors) across all 122 App Store countries in one run** with `"countries": ["all"]` + `trackApps`, and get a **country rank map** (best country, top-10 countries, countries where you're not ranked), and every row carries **ratings, rating count, version, last update and (Google Play) installs**.

### Why use it

- 🍏🤖 **Both stores in one dataset**: Apple and Google Play rows share the same columns, so you can compare an app's rank on iOS and Android side by side.
- 📈 **Rank history built in**: up to 60 snapshots per chart are kept for you (`historyLength`, default 30). Every row shows the move since the previous run **and** `rankChange7d`, `rankChange30d`, `averageRank7d`, `bestRank`, `isNewBestRank`, `consecutiveSnapshotsInChart` and a `trend`, plus a compact `rankHistory` you can chart directly.
- 🚨 **Changes-only alerts**: get only new entries, apps that moved at least *N* places, and apps that left the chart. Unchanged positions are never charged.
- 🌍 **Many countries and categories at once**: e.g. `us, gb, de, jp, br` × `overall, games, finance, health-fitness`, plus game subgenres like puzzle, casual and strategy. Or `"countries": ["all"]` for every App Store country (122; Google Play 121).
- 🗺️ **Country rank map**: with `trackApps`, the `RANK_MAP` record shows each app's rank in every country, its best country and the countries where it's top 10 or not ranked at all. Spot your strongest and weakest markets at a glance.
- 🔎 **Keyword search rankings (ASO)**: `keywords` gives you each app's position in App Store and Google Play search for your terms, in every country you list, with `rankChange` vs the previous run. Combine with `trackApps` to follow just your app and competitors.
- 💡 **Keyword discovery with popularity & difficulty**: `suggestKeywordsFor` collects App Store and Google Play autocomplete suggestions (seed + a…z), then scores each keyword: popularity (how few letters users type before the store suggests it), difficulty (how strong the top-10 apps are) and opportunity (popular but beatable).
- 🧭 **Chart report (market roll-up)**: one `chart-report` row per store × chart × category (or keyword) across all countries: top developers by chart slots and top-10 slots, top-5 developer share, **global hits**, **local breakouts**, #1 app per country, genre mix (English names in every country), paid / IAP / ads share, ratings, app age and new launches, `sinceLastRun` (new top-10 entries, biggest climbers, rising apps) and plain-English `opportunitySignals`.
- 🎯 **App rank tracking**: list your app and competitors in `trackApps` and get one row per chart and country, including `not-ranked` rows where an app is missing.
- ⭐ **Ratings & details on both stores**: rating, rating count, version, last update date and content rating for Apple and Google Play, plus installs, review count, in-app purchase and ads flags for Google Play.
- 🧾 **Useful fields**: bundle ID / package name, developer, price, currency, genre, release date, store URL and icon.

### Use cases

- **App founders & ASO consultants**: find keywords for a new app or a metadata update, popular enough to matter but not owned by apps with 100k+ ratings.
- **ASO & UA teams**: see daily movement for your app and your competitors in every market.
- **Mobile game studios & publishers**: spot rising games in a subgenre before they peak.
- **Investors & market analysts**: find breakout apps early (new entries in top grossing charts).
- **Founders deciding which market to enter or localise for**: run `chartReportOnly` on your category in 10–20 countries and see where the chart is fragmented, where newcomers still break in, and which local apps lead each country.
- **Agencies & lead generation**: list developers whose apps are climbing the charts right now.
- **Journalists & researchers**: build historical chart datasets across countries.

### Input example

```json
{
  "stores": ["apple", "google"],
  "countries": ["us", "gb", "de"],
  "charts": ["top-free", "top-grossing"],
  "categories": ["overall", "games-puzzle", "finance"],
  "maxRank": 100,
  "mode": "changes",
  "minRankChange": 10,
  "stateKey": "daily-markets"
}
```

Categories: `overall`, `books`, `business`, `developer-tools`, `education`, `entertainment`, `finance`, `food-drink`, `games`, `graphics-design`, `health-fitness`, `lifestyle`, `medical`, `music`, `navigation`, `news`, `photo-video`, `productivity`, `reference`, `shopping`, `social`, `sports`, `travel`, `utilities`, `weather`, and game subgenres `games-action`, `games-adventure`, `games-casual`, `games-board`, `games-card`, `games-casino`, `games-family`, `games-music`, `games-puzzle`, `games-racing`, `games-role-playing`, `games-simulation`, `games-sports`, `games-strategy`, `games-trivia`, `games-word`. You can also use raw store IDs: `apple:6014`, `google:GAME_PUZZLE`.

Charts: `top-free`, `top-paid`, `top-grossing` (both stores) and `top-free-ipad`, `top-paid-ipad`, `top-grossing-ipad` (Apple only).

Example: where do my app and two competitors rank in 5 markets today?

```json
{
  "stores": ["apple", "google"],
  "countries": ["us", "gb", "de", "fr", "jp"],
  "charts": ["top-free", "top-grossing"],
  "trackApps": ["Duolingo", "com.babbel.mobile.android.en", "284882215"],
  "maxRank": 200
}
```

`trackApps` accepts an Apple numeric ID (`284882215` or `id284882215`), a bundle / Google Play package ID (`com.spotify.music`), or part of the app name (`Duolingo`). Names are the easiest way to match the same app on both stores.

#### Rank in every country (rank map)

Where does ChatGPT rank in the top free chart in **every** App Store and Google Play country?

```json
{
  "stores": ["apple", "google"],
  "countries": ["all"],
  "charts": ["top-free"],
  "trackApps": ["ChatGPT"],
  "maxRank": 50
}
```

That's 243 charts (122 Apple + 121 Google Play countries) in about 1.5 minutes. Real result (October 2026): ChatGPT is in the App Store top 50 in 116 of 122 countries and top 10 in 103; on Google Play it's #1 in Germany. The dataset gets one row per chart and country (rank or `not-ranked`), and the key-value store gets a `RANK_MAP` record:

```json
{
  "trackedApp": "ChatGPT",
  "store": "apple",
  "chart": "top-free",
  "category": "overall",
  "countriesChecked": 122,
  "rankedIn": 116,
  "bestRank": 1,
  "bestCountry": "in",
  "top10Countries": ["in", "mx", "dz", "ai", "ao", "at", "... 103 countries"],
  "notRankedIn": ["ru", "cn", "by", "hk", "mo", "ve"],
  "ranks": { "us": 3, "gb": 4, "de": 4, "in": 1, "ru": null, "...": "..." }
}
```

Countries run biggest markets first (US, UK, Germany, Japan, France, ...), so if a run hits its timeout the important countries are already done; the actor stops cleanly before the timeout and saves results, state and `SUMMARY` (`stoppedEarly: true`). `"all"` also works with `keywords` for keyword ranks in every country.

#### Keyword rank tracking (ASO)

Where do my app and competitors rank for my target keywords in the US and UK, on both stores?

```json
{
  "stores": ["apple", "google"],
  "countries": ["us", "gb"],
  "keywords": ["habit tracker", "daily planner", "streaks"],
  "trackApps": ["HabitKit", "Finch", "com.habitnow"],
  "maxRank": 100,
  "stateKey": "aso-keywords"
}
```

When `keywords` is set the actor tracks search rankings instead of top charts (`charts` and `categories` are ignored; run a separate task for charts). Each row has `chart: "keyword-search"`, the `keyword`, the `rank` and `rankSource`:

- **Apple**: `app-store-search` = the exact order the App Store shows for the first ~12 results; positions after that come from Apple's public iTunes Search API (`itunes-search-api`), up to 200. In our checks the API order matched the App Store for 9 of the top 10 apps, usually within 1–3 places.
- **Google Play**: `google-play-search` = the order the Play Store shows. Google Play shows **at most 30 results per keyword**, so Google rows stop at rank 30.

Leave out `trackApps` to get the full result list (great for keyword research: who owns this term, how many ratings do they have, when did they last update). Add `"mode": "changes"` and a daily schedule to get alerts only when an app enters, leaves or moves on a keyword.

Example keyword row:

```json
{
  "store": "google",
  "country": "us",
  "chart": "keyword-search",
  "keyword": "habit tracker",
  "rank": 1,
  "previousRank": 2,
  "rankChange": 1,
  "status": "up",
  "appId": "org.isoron.uhabits",
  "appName": "Loop Habit Tracker",
  "developer": "Álinson S Xavier",
  "rating": 4.72,
  "ratingCount": 63401,
  "installs": "5,000,000+",
  "rankSource": "google-play-search",
  "url": "https://play.google.com/store/apps/details?id=org.isoron.uhabits"
}
```

#### Keyword discovery (ASO keyword research)

Which "budget" keywords do people search for in the US, how hard are they, and where does YNAB rank for them?

```json
{
  "stores": ["apple", "google"],
  "countries": ["us"],
  "suggestKeywordsFor": ["budget"],
  "trackApps": ["YNAB"],
  "maxSuggestions": 50
}
```

For each store and country the actor asks the store's search autocomplete for the seed and for `seed a` … `seed z`, keeps the most prominent suggestions (`maxSuggestions`, default 50) and scores each one:

| Field | Meaning |
|---|---|
| `popularity` (1–100) | After how many letters the store suggests this exact keyword: 100 = after the first letter at the top of the list, −10 per extra letter, −2 per position. `minPrefix` shows the prefix, e.g. `"bu"`. Popular searches are suggested earlier. |
| `difficulty` (1–100) | App Store: 70% strength of the top-10 apps (median rating count on a log scale, 1M ratings ≈ 100) + 30% share of top-10 titles containing every word of the keyword. Google Play: title share + average rating (Google search pages don't show rating counts). |
| `opportunity` | `popularity × (1 − difficulty/120)`: high = popular and beatable. Rows are sorted by it. |
| `topApps` | Top 5 apps for the keyword (App Store: with rating and rating count). |
| `trackedApps` | With `trackApps`: your app's rank for this keyword (App Store up to 200, Google Play up to 30). |

Real row (App Store US, October 2026):

```json
{
  "type": "keyword-suggestion",
  "store": "apple",
  "country": "us",
  "keyword": "budget app",
  "seeds": ["budget"],
  "suggestPosition": 1,
  "popularity": 82,
  "minPrefix": "bu",
  "searchResults": 192,
  "top10TitleMatches": 3,
  "top10AvgRating": 4.73,
  "top10MedianRatingCount": 23301,
  "top10MaxRatingCount": 396595,
  "difficulty": 60,
  "opportunity": 41,
  "topApps": [
    { "rank": 1, "appName": "EveryDollar: Budget Management", "developer": "The Lampo Group Incorporated", "rating": 4.73, "ratingCount": 84128 },
    { "rank": 2, "appName": "Fleur - Budget Planner App", "developer": "Akash Jain", "rating": 4.8, "ratingCount": 12969 }
  ],
  "trackedApps": [{ "trackedApp": "YNAB", "rank": 6, "appName": "YNAB" }]
}
```

A `KEYWORD_IDEAS` record in the key-value store lists the top 15 keywords per store and country. Popularity and difficulty are transparent heuristics from public store data, not Apple's private search volume. Use them to compare keywords against each other. Discovery takes about 1–2 minutes per store and country with the defaults; `expandAlphabet: false` or `measurePopularity: false` makes it faster.

#### Chart report (who owns the chart, global hits, local breakouts)

```json
{
  "stores": ["apple", "google"],
  "countries": ["us", "gb", "de", "fr", "jp", "br"],
  "charts": ["top-free"],
  "maxRank": 50,
  "chartReportOnly": true
}
```

Real result (October 2026, 2 report rows, shortened):

| | App Store top free | Google Play top free |
|---|---|---|
| Distinct apps / developers in 6 countries | 188 / 156 | 200 / 168 |
| Top developers by chart slots | Google 36 (9 apps), Microsoft 19, TikTok 10 | TikTok 16 (7 apps), Meta 11, Microsoft 10 |
| Top-5 developer share | 26.7% | 17.3% |
| Global hits (all 6 countries) | ChatGPT (median #3.5), Google Gemini, Claude by Anthropic | ChatGPT (median #2), Instagram, CapCut |
| #1 per country | GB Lloyds Mobile Banking, US Muse from Meta, FR + DE Claude by Anthropic, JP Bump, BR e-Título | FR + DE ChatGPT, JP TikTok Lite |
| Released in the last 90 days | 4 of 188 apps | 10 of 194 apps |
| In-app purchases / ads | - | 45.7% / 49% of slots |

`opportunitySignals` turns this into sentences such as *"15 local breakouts (top 10 in at most 1 country), e.g. Lloyds Mobile Banking (GB #1)... candidates to expand or to copy locally."* Each report also has `genreMix`, `ratings` (median rating and rating count), `freshness.newestApps` and, from the second run on, `sinceLastRun` (new entries, biggest climbers, new top-10 entries, rising apps). Works for keyword searches too (`keywords` + `chartReportOnly` = who owns a search term across countries).

#### Rank history (daily schedule)

With a daily schedule and the same `stateKey`, each row gets these extra fields (example from a test with a breakout app):

```json
{
  "rank": 3,
  "appName": "ChatGPT",
  "rankChange": 6,
  "rank7dAgo": 9,
  "rankChange7d": 6,
  "rank30dAgo": 22,
  "rankChange30d": 19,
  "averageRank7d": 6,
  "bestRank": 3,
  "bestRankAt": "2026-10-07T08:00:00.000Z",
  "isNewBestRank": true,
  "snapshotsInChart": 8,
  "consecutiveSnapshotsInChart": 5,
  "enteredChartLast7d": false,
  "trend": "rising",
  "historySnapshots": 9,
  "historySince": "2026-09-02T08:00:00.000Z",
  "rankHistory": [{ "at": "2026-09-27T08:00:00.000Z", "rank": 15 }, { "at": "2026-10-02T08:00:00.000Z", "rank": 9 }, { "at": "2026-10-07T08:00:00.000Z", "rank": 3 }]
}
```

- `rank7dAgo` / `rank30dAgo` come from the snapshot closest to 7 / 30 days ago (±2 / ±6 days); `null` when the app wasn't in the chart then (see `enteredChartLast7d`) or no run happened then.
- `trend` compares the average rank of the last 3 snapshots with the 3 before (an absent app counts as last + 1). It needs 6 snapshots.
- History starts with your first run: the stores don't publish past rankings. Works for charts and for keyword search tracking.

### Output example

```json
{
  "store": "apple",
  "country": "us",
  "chart": "top-free",
  "category": "overall",
  "rank": 1,
  "previousRank": 30,
  "rankChange": 29,
  "status": "up",
  "appId": "6760173601",
  "bundleId": "com.facebook.hatch",
  "appName": "Muse from Meta",
  "developer": "Meta Platforms, Inc.",
  "developerUrl": "https://apps.apple.com/us/developer/meta-platforms-inc/id284882218",
  "price": 0,
  "currency": "USD",
  "free": true,
  "genre": "Productivity",
  "releaseDate": "2026-09-08",
  "rating": 4.71,
  "ratingCount": 18523,
  "version": "1.3.0",
  "lastUpdated": "2026-10-02",
  "contentRating": "12+",
  "url": "https://apps.apple.com/us/app/muse-from-meta/id6760173601",
  "icon": "https://is1-ssl.mzstatic.com/image/thumb/.../100x100bb.png",
  "previousSnapshotAt": "2026-10-04T08:00:00.000Z",
  "scrapedAt": "2026-10-05T08:00:00.000Z"
}
```

`status` values:

- `first-run`: there's no previous snapshot yet. The first run is your baseline.
- `new`: the app wasn't in the chart last run.
- `up`, `down`, `same`: the app moved, and `rankChange` is positive when it climbed.
- `dropped`: the app was in the chart last run but isn't now. `previousRank` holds its last position.
- `not-ranked`: (only with `trackApps`) the tracked app isn't in this chart (or these search results) right now; `trackedApp` says which one.

Google Play rows also include `installs` (e.g. "10,000,000+"), `minInstalls`, `reviewCount`, `inAppPurchases` and `containsAds`. Set `includeDetails` to `false` if you only need ranks and want the fastest run.

The `SUMMARY` record in the key-value store lists each chart with its counts of new entries, movers and dropouts.

### Pricing

**$1 per 1,000 chart entries.** No subscription.

Chart report: **$0.02 per report row** (one per store × chart × category or keyword, however many countries). With `chartReportOnly` the chart entries read for it are not charged, so a 6-country, 2-store top-free report costs $0.04.

Keyword discovery: **$3 per 1,000 scored keywords** (`keyword-suggestion` event). 50 scored keywords for one store and country cost $0.15.

A full top-100 chart costs $0.10. In changes-only mode you pay only for the rows that changed, which is usually just a few cents a day even when you track many markets.

### Scheduling a daily chart monitor

1. Choose your stores, countries, charts and categories, set `mode` to `changes`, and give the monitor a name in `stateKey`.
2. Create a Schedule in Apify Console (e.g. daily at 08:00 UTC).
3. Add a Slack, email, Google Sheets, webhook, Zapier or Make integration to get breakout apps automatically.

Use a different `stateKey` for each separate schedule so their snapshots don't overwrite each other.

### Notes & limits

- Apple's public feeds return up to **100 positions** per chart. Google Play returns up to **200**.
- Keyword search: Apple up to 200 positions (exact App Store order for the first ~12), Google Play up to 30. Search results are for a signed-out user in that country; personalised results on a real phone can differ slightly.
- Google Play has no iPad charts, and it has no "family" game subgenre. Combinations a store doesn't offer are skipped with a warning.
- Keyword discovery: Google Play suggestions depend mainly on `language`, so they are similar across countries; App Store suggestions are per storefront.
- Uses only public store charts, search results and autocomplete. No personal data is collected.

### FAQ

#### Can I get historical rankings?

The App Store and Google Play only publish the current chart, so history is built from your own runs: schedule the Actor (daily is typical) with a fixed `stateKey`, and after a week each row carries 7-day changes, after a month 30-day changes and up to 60 snapshots of `rankHistory`. Set `historyLength: 0` to turn it off.

**Can I track where my app ranks in every country?**
Yes. Put your app's name, Apple ID or package name in `trackApps`, add the countries, and schedule the run daily. You get one row per chart and country, including `not-ranked` rows, and `rankChange` vs the previous run.

**Does it include ratings and rating counts for App Store apps?**
Yes. Apple's chart feeds don't contain ratings, so each chart is enriched with one batch call to Apple's public lookup API: `rating`, `ratingCount`, `version`, `lastUpdated` and `contentRating`.

**How do I get Google Play install counts?**
They're included by default (`installs`, `minInstalls`) together with rating count, review count, in-app purchases and ads flags.

**How far down the chart can I go?**
Apple: top 100. Google Play: top 200.

**Can it track App Store keyword rankings (ASO)?**
Yes. Put your search terms in `keywords`, pick countries, and optionally your app and competitors in `trackApps`. Each run outputs the rank per keyword, store and country, with `rankChange` vs the previous run, at $1 per 1,000 rows. A small keyword tracker (10 keywords × 2 stores × 1 country, tracked apps only) costs about a cent per day.

**Can it find new keywords for my app (keyword research)?**
Yes. Put seed words in `suggestKeywordsFor` (e.g. `budget`, `expense`). You get the App Store and Google Play autocomplete suggestions for each seed and seed + a…z, with popularity, difficulty and opportunity scores, the top 5 apps for each keyword and, with `trackApps`, your own rank. Pick high-opportunity keywords for your title, subtitle and keyword field, then track them daily with `keywords`.

**Is the popularity score Apple's search volume?**
No. Apple's search popularity is only visible inside Apple Search Ads. Our score measures how early the store's own autocomplete suggests a keyword, which tracks how often people search it. It is good for ranking keywords against each other, not for absolute search counts.

**Are keyword ranks exactly what I see on my phone?**
Google Play ranks are the Play Store's own order. For Apple, the first ~12 positions are the App Store's own order; deeper positions come from Apple's public search API, which is close but can differ by a few places. `rankSource` on every row tells you which. Search Ads placements are not counted as ranks.

**Is there historical data?**
History starts with your first run. Schedule the actor daily and the dataset becomes your own chart history, with rank changes computed for you.

#### Which developers dominate the App Store / Google Play top charts?

Turn on `chartReportOnly`, pick the chart, category and countries. The `topDevelopers` field lists developers by chart slots across all countries (with top-10 slots, number of apps and countries), and `top5DevelopersSlotSharePct` tells you how concentrated the chart is. `globalHits` and `localBreakouts` show which apps chart everywhere and which only in one market.

#### Can I see my app's rank in every country at once?

Yes. Set `"countries": ["all"]` and put your app in `trackApps`. You get your rank in all 122 App Store countries and 121 Google Play countries, plus a `RANK_MAP` record with your best country, top-10 countries and the countries where you're not in the chart. With `trackApps`, only matched rows are charged, so a daily all-countries check of one app costs a few cents.

#### How long does an all-countries run take?

About 1.5 minutes for one chart on both stores (243 charts). Each extra chart or keyword adds roughly the same. Keep the default run timeout or raise it for many charts × all countries.

### More tools from the same developer

- [Salesforce AppExchange Scraper & Listing Monitor](https://apify.com/signalscope-data/appexchange-tracker): AppExchange apps and agents with ratings, reviews, pricing and versions, plus new-listing and change alerts.
- [Chrome, Firefox & VS Code Extensions Tracker](https://apify.com/signalscope-data/extension-marketplaces-tracker): installs, ratings and rank changes for IDE and browser extensions, with new-release alerts.
- [App Store & Google Play Reviews Scraper](https://apify.com/signalscope-data/app-reviews-scraper): reviews, ratings and new-review monitoring for any app.
- [Company Jobs Scraper](https://apify.com/signalscope-data/ats-jobs-scraper): every open job from Workday, Greenhouse, Lever, Ashby & more, with new-job alerts.
- [Shopify Products Scraper & Price Change Monitor](https://apify.com/signalscope-data/shopify-store-monitor): full catalogs plus price-drop / restock alerts.
- [Telegram Channel Scraper & Keyword Monitor](https://apify.com/signalscope-data/telegram-channel-monitor): posts, views and reactions from public channels, with keyword alerts.

# Actor input Schema

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

Which stores to track.

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

2-letter country codes, e.g. "us", "gb", "de", "jp", "br". Each country is a separate chart. Use "all" for every App Store country (122, biggest markets first; Google Play 121). With "trackApps" you also get a RANK_MAP record: each app's rank in every country, best country and countries where it is not ranked.

## `charts` (type: `array`):

Chart types. iPad charts exist only on Apple and are skipped for Google Play.

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

"overall" (all apps) or category names: books, business, developer-tools, education, entertainment, finance, food-drink, games, graphics-design, health-fitness, lifestyle, medical, music, navigation, news, photo-video, productivity, reference, shopping, social, sports, travel, utilities, weather, games-action, games-adventure, games-casual, games-board, games-card, games-casino, games-family, games-music, games-puzzle, games-racing, games-role-playing, games-simulation, games-sports, games-strategy, games-trivia, games-word. Store-specific IDs also work: "apple:6014", "google:GAME_PUZZLE".

## `maxRank` (type: `integer`):

How many positions to collect per chart (Apple provides up to 100, Google Play up to 200).

## `keywords` (type: `array`):

Track where apps rank in App Store and Google Play SEARCH results for these keywords (e.g. "habit tracker", "vpn"), per country. When set, the actor tracks keyword rankings instead of top charts ("charts" and "categories" are ignored). Apple: exact App Store order for the first ~12 results, then the iTunes Search API order up to 200. Google Play: the up-to-30 results the Play Store shows. Combine with "trackApps" to follow only your own apps and competitors.

## `trackApps` (type: `array`):

Only output these apps: Apple numeric ID ("284882215" or "id284882215"), bundle / Google Play package ID ("com.spotify.music"), or part of the app name ("Duolingo"). Every chart/country where a tracked app is missing gets a 'not-ranked' row, so you see where your app (or a competitor) ranks across all countries in one table.

## `suggestKeywordsFor` (type: `array`):

Short, generic seed words such as "habit", "budget" or "meditation". For each store and country the actor collects the store's search autocomplete suggestions for the seed (and seed + a…z) and outputs one row per suggested keyword with popularity (how few letters users type before the store suggests it, 1–100), difficulty (strength of the apps already ranking, 1–100), opportunity, the top 5 ranking apps and, with "Track specific apps", where your apps rank for it.

## `expandAlphabet` (type: `boolean`):

Also query "seed a" … "seed z" (27 autocomplete lookups per seed) to find long-tail keywords. Turn off for a quick look at the top suggestions only.

## `maxSuggestions` (type: `integer`):

How many discovered keywords to score and output per store × country (the most prominent suggestions first).

## `measurePopularity` (type: `boolean`):

Probe shorter prefixes of every keyword to find after how many letters the store suggests it (the popularity score). Adds a few fast autocomplete lookups per keyword.

## `includeCompetition` (type: `boolean`):

Run one store search per keyword and score the apps already ranking: top-10 title matches, average rating, median rating count (App Store) and a 1–100 difficulty score.

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

'Full chart' outputs every position with previousRank/rankChange. 'Changes only' outputs just new entries, apps that moved at least 'Min rank change' places, and apps that dropped out. The first run of a monitor always outputs the full chart as a baseline.

## `minRankChange` (type: `integer`):

Used in 'Changes only' mode: minimum number of places an app must move to be reported.

## `includeDropped` (type: `boolean`):

Output a 'dropped' record for apps that were in the chart last run but are not any more.

## `stateKey` (type: `string`):

The previous snapshot is stored under this name and used to compute rank changes. Use a different name for each separate schedule.

## `historyLength` (type: `integer`):

How many past runs of this monitor (same stateKey) are kept per chart / keyword to build rank history. Every row then gets rankHistory (last 14 snapshots), rank7dAgo / rankChange7d, rank30dAgo / rankChange30d, averageRank7d, bestRank (+ date), isNewBestRank, snapshotsInChart, consecutiveSnapshotsInChart, enteredChartLast7d and trend (rising / falling / stable, from the last 6 snapshots). Schedule the Actor daily: 30 = one month of daily history. History starts with your first run (the stores do not publish past rankings). 0 = off.

## `includeChartReport` (type: `boolean`):

Also output one chart-report row per store × chart × category (or keyword) across all countries of the run (recordType = "chart-report"): which developers own the most chart slots (and top-10 slots), developer concentration (top-5 share), global hits (apps charting in the most countries, median rank, #1 countries), local breakouts (top 10 in only a few countries), the #1 app per country, genre mix (English genre names), paid share, in-app purchase / ads share (Google Play), median rating and rating count, app age and apps released in the last 90 / 365 days, and plain-English opportunity signals. With a previous run of the same stateKey it adds sinceLastRun: new entries, biggest climbers, new top-10 entries and rising apps. Also saved as the CHART_REPORT record.

## `chartReportOnly` (type: `boolean`):

Output only the chart-report rows (no per-app chart rows). Each report is charged as one chart-report event; the chart entries read for it are not charged. Rank history and state are still updated, so a daily report-only schedule still gets sinceLastRun.

## `includeDescription` (type: `boolean`):

Add the store description/summary text to every record (makes the dataset larger).

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

Language code for Google Play titles and descriptions, e.g. "en", "de", "ja".

## `includeDetails` (type: `boolean`):

Add rating, rating count, version, last update date and content rating (Apple, via the iTunes lookup API) plus installs, review count, in-app purchases and ads flags (Google Play). Turn off for the fastest runs.

## Actor input object example

```json
{
  "stores": [
    "apple",
    "google"
  ],
  "countries": [
    "us",
    "gb"
  ],
  "charts": [
    "top-free"
  ],
  "categories": [
    "overall"
  ],
  "maxRank": 100,
  "expandAlphabet": true,
  "maxSuggestions": 50,
  "measurePopularity": true,
  "includeCompetition": true,
  "mode": "all",
  "minRankChange": 5,
  "includeDropped": true,
  "stateKey": "default",
  "historyLength": 30,
  "includeChartReport": false,
  "chartReportOnly": false,
  "includeDescription": false,
  "language": "en",
  "includeDetails": true
}
```

# 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 = {
    "countries": [
        "us",
        "gb"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("signalscope-data/app-charts-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 = { "countries": [
        "us",
        "gb",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("signalscope-data/app-charts-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 '{
  "countries": [
    "us",
    "gb"
  ]
}' |
apify call signalscope-data/app-charts-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,signalscope-data/app-charts-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/O02y6ugyGvhaThXMf/builds/lr9Vm8IDaduBdfQsA/openapi.json
