# ASO Rank Tracker — App Store Keyword Rankings & Alerts (`acebuilds/aso-rank-radar`) Actor

Track where your app and competitors rank for App Store keywords, on a schedule. Snapshot mode returns current rankings; watchlist mode reports only what changed — rank moves, new top-10 entrants, and drop-offs. For app publishers and ASO/mobile-growth agencies.

- **URL**: https://apify.com/acebuilds/aso-rank-radar.md
- **Developed by:** [Ace](https://apify.com/acebuilds) (community)
- **Categories:** SEO tools, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$10.00 / 1,000 keyword trackeds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## ASO Rank Tracker — App Store Keyword Rankings & Change Alerts

**Track where your app and your competitors rank for App Store keywords — and get alerted the moment those rankings move.**

Most App Store keyword trackers hand you a flat CSV snapshot and leave you to diff it yourself. This actor does both: pull current rankings **and** — on a schedule — tell you exactly **what changed** since last time. Built for **app publishers** and **ASO / mobile-growth agencies** who need to watch keyword positions without paying enterprise-SaaS prices.

> iOS (Apple App Store) is supported today via Apple's official iTunes Search API. Google Play tracking is a planned fast-follow.

### What it does

1. Searches the App Store for each of your **keywords** in a given **storefront** (country).
2. Returns the **top-ranked apps** per keyword — name, developer, rating, review count, price, genre — with each app's **rank**.
3. If you provide your app's ID (and competitors'), it reports **exactly where each ranks** for every keyword.
4. In **watchlist mode**, it remembers the last run and emits only the **changes**.

### Modes

| Mode | What you get |
|---|---|
| `snapshot` (default) | Current top-N rankings for each keyword, every run |
| `watchlist` | Only what changed since the last run — for scheduled tracking |

#### Watchlist change types

| `changeType` | Meaning |
|---|---|
| `rank_move` | A tracked app moved up or down (`delta` is positive when it **improved**) |
| `new_entrant` | An app newly entered the top-N window for a keyword |
| `dropped_out` | An app fell out of the top-N window |
| `baseline` | First run for a keyword — current ranking saved as the baseline |
| `no_change` | Nothing changed for that keyword this run (free) |

Set a **Schedule** in Apify (e.g. daily) and wire the dataset to a webhook/Slack for automatic rank-move alerts.

### Input

| Field | Required | Notes |
|---|---|---|
| `keywords` | ✅ | Search terms to track. Each keyword = one billable unit per run. |
| `appId` | optional | Your app's numeric iTunes ID (the number in `apps.apple.com/app/id‹…›`). |
| `competitorAppIds` | optional | Competitor iTunes IDs to track alongside yours. |
| `country` | optional | Storefront country code (default `us`). Rankings are storefront-specific. |
| `topN` | optional | Top apps per keyword + the window for entrant/drop detection (default 10). |
| `resultsPerKeyword` | optional | How deep to scan (1–200, default 50). Must be ≥ `topN`. |
| `mode` | optional | `snapshot` or `watchlist` (default `snapshot`). |
| `watchlistName` | optional | Namespaces the baseline in watchlist mode. |
| `requestDelayMs` | optional | Delay between keyword lookups (default 500ms) to respect Apple's rate limit. |

**Finding your app ID:** open your app in the App Store; the URL ends in `.../id1459969523` → `1459969523`.

### Output

`recordType: "ranking"` (or `"baseline"`) — one row per top app per keyword:

```json
{
  "recordType": "ranking",
  "keyword": "meditation",
  "rank": 3,
  "appId": 571800810,
  "name": "Calm",
  "developer": "Calm.com",
  "rating": 4.77,
  "ratingCount": 1965687,
  "price": 0,
  "genre": "Health & Fitness",
  "isTracked": false,
  "store": "apple",
  "country": "us"
}
```

`recordType: "change"` — one row per detected change (watchlist mode). See the **Rankings** and **Changes** dataset views.

### Pricing

**$0.01 per keyword tracked.** You are charged once per **keyword scanned** per run (`keyword-tracked`), in both modes — no subscription, no per-run fee. Keywords that error (e.g. a transient rate limit) are **not** charged.

