# ASO Keyword Rank Tracker — App Store & Google Play (`slothtechlabs/aso-keyword-rank-tracker`) Actor

Track keyword rankings, find top apps per keyword, and discover related keywords across Apple App Store and Google Play (60+ storefronts). Pay-per-use, no subscription. Flat CSV output. The affordable AppTweak / Sensor Tower alternative — same data at a fraction of the cost.

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

## Pricing

$1.00 / 1,000 result rows

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

## 🔍 ASO Keyword Rank Tracker — App Store & Google Play

> **Clean ASO data, delivered as a spreadsheet.** One Actor, three actions, both stores, pay per use.

Tired of paying **$83+/month to AppTweak** or **$179+/month to AppFollow** just to check whether your app still ranks for your target keywords? This Actor gives you the same kind of data — cross-platform (iOS + Android), 60 storefronts, **pay-per-use** — as flat CSV rows that open cleanly in Excel / Google Sheets / Looker.

**Under 20 seconds** from clicking Start to having sortable ASO data you can pivot, filter, and plot.

You get the **real data** (top apps, review counts, ratings, prices, release dates), **raw aggregates** (total results, top-10 review-count median, etc.), and **three convenience estimates** (`popularityEstimate`, `difficultyEstimate`, `opportunityEstimate`) so you can prioritize keywords with one sort. No dashboards, no lock-in.

---

### 📊 Sample output (CSV-friendly)

Running with the default input (2 keywords × both stores, top 10 each) produces rows like this:

| keyword | store | appRank | appName | rating | ratingCount | price | genre | releaseDate | popularity­Estimate | difficulty­Estimate | opportunity­Estimate |
|---|---|---|---|---|---|---|---|---|---|---|---|
| fitness app | apple | 1 | Fitness App (Trainerize) | 4.9 | 62,559 | Free | Health & Fitness | 2012-04-12 | 87 | 84 | 14 |
| fitness app | apple | 2 | Apple Fitness | 2.9 | 10,796 | Free | Health & Fitness | 2020-09-30 | 87 | 84 | 14 |
| fitness app | google | 1 | Home Workout — No Equipment | 4.8 | 3,895,736 | Free | Health & Fitness | 2017-11-08 | 98 | 91 | 9 |
| meditation | apple | 1 | Insight Timer | 4.9 | 437,965 | Free | Health & Fitness | 2009-11-05 | 87 | 86 | 12 |

(plus `iconUrl` rendered as thumbnail, `appId`, `developer`, 4 raw aggregate columns, `url`, `storefront`, `scrapedAt`, `action` — 23 columns in total.)

40 rows per prefill (2 × 2 × 10). **Sort by `opportunityEstimate` desc to surface your best targets; filter by `store`; pivot by `keyword`** — no JSON parsing required.

---

### 🎯 Who this is for

