# App Store Rank Tracker - Apple Keyword & Category Ranking (ASO) (`constant_quadruped/app-store-rank-tracker`) Actor

Track an iOS app key word ranking position, category rank, rating and version with run-over-run deltas. Zero-auth Apple iTunes Search + RSS + Lookup APIs.

- **URL**: https://apify.com/constant\_quadruped/app-store-rank-tracker.md
- **Developed by:** [CQ](https://apify.com/constant_quadruped) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 app rank record returneds

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## App Store Rank Tracker — Apple Keyword & Category Ranking (ASO)

Track exactly where your iOS app ranks in the Apple App Store — for the **keywords that matter to you**, in its **category top charts**, with **run-over-run deltas** so you can see whether your ASO work is actually moving the needle.

Built for app teams and ASO agencies who need a cheap, reliable, scriptable rank tracker without standing up scrapers or paying enterprise ASO-tool prices.

### What it does

For each app you give it, every run reports:

- **Keyword ranking position** — the app's 1-based position in App Store search results for each keyword you track, plus the apps Apple ranks above you (your direct ASO competitors for that term).
- **Category rank** — the app's position in its primary-genre top charts (top free / top paid / top grossing).
- **Rating & version snapshot** — current average rating, rating count, current-version rating, current version string and its release date, and price.
- **Deltas since last run** — every keyword position and category position is compared to the previous run: did it move **up**, **down**, stay **flat**, go **lost** (dropped out of results), or is it **new**? Rating and version changes are tracked too.

State is persisted in the Actor's key-value store, so as long as you run it on a schedule (daily/weekly), each run shows movement vs. the previous one.

### Data source — 100% real, zero-auth Apple APIs

This Actor hits Apple's own official public endpoints — the same ones `apps.apple.com` uses. No headless browser, no proxies, no third-party scraper, no mock data. Output is fully **input-dependent**: different apps / keywords / countries return different real rankings.

| Signal | Apple endpoint |
| --- | --- |
| Keyword position | `itunes.apple.com/search?term=...&entity=software&country=...` |
| Category rank | `itunes.apple.com/<cc>/rss/topfreeapplications/limit=200/genre=<id>/json` |
| Rating / version / price | `itunes.apple.com/lookup?id=...&country=...` |

These endpoints are free and require no authentication or API key.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `appIds` | array | App Store numeric IDs or full app URLs to track. |
| `keywords` | array | Keywords/phrases to look up each app's ranking position for. |
| `searchTerms` | array | (Optional) App names to auto-resolve to IDs when you don't have the numeric ID. |
| `country` | string | 2-letter storefront code. Rankings are storefront-specific. Default `us`. |
| `charts` | array | Category charts to check: `topfree`, `toppaid`, `topgrossing`. Default `["topfree"]`. |
| `includeCategoryRank` | boolean | Include category top-charts rank. Default `true`. |
| `searchLimit` | integer | Search depth per keyword, 10–200. Default `100`. |
| `categoryChartLimit` | integer | Category chart scan depth, 50–200. Default `200`. |

#### Example input

```json
{
    "appIds": ["281796108"],
    "keywords": ["notes", "note taking", "todo list", "evernote"],
    "country": "us",
    "charts": ["topfree"]
}
````

### Output

One dataset item per tracked app. Key fields:

```json
{
    "appId": "281796108",
    "trackName": "Evernote - Notes Organizer",
    "country": "us",
    "primaryGenre": "Productivity",
    "averageUserRating": 4.4,
    "currentVersion": "10.x",
    "keywordRanks": [
        {
            "keyword": "evernote",
            "found": true,
            "position": 1,
            "totalResults": 22,
            "topCompetitors": [],
            "delta": { "current": 1, "previous": 2, "change": 1, "improved": true, "status": "up" }
        }
    ],
    "categoryRanks": [
        { "chart": "topfree", "genre": "Productivity", "position": 37, "chartSize": 200,
          "delta": { "current": 37, "previous": 41, "change": 4, "improved": true, "status": "up" } }
    ],
    "ratingDelta": { "averageUserRatingChange": 0.0, "userRatingCountChange": 120, "versionChanged": false },
    "isFirstRun": false,
    "scrapedAt": "2026-06-22T..."
}
```

In `delta`, **`change` is positive when the app moved up** (toward #1). `status` is one of `up` / `down` / `flat` / `new` / `not_ranked`.

### Scheduling

Run it on Apify's scheduler (e.g. daily at 9am). Because state persists between runs in the key-value store, every scheduled run gives you a clean "what moved since yesterday" view of your keyword and category rankings.

### Pricing

Pay-per-result: you're charged a small fixed amount per app ranking record written to the dataset. Tracking N apps = N records per run. No proxy or compute surprises.

### Notes & limits

- Apple's storefront RSS top charts cap at 200 entries — apps ranked below 200 in a category show as `not in chart`.
- App Store search results are storefront-specific and can vary slightly by region/device; this Actor uses the public storefront search, which is what most ASO tools track against.
- The Actor throttles itself (~50 req/min) and backs off on Apple rate limits, so large keyword sets simply take a little longer rather than failing.

# Actor input Schema

## `appIds` (type: `array`):

Apple App Store numeric IDs (e.g. 281796108) or full app URLs (e.g. https://apps.apple.com/us/app/evernote/id281796108) for the apps you want to track.

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

Search keywords/phrases to look up each app's ranking position for (e.g. 'notes app', 'todo list', 'project management'). The actor reports the app's 1-based position in App Store search results for each keyword.

## `searchTerms` (type: `array`):

App names to resolve to App Store IDs automatically via the iTunes Search API when you don't have the numeric ID. Each resolved app is then tracked like an appId.

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

2-letter App Store storefront code. Rankings are storefront-specific. Default: us.

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

Which top-charts to look the app up in for category rank: topfree, toppaid, topgrossing. The app is matched within its own primary genre chart.

## `includeCategoryRank` (type: `boolean`):

Also look up each app's position in its primary-genre top-charts feed(s). Turn off to track keyword rankings only.

## `searchLimit` (type: `integer`):

How many App Store search results to scan per keyword when locating the app. Higher = catches lower-ranked apps but slightly slower. Apple caps at 200.

## `categoryChartLimit` (type: `integer`):

How many top-chart entries to scan when locating the app's category rank. Apple caps RSS top-charts at 200.

## Actor input object example

```json
{
  "appIds": [
    "281796108",
    "https://apps.apple.com/us/app/notion/id1232780281"
  ],
  "keywords": [
    "notes",
    "note taking",
    "todo list"
  ],
  "country": "us",
  "charts": [
    "topfree",
    "topgrossing"
  ],
  "includeCategoryRank": true,
  "searchLimit": 100,
  "categoryChartLimit": 200
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per app: name, ID, country, genre, average rating, current version, keywords ranked, best keyword position, average keyword position, and counts of keywords that moved up / down / lost ranking since last 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 = {
    "appIds": [
        "281796108"
    ],
    "keywords": [
        "notes",
        "note taking",
        "evernote"
    ],
    "country": "us",
    "charts": [
        "topfree"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("constant_quadruped/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 = {
    "appIds": ["281796108"],
    "keywords": [
        "notes",
        "note taking",
        "evernote",
    ],
    "country": "us",
    "charts": ["topfree"],
}

# Run the Actor and wait for it to finish
run = client.actor("constant_quadruped/app-store-rank-tracker").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 '{
  "appIds": [
    "281796108"
  ],
  "keywords": [
    "notes",
    "note taking",
    "evernote"
  ],
  "country": "us",
  "charts": [
    "topfree"
  ]
}' |
apify call constant_quadruped/app-store-rank-tracker --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "App Store Rank Tracker - Apple Keyword & Category Ranking (ASO)",
        "description": "Track an iOS app key word ranking position, category rank, rating and version with run-over-run deltas. Zero-auth Apple iTunes Search + RSS + Lookup APIs.",
        "version": "1.0",
        "x-build-id": "RfecEDXqbpHP6oLcE"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/constant_quadruped~app-store-rank-tracker/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-constant_quadruped-app-store-rank-tracker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/constant_quadruped~app-store-rank-tracker/runs": {
            "post": {
                "operationId": "runs-sync-constant_quadruped-app-store-rank-tracker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/constant_quadruped~app-store-rank-tracker/run-sync": {
            "post": {
                "operationId": "run-sync-constant_quadruped-app-store-rank-tracker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "appIds": {
                        "title": "App Store app IDs or URLs",
                        "type": "array",
                        "description": "Apple App Store numeric IDs (e.g. 281796108) or full app URLs (e.g. https://apps.apple.com/us/app/evernote/id281796108) for the apps you want to track.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Keywords to track",
                        "type": "array",
                        "description": "Search keywords/phrases to look up each app's ranking position for (e.g. 'notes app', 'todo list', 'project management'). The actor reports the app's 1-based position in App Store search results for each keyword.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchTerms": {
                        "title": "Search terms to resolve to app IDs (optional)",
                        "type": "array",
                        "description": "App names to resolve to App Store IDs automatically via the iTunes Search API when you don't have the numeric ID. Each resolved app is then tracked like an appId.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "country": {
                        "title": "Storefront country",
                        "type": "string",
                        "description": "2-letter App Store storefront code. Rankings are storefront-specific. Default: us.",
                        "default": "us"
                    },
                    "charts": {
                        "title": "Category charts to check",
                        "type": "array",
                        "description": "Which top-charts to look the app up in for category rank: topfree, toppaid, topgrossing. The app is matched within its own primary genre chart.",
                        "default": [
                            "topfree"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "includeCategoryRank": {
                        "title": "Include category (top-charts) rank",
                        "type": "boolean",
                        "description": "Also look up each app's position in its primary-genre top-charts feed(s). Turn off to track keyword rankings only.",
                        "default": true
                    },
                    "searchLimit": {
                        "title": "Search depth per keyword (10-200)",
                        "minimum": 10,
                        "maximum": 200,
                        "type": "integer",
                        "description": "How many App Store search results to scan per keyword when locating the app. Higher = catches lower-ranked apps but slightly slower. Apple caps at 200.",
                        "default": 100
                    },
                    "categoryChartLimit": {
                        "title": "Category chart depth (50-200)",
                        "minimum": 50,
                        "maximum": 200,
                        "type": "integer",
                        "description": "How many top-chart entries to scan when locating the app's category rank. Apple caps RSS top-charts at 200.",
                        "default": 200
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
