# App Store ASO Keyword & Rankings Scraper (`juramoshkov/app-store-aso-keyword-rankings-scraper`) Actor

Track App Store keyword rankings, app metadata, reviews, and top charts by country using public iTunes endpoints.

- **URL**: https://apify.com/juramoshkov/app-store-aso-keyword-rankings-scraper.md
- **Developed by:** [Jura Moshkov](https://apify.com/juramoshkov) (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

from $1.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/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 Scraper — ASO Keywords, Rankings & Reviews

App Store scraper and ASO keyword tool for the Apple App Store / iOS. Track App Store keyword rankings with a **keyword difficulty score**, app metadata, reviews, ratings, and top charts by country. This Actor uses Apple's public iTunes endpoints, so it is fast, lightweight, and does not need an API key or browser automation.

### What This App Store Scraper Does

- Check App Store keyword rankings for one or more apps across countries, with an ASO keyword difficulty score (0-100).
- Extract app metadata: title, developer, bundle ID, rating, rating count, price, version, update date, icon, screenshots, and App Store URL.
- Scrape recent or helpful App Store reviews.
- Export top free, paid, or grossing App Store charts by country and optional genre.
- Produce normalized dataset rows for ASO research, competitor monitoring, app intelligence, and market tracking.

### Use Cases

- App Store ASO keyword rank tracking
- Competitor app monitoring
- App metadata and screenshot audits
- App review exports for sentiment analysis
- Country-level App Store top charts research
- Daily app intelligence workflows through Apify integrations

### Input

Choose one `mode`:

- `rankings` - checks where each target app ranks for each keyword/country pair.
- `metadata` - extracts app details by numeric App Store app ID or iOS bundle ID.
- `reviews` - extracts App Store reviews by app ID and country.
- `charts` - extracts top free, paid, or grossing app charts.

Example keyword ranking input:

```json
{
  "mode": "rankings",
  "appIds": ["284882215"],
  "keywords": ["social network", "messenger"],
  "countries": ["us", "gb"],
  "maxSearchResults": 50
}
````

Example metadata input:

```json
{
  "mode": "metadata",
  "appIds": ["284882215"],
  "bundleIds": ["com.instagram.ios"],
  "countries": ["us"]
}
```

Example reviews input:

```json
{
  "mode": "reviews",
  "appIds": ["284882215"],
  "countries": ["us"],
  "maxReviews": 100,
  "reviewSortBy": "mostrecent"
}
```

Example top charts input:

```json
{
  "mode": "charts",
  "countries": ["us"],
  "chart": "topfreeapplications",
  "maxChartResults": 100
}
```

### Output

The Actor writes normalized rows to the default Apify dataset. Depending on the mode, rows include:

- `mode`
- `country`
- `keyword`
- `rankPosition`
- `keywordDifficulty` (0-100 ASO difficulty, rankings mode)
- `keywordResultCount`
- `topAppsAvgRatingCount`
- `found`
- `appId`
- `bundleId`
- `title`
- `developer`
- `genre`
- `rating`
- `ratingCount`
- `price`
- `currency`
- `version`
- `updated`
- `url`
- `reviewId`
- `content`
- `author`
- `chart`
- `category`
- `checkedAt`

Example ranking row:

```json
{
  "mode": "rankings",
  "appId": 284882215,
  "bundleId": "com.facebook.Facebook",
  "title": "Facebook",
  "keyword": "social network",
  "country": "us",
  "rankPosition": 42,
  "keywordDifficulty": 78,
  "keywordResultCount": 50,
  "topAppsAvgRatingCount": 1840000,
  "found": true,
  "rating": 4.52,
  "ratingCount": 27000000,
  "price": 0,
  "currency": "USD",
  "version": "567.0.0",
  "url": "https://apps.apple.com/us/app/facebook/id284882215?uo=4"
}
```

### App Store Country Codes

Use two-letter App Store country codes such as:

- `us` - United States
- `gb` - United Kingdom
- `de` - Germany
- `fr` - France
- `es` - Spain
- `br` - Brazil
- `jp` - Japan

### Local Development

```bash
pnpm install
pnpm --filter app-store-aso build
cd actors/app-store-aso
apify run --input-file fixtures/input.metadata.json
```

For quick local smoke tests without Apify CLI:

```bash
node dist/dev-run.js fixtures/input.rankings.json storage/dev-rankings-output.jsonl
```

### FAQ

#### Is this App Store scraper free to use?

The Actor itself reads Apple's public iTunes endpoints. You only pay for Apify platform usage; there is no third-party API key or proxy cost.

#### Do I need an API key?

No. Unlike RapidAPI-based App Store APIs, this scraper calls Apple's public iTunes/App Store endpoints directly — no key, no login.

#### How do I track App Store keyword rankings?

Use `rankings` mode with your `appIds` (or `bundleIds`) and a list of `keywords`. Each row returns the app's `rankPosition` in App Store search plus a `keywordDifficulty` score for ASO prioritization.

#### What is the keyword difficulty score?

A 0-100 ASO signal estimating how hard a keyword is to rank for, based on the rating strength of the top apps and the number of competing apps. Raw App Store scrapers do not provide this.

#### Can I export App Store reviews?

Yes. Use `reviews` mode with numeric `appIds` to export recent or most-helpful App Store reviews with ratings, author, and version.

#### Does it support iOS bundle IDs?

Yes. `metadata` and `rankings` modes accept both numeric App Store app IDs and iOS bundle IDs (e.g. `com.instagram.ios`).

#### Does it scrape Google Play too?

No — this Actor covers the Apple App Store / iOS. A separate Google Play ASO scraper is planned.

### Notes

- Reviews mode requires numeric App Store app IDs.
- Metadata and rankings mode support numeric app IDs and bundle IDs.
- Rankings mode checks App Store search result positions within `maxSearchResults`.
- Metadata mode batches numeric app IDs through Apple's lookup endpoint. Use `metadataBatchSize` and `requestDelayMs` to tune large runs; batch sizes up to 200 are supported by the Actor.
- This Actor does not estimate downloads or revenue; it returns public App Store/iTunes data.

# Actor input Schema

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

Choose what data to extract.

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

Apple numeric app IDs, e.g. 284882215 for Facebook.

## `bundleIds` (type: `array`):

Optional iOS bundle IDs, e.g. com.facebook.Facebook.

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

Keywords to rank-check in App Store search.

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

Two-letter App Store country codes.

## `lang` (type: `string`):

Optional iTunes language code, e.g. en\_us.

## `maxSearchResults` (type: `integer`):

How many App Store search results to inspect per keyword/country.

## `maxReviews` (type: `integer`):

Maximum reviews per app/country in reviews mode.

## `reviewSortBy` (type: `string`):

Sort order for App Store reviews.

## `metadataBatchSize` (type: `integer`):

How many numeric app IDs to send in one App Store lookup request in metadata mode.

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

Delay in milliseconds between App Store requests. Increase for very large runs.

## `chart` (type: `string`):

Top chart type to extract in charts mode.

## `genre` (type: `string`):

Optional App Store genre ID for top charts, e.g. 6014 for Games.

## `maxChartResults` (type: `integer`):

Maximum number of top chart rows to extract per country.

## Actor input object example

```json
{
  "mode": "rankings",
  "appIds": [
    "284882215"
  ],
  "keywords": [
    "social network"
  ],
  "countries": [
    "us",
    "gb",
    "de"
  ],
  "maxSearchResults": 50,
  "maxReviews": 100,
  "reviewSortBy": "mostrecent",
  "metadataBatchSize": 50,
  "requestDelayMs": 500,
  "chart": "topfreeapplications",
  "maxChartResults": 100
}
```

# Actor output Schema

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

All extracted rows from the default dataset.

## `resultsCsv` (type: `string`):

The same rows exported as CSV.

# 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": [
        "284882215"
    ],
    "keywords": [
        "social network"
    ],
    "countries": [
        "us",
        "gb",
        "de"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("juramoshkov/app-store-aso-keyword-rankings-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "appIds": ["284882215"],
    "keywords": ["social network"],
    "countries": [
        "us",
        "gb",
        "de",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("juramoshkov/app-store-aso-keyword-rankings-scraper").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": [
    "284882215"
  ],
  "keywords": [
    "social network"
  ],
  "countries": [
    "us",
    "gb",
    "de"
  ]
}' |
apify call juramoshkov/app-store-aso-keyword-rankings-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "App Store ASO Keyword & Rankings Scraper",
        "description": "Track App Store keyword rankings, app metadata, reviews, and top charts by country using public iTunes endpoints.",
        "version": "0.1",
        "x-build-id": "Ns2YdoK5Ww3nB0BvH"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/juramoshkov~app-store-aso-keyword-rankings-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-juramoshkov-app-store-aso-keyword-rankings-scraper",
                "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/juramoshkov~app-store-aso-keyword-rankings-scraper/runs": {
            "post": {
                "operationId": "runs-sync-juramoshkov-app-store-aso-keyword-rankings-scraper",
                "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/juramoshkov~app-store-aso-keyword-rankings-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-juramoshkov-app-store-aso-keyword-rankings-scraper",
                "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",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "rankings",
                            "metadata",
                            "reviews",
                            "charts"
                        ],
                        "type": "string",
                        "description": "Choose what data to extract.",
                        "default": "rankings"
                    },
                    "appIds": {
                        "title": "App IDs",
                        "type": "array",
                        "description": "Apple numeric app IDs, e.g. 284882215 for Facebook.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "bundleIds": {
                        "title": "Bundle IDs",
                        "type": "array",
                        "description": "Optional iOS bundle IDs, e.g. com.facebook.Facebook.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Keywords",
                        "type": "array",
                        "description": "Keywords to rank-check in App Store search.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "countries": {
                        "title": "Countries",
                        "type": "array",
                        "description": "Two-letter App Store country codes.",
                        "default": [
                            "us"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "lang": {
                        "title": "Language",
                        "type": "string",
                        "description": "Optional iTunes language code, e.g. en_us."
                    },
                    "maxSearchResults": {
                        "title": "Max search results",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "How many App Store search results to inspect per keyword/country.",
                        "default": 50
                    },
                    "maxReviews": {
                        "title": "Max reviews",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum reviews per app/country in reviews mode.",
                        "default": 100
                    },
                    "reviewSortBy": {
                        "title": "Review sort",
                        "enum": [
                            "mostrecent",
                            "mosthelpful"
                        ],
                        "type": "string",
                        "description": "Sort order for App Store reviews.",
                        "default": "mostrecent"
                    },
                    "metadataBatchSize": {
                        "title": "Metadata batch size",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "How many numeric app IDs to send in one App Store lookup request in metadata mode.",
                        "default": 50
                    },
                    "requestDelayMs": {
                        "title": "Request delay",
                        "minimum": 0,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Delay in milliseconds between App Store requests. Increase for very large runs.",
                        "default": 500
                    },
                    "chart": {
                        "title": "Chart",
                        "enum": [
                            "topfreeapplications",
                            "toppaidapplications",
                            "topgrossingapplications"
                        ],
                        "type": "string",
                        "description": "Top chart type to extract in charts mode.",
                        "default": "topfreeapplications"
                    },
                    "genre": {
                        "title": "Genre ID",
                        "type": "string",
                        "description": "Optional App Store genre ID for top charts, e.g. 6014 for Games."
                    },
                    "maxChartResults": {
                        "title": "Max chart results",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Maximum number of top chart rows to extract per country.",
                        "default": 100
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