- 🧑‍💻 **Indie developers** — track your app's rank for 20 keywords daily, both stores, for **~$1.20/month**
- 🏢 **ASO agencies** — benchmark 10 clients × 50 keywords × both stores nightly for **~$30/month total** (vs AppFollow's $179/seat)
- 🎯 **Product marketers** — week-of-launch competitor benchmark (10 apps × 20 keywords × both stores × 7 days) for **~$2.80**
- 🔍 **VCs / App scouts** — one-shot market scan (5 keywords × both stores × top 10) for **~$0.10** per evaluation
- 📊 **Data analysts** — pipe the flat CSV into your BI tool and never pay for another dashboard seat

---

### 🚀 First run — 3 steps

1. **Click Start** (prefill is already safe: 2 keywords × both stores × top 10).
2. After ~15 seconds, **open the Dataset tab**. The **Overview** view is shown by default — columns are already in a readable order (keyword, store, app rank, app name, then metrics, estimates, and meta).
3. **Export → CSV** and open in Google Sheets / Excel. Sort by `opportunityEstimate` desc — the top rows are your best keyword targets.

That's it. When you're ready for real workflows, jump to **App rank tracking** below.

---

### 🧭 Three actions

#### 📈 App rank tracking (most popular — pair with Apify Scheduler for daily tracking)

"**Where does app X rank for keyword Y?**" — one row per (app × keyword × store).

```json
{
  "action": "app-rank-tracking",
  "stores": ["apple", "google"],
  "storefront": "us",
  "keywords": ["instagram", "reels", "social"],
  "apps": ["389801252", "com.instagram.android"],
  "myApp": "389801252"
}
````

Output columns: `keyword`, `store`, `iconUrl`, `appName`, `appId`, `appRank`, `rankStatus` (`ranked` / `out-of-top-200`), `isMyApp`, `rating`, `ratingCount`, `price`, `genre`, `developer`, `releaseDate`, `storefront`, `scrapedAt`, `action`.

💡 **Daily tracking tip**: Save this as an Apify **Task** (save-input feature) and enable **Scheduler** (daily at 03:00 UTC). Each run appends a fresh dataset; Apify retains dataset history for free, so you have a time series without extra code.

***

#### 🆚 Competitor comparison — just list them in `apps`

Want to see how you compare to competitors? Pass them in `apps` alongside `myApp`:

```json
{
  "action": "app-rank-tracking",
  "stores": ["apple", "google"],
  "storefront": "us",
  "keywords": ["photo editor"],
  "myApp": "389801252",
  "apps": ["447188370", "547702041", "380726137"]
}
```

Filter by `isMyApp=true` in the Dataset to see your app's row; `isMyApp=false` for rivals. Pivot by keyword → side-by-side leaderboard.

***

#### 🔍 Top apps for keywords — market research

"**Who shows up for keyword X?**" — top-N flat rows per (keyword × store).

```json
{
  "action": "keyword-top-apps",
  "stores": ["apple", "google"],
  "storefront": "us",
  "keywords": ["fitness app", "meditation"],
  "topN": 10
}
```

Per row you get the app's full context (appName, rating, ratingCount, price, genre, developer, url, iconUrl) **plus keyword-level columns** — repeated on every row so you can filter/sort without losing context.

##### Keyword-level columns

**Raw aggregates (deterministic, computed from the top-ranking apps):**

| Column | What it tells you |
|---|---|
| `totalResults` | How saturated the keyword is (8 apps = niche, 200+ = competitive) |
| `top10MedianRatings` | Review-count scale of top competitors. 1,000 = approachable; 1M+ = very hard |
| `top10AvgRating` | If average rating is 4.8+, users love the top apps — quality bar is high |
| `top10PaidCount` | Paid apps in top 10. Signals whether paid listings rank |

**Per-app context (per row):**

| Column | What it tells you |
|---|---|
| `appRank` | 1–topN rank within this keyword & store |
| `appName`, `developer`, `iconUrl`, `url` | Identity + direct store link for the ranking app |
| `rating`, `ratingCount` | Star + review volume |
| `price`, `genre` | Monetization + category |
| `releaseDate` | When the app launched (YYYY-MM-DD). Helps gauge competitive age — a top 10 of 5+ year-old apps is harder to unseat than a top 10 of recent launches |

**Convenience estimates (directional 0-100 scores for quick prioritization):**

| Column | What it suggests |
|---|---|
| `popularityEstimate` (5-100) | How popular the keyword is likely to be |
| `difficultyEstimate` (0-100) | How hard it's likely to be to rank for it |
| `opportunityEstimate` (0-100) | Combined "worth targeting" score — the higher, the better |

> **About the estimates**: `popularityEstimate`, `difficultyEstimate`, and `opportunityEstimate` are directional 0-100 scores derived from the top-ranking apps for each keyword. Treat them as a prioritization aid, not calibrated truth. For important decisions, cross-check against the raw aggregate columns (`totalResults`, `top10MedianRatings`, `top10AvgRating`, `top10PaidCount`) and apply your own judgment. Sort by `opportunityEstimate` desc to surface candidates worth investigating first.

***

#### 💡 Keyword recommendations — idea expansion

"**Give me related keywords to target.**" — one row per recommended keyword.

```json
{
  "action": "keyword-recommendations",
  "stores": ["apple", "google"],
  "storefront": "us",
  "seedKeyword": "fitness",
  "limit": 30
}
```

Output columns: `seedKeyword`, `store`, `rank` (1..limit), `recommendedKeyword`, `source`, `storefront`, `scrapedAt`, `action`.

The `source` column indicates where each suggestion came from — use it if you want to weight suggestions differently in your own workflow.

***

### 🧾 Input reference

| Field | Required for | Example |
|---|---|---|
| `action` | all | `"keyword-top-apps"` | `"keyword-recommendations"` | `"app-rank-tracking"` |
| `stores` | all | `["apple", "google"]` |
| `storefront` | all | `"us"` (60 supported codes) |
| `keywords` | keyword-top-apps, app-rank-tracking | up to 100 |
| `topN` | keyword-top-apps | 1–20 (default 10) |
| `seedKeyword` | keyword-recommendations | one word/phrase |
| `limit` | keyword-recommendations | 1–80 (default 50) |
| `apps` | app-rank-tracking | Apple trackIds OR Google bundle ids, up to 20 |
| `myApp` | app-rank-tracking (optional) | one app ID; flags `isMyApp=true` |

#### Where to find App IDs

- **Apple**: numeric digits after `/id` in the store URL.
  Example: `https://apps.apple.com/us/app/instagram/id389801252` → **`389801252`**
- **Google**: value after `?id=` in the store URL.
  Example: `https://play.google.com/store/apps/details?id=com.instagram.android` → **`com.instagram.android`**

#### Storefront behavior

The `storefront` field drives both the country ranking **and** the locale of the returned app names. For example, `storefront: "jp"` returns the Japan App Store / Google Play rankings with Japanese app names and localized genres. Use `us` for English.

***

### ⏱ How long does it take?

| Run size | Expected duration |
|---|---|
| Prefill (2 KW × 2 stores × top 10) | **~15 seconds** |
| Medium (20 KW × 2 stores × top 10) | ~1–2 minutes |
| Large (100 KW × 2 stores × top 10) | ~5–8 minutes |
| App rank tracking (20 apps × 20 KW × 2 stores) | ~30–60 seconds |
| Keyword recommendations (1 seed × 2 stores × 50) | ~10 seconds |

All runs stay well under Apify's default 1-hour timeout. Transient failures on individual (keyword × store) pairs are retried 3× automatically; persistent failures are recorded in the `RUN_SUMMARY` key-value entry and the rest of the run continues.

***

### ❓ When does a field come back `null` / empty?

This is **not a bug** — it means the source store didn't expose that field for that specific app. Common cases:

- **`ratingCount` / `rating`** → brand-new apps with zero user ratings yet
- **`releaseDate`** → rare; a handful of non-US storefronts redact this
- **`iconUrl`** → rare; the store hasn't served an image URL
- **`appRank` + `rankStatus = "out-of-top-200"`** → by design, the app is outside the top 200 search results for that keyword (rank tracking covers top 200 per store)
- **`genre` / `developer`** → rare; data-source gap

***

### 📦 Getting your data out

After a run completes:

1. **Apify Console → Dataset tab** shows the **Overview** table view by default. Columns are in a user-priority order: keyword → store → app identity → app metrics → keyword estimates → raw aggregates → meta. Icon images render as thumbnails; URLs are clickable.
2. A secondary **All Fields** tab is auto-generated by the Apify platform — same data, columns sorted alphabetically. You can safely ignore it in normal use.
3. **Export → CSV** (or XLSX / JSON). All columns are flat — Excel / Sheets will just work.
4. **API with Overview column order** (recommended for scripts):
   `https://api.apify.com/v2/datasets/{datasetId}/items?format=csv&view=overview`
5. **API (default, alphabetical)**: `?format=csv` — columns are sorted A–Z by Apify.
6. **Google Sheets**: use Apify's "Open in Sheets" button (bottom of Dataset tab), or `IMPORTDATA("<url with ?view=overview>")` in a cell.

***

### 🔁 Daily tracking workflow (free time series)

1. Configure the Actor input once (e.g., `app-rank-tracking` for your 20 target keywords).
2. In Apify Console → **Save as Task** → give it a name.
3. Open the Task → **Integrations → Scheduler** → daily cadence.
4. Each day's run creates a new Dataset; combine by downloading the last N days' datasets and joining on `appId + keyword + store` with a `scrapedAt` timestamp column.

No delta-calculation code required on our side; Apify retains dataset history for you.

***

### 💰 Cost (pay per result row)

**$0.001 per dataset row.** No startup fee. No tiered events. You only pay for the rows you actually receive.

#### Typical runs

| Use case | Volume | Cost |
|---|---|---|
| Prefill run (2 KW × 2 stores × top 10) | 40 rows | ~**$0.04** |
| Daily rank tracking: 1 app × 20 KW × both stores | 40 rows/day | ~**$0.04/day** / **$1.20/month** |
| Agency: 5 apps × 50 KW × both stores daily | 500 rows/day | ~**$0.50/day** / **$15/month** |
| Keyword research: seed × both stores × 50 recs | ~100 rows | ~**$0.10** |

Compare to **AppTweak Essential** ($83/mo fixed), **AppFollow** ($179+/mo), **Sensor Tower** (~$25k+/yr). Daily 60-KW tracking here costs **~$3.60/month** — over **98 % cheaper** than AppFollow.

***

### ℹ️ What we do — and what we intentionally don't

**We excel at**:

- Returning clean, flat ASO rows from both stores in CSV-ready form
- Daily rank tracking paired with Apify Scheduler (free time series via dataset history)
- Competitor benchmarking in one pivot (set `myApp`, list rivals in `apps`)
- 60 storefronts with locale-aware app names

**We intentionally don't**:

- **Replace calibrated SaaS dashboards** like AppTweak or Sensor Tower. Our estimates are directional prioritization aids, not calibrated indices for precision work. For calibrated scoring, keep those subscriptions.
- **Track apps below the top 200** search results (outside that range the row returns `appRank: null` / `rankStatus: "out-of-top-200"`)
- **Build dashboards** — we produce data rows; your spreadsheet, Looker, or Tableau builds the chart

**Disclaimer**: Not affiliated with Apple Inc. or Google LLC. Data is derived from publicly accessible endpoints; use in accordance with each store's Terms of Service.

***

### 🔗 Related Actors by the same publisher

- [slothtechlabs/ios-android-app-rankings-scraper](https://apify.com/slothtechlabs/ios-android-app-rankings-scraper) — Top chart rankings (Top Free / Paid / Grossing) for both stores, daily.

***

### ▶️ Ready?

**Click Start** at the top with the prefilled input — your first 40 rows of ASO intelligence arrive in about 15 seconds, for **$0.04** total.

***

### 📬 Feedback & support

If you have any questions, feature requests, or encounter any issues, please open an [issue on the Actor's page](https://console.apify.com/actors). We'd love to hear from you!

# Actor input Schema

## `action` (type: `string`):

Pick an action. Each action uses a different subset of the fields below.

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

Query Apple App Store, Google Play, or both in one run.

## `storefront` (type: `string`):

ISO 3166-1 alpha-2 country code. 60 storefronts supported.

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

Used by 'Top apps for keywords' and 'App rank tracking'. Enter one keyword per line, up to 100.

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

Only used by 'Top apps for keywords'. 1–20. Default 10. Increasing this multiplies the number of result rows.

## `seedKeyword` (type: `string`):

Only used by 'Keyword recommendations'. A single seed word to expand (e.g., 'fitness' → 'fitness tracker', 'fitness app for women', ...).

## `limit` (type: `integer`):

Only used by 'Keyword recommendations'. 1–80 suggestions per store. Default 50.

## `apps` (type: `array`):

Only used by 'App rank tracking'. Enter Apple numeric trackIds (e.g., "389801252" — the digits after '/id' in a URL like https://apps.apple.com/us/app/instagram/id389801252) OR Google bundle ids (e.g., "com.instagram.android" — the value after '?id=' in a URL like https://play.google.com/store/apps/details?id=com.instagram.android). Up to 20.

## `myApp` (type: `string`):

Only used by 'App rank tracking'. Your own app's ID (Apple trackId or Google bundle id). If set, the row for that app will have isMyApp=true — handy for side-by-side reports. Will be automatically added to the tracked apps list if not already there.

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

Defaults to Apify Proxy (datacenter). Enable residential if a specific country returns sparse Google Play results.

## Actor input object example

```json
{
  "action": "keyword-top-apps",
  "stores": [
    "apple",
    "google"
  ],
  "storefront": "us",
  "keywords": [
    "fitness app",
    "meditation"
  ],
  "topN": 10,
  "seedKeyword": "fitness",
  "limit": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All rows pushed to the default dataset by this run.

## `runSummary` (type: `string`):

JSON object with action, totalRows, errors, errorDetails, durationMs, stores, storefront.

# 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 = {
    "action": "keyword-top-apps",
    "stores": [
        "apple",
        "google"
    ],
    "storefront": "us",
    "keywords": [
        "fitness app",
        "meditation"
    ],
    "topN": 10,
    "limit": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("slothtechlabs/aso-keyword-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 = {
    "action": "keyword-top-apps",
    "stores": [
        "apple",
        "google",
    ],
    "storefront": "us",
    "keywords": [
        "fitness app",
        "meditation",
    ],
    "topN": 10,
    "limit": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("slothtechlabs/aso-keyword-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 '{
  "action": "keyword-top-apps",
  "stores": [
    "apple",
    "google"
  ],
  "storefront": "us",
  "keywords": [
    "fitness app",
    "meditation"
  ],
  "topN": 10,
  "limit": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call slothtechlabs/aso-keyword-rank-tracker --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "ASO Keyword Rank Tracker — App Store & Google Play",
        "description": "Track keyword rankings, find top apps per keyword, and discover related keywords across Apple App Store and Google Play (60+ storefronts). Pay-per-use, no subscription. Flat CSV output. The affordable AppTweak / Sensor Tower alternative — same data at a fraction of the cost.",
        "version": "1.0",
        "x-build-id": "VJNdhLcitRem5szze"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/slothtechlabs~aso-keyword-rank-tracker/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-slothtechlabs-aso-keyword-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/slothtechlabs~aso-keyword-rank-tracker/runs": {
            "post": {
                "operationId": "runs-sync-slothtechlabs-aso-keyword-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/slothtechlabs~aso-keyword-rank-tracker/run-sync": {
            "post": {
                "operationId": "run-sync-slothtechlabs-aso-keyword-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",
                "required": [
                    "action",
                    "stores",
                    "storefront"
                ],
                "properties": {
                    "action": {
                        "title": "What do you want to do?",
                        "enum": [
                            "keyword-top-apps",
                            "keyword-recommendations",
                            "app-rank-tracking"
                        ],
                        "type": "string",
                        "description": "Pick an action. Each action uses a different subset of the fields below.",
                        "default": "keyword-top-apps"
                    },
                    "stores": {
                        "title": "Stores",
                        "type": "array",
                        "description": "Query Apple App Store, Google Play, or both in one run.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "apple",
                                "google"
                            ],
                            "enumTitles": [
                                "🍎 Apple App Store (iOS)",
                                "🤖 Google Play Store (Android)"
                            ]
                        },
                        "default": [
                            "apple",
                            "google"
                        ]
                    },
                    "storefront": {
                        "title": "Storefront (Country)",
                        "enum": [
                            "us",
                            "gb",
                            "jp",
                            "kr",
                            "cn",
                            "de",
                            "fr",
                            "au",
                            "ca",
                            "br",
                            "in",
                            "mx",
                            "it",
                            "es",
                            "nl",
                            "se",
                            "no",
                            "dk",
                            "fi",
                            "ch",
                            "at",
                            "be",
                            "pt",
                            "ie",
                            "nz",
                            "sg",
                            "hk",
                            "tw",
                            "th",
                            "my",
                            "ph",
                            "id",
                            "vn",
                            "sa",
                            "ae",
                            "il",
                            "tr",
                            "ru",
                            "pl",
                            "cz",
                            "hu",
                            "ro",
                            "bg",
                            "hr",
                            "sk",
                            "si",
                            "lt",
                            "lv",
                            "ee",
                            "gr",
                            "ua",
                            "za",
                            "ng",
                            "ke",
                            "eg",
                            "ar",
                            "cl",
                            "co",
                            "pe",
                            "pk"
                        ],
                        "type": "string",
                        "description": "ISO 3166-1 alpha-2 country code. 60 storefronts supported.",
                        "default": "us"
                    },
                    "keywords": {
                        "title": "Keywords",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Used by 'Top apps for keywords' and 'App rank tracking'. Enter one keyword per line, up to 100.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "topN": {
                        "title": "How many top apps per keyword?",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Only used by 'Top apps for keywords'. 1–20. Default 10. Increasing this multiplies the number of result rows.",
                        "default": 10
                    },
                    "seedKeyword": {
                        "title": "Seed keyword",
                        "type": "string",
                        "description": "Only used by 'Keyword recommendations'. A single seed word to expand (e.g., 'fitness' → 'fitness tracker', 'fitness app for women', ...)."
                    },
                    "limit": {
                        "title": "How many recommendations?",
                        "minimum": 1,
                        "maximum": 80,
                        "type": "integer",
                        "description": "Only used by 'Keyword recommendations'. 1–80 suggestions per store. Default 50.",
                        "default": 50
                    },
                    "apps": {
                        "title": "App IDs to track",
                        "maxItems": 20,
                        "type": "array",
                        "description": "Only used by 'App rank tracking'. Enter Apple numeric trackIds (e.g., \"389801252\" — the digits after '/id' in a URL like https://apps.apple.com/us/app/instagram/id389801252) OR Google bundle ids (e.g., \"com.instagram.android\" — the value after '?id=' in a URL like https://play.google.com/store/apps/details?id=com.instagram.android). Up to 20.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "myApp": {
                        "title": "My app ID (optional)",
                        "type": "string",
                        "description": "Only used by 'App rank tracking'. Your own app's ID (Apple trackId or Google bundle id). If set, the row for that app will have isMyApp=true — handy for side-by-side reports. Will be automatically added to the tracked apps list if not already there."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Defaults to Apify Proxy (datacenter). Enable residential if a specific country returns sparse Google Play results.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