| What you run | Cost |
|---|---|
| One-off snapshot, 20 keywords | **$0.20** |
| Daily watchlist, 20 keywords | **~$6 / month** |
| Weekly watchlist, 50 keywords | **~$2 / month** |

### Notes & limits

- **Ranking = App Store search order.** Position in Apple's search results for a term is the keyword ranking — the same signal ASO tools use.
- **Top 200 only.** Apple's Search API returns up to 200 results per query; an app below that is reported as not found for the keyword.
- **Rate limits.** Apple limits the Search API (~20 requests/min); `requestDelayMs` keeps runs polite. Rate-limited keywords retry with backoff, then emit a free error row if still failing.
- **Data source:** Apple's public iTunes Search API (`itunes.apple.com/search`). No API key required.

# Actor input Schema

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

App Store search terms to track rankings for (e.g. "meditation", "budget planner", "photo editor"). Each keyword is one billable unit per run.

## `appId` (type: `string`):

Numeric iTunes track ID of the app you want to track (the number in an App Store URL: apps.apple.com/app/id‹THIS›). If set, each keyword reports where this app ranks. Leave empty to just see the top apps per keyword.

## `competitorAppIds` (type: `array`):

Numeric iTunes track IDs of competitor apps to track alongside yours. In watchlist mode you'll be alerted when any of them move.

## `country` (type: `string`):

Two-letter App Store country code (e.g. us, gb, de, jp). Rankings are storefront-specific.

## `topN` (type: `integer`):

How many top-ranked apps to return per keyword (also the window used to detect new entrants / drop-offs in watchlist mode).

## `resultsPerKeyword` (type: `integer`):

How deep to scan the App Store per keyword (1–200). Must be ≥ Top N. Scan deeper so a tracked app ranked below the top window is still found.

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

snapshot (default) = return current rankings every run. watchlist = remember the last run and report only what CHANGED (rank moves, new top-N entrants, drop-offs). Watchlist is built for scheduled runs; the first run saves a baseline.

## `watchlistName` (type: `string`):

Names the baseline this run diffs against, so you can keep multiple independent watchlists. Ignored in snapshot mode.

## `minRankDelta` (type: `integer`):

Smallest rank change reported as a move. Small daily drift is noise, not signal — the default of 3 never reports a ±1 or ±2 wobble. Set to 1 to report every move (noisy). Ignored in snapshot mode.

## `rankDeltaFraction` (type: `number`):

Scales the reporting threshold with rank depth, so a move near the top matters more than the same move deep down. At 0.2, a move from rank 3 must cover 3 places to report, but a move from rank 43 must cover 9. Set to 0 to use the flat minimum at every depth. Ignored in snapshot mode.

## `requestDelayMs` (type: `integer`):

Milliseconds to wait between keyword lookups. Apple rate-limits the Search API (~20/min); the default keeps runs well-behaved. Raise it if you track many keywords and see rate-limit errors.

## Actor input object example

```json
{
  "keywords": [
    "meditation",
    "habit tracker"
  ],
  "appId": "389801252",
  "competitorAppIds": [],
  "country": "us",
  "topN": 10,
  "resultsPerKeyword": 50,
  "mode": "snapshot",
  "watchlistName": "default",
  "minRankDelta": 3,
  "rankDeltaFraction": 0.2,
  "requestDelayMs": 500
}
```

# 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 = {
    "keywords": [
        "meditation",
        "habit tracker"
    ],
    "competitorAppIds": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("acebuilds/aso-rank-radar").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 = {
    "keywords": [
        "meditation",
        "habit tracker",
    ],
    "competitorAppIds": [],
}

# Run the Actor and wait for it to finish
run = client.actor("acebuilds/aso-rank-radar").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "meditation",
    "habit tracker"
  ],
  "competitorAppIds": []
}' |
apify call acebuilds/aso-rank-radar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=acebuilds/aso-rank-radar",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/35vmcnj0dG5H0g8md/builds/3kBcpM1RWe1hc4zcN/openapi.json
