# App Store Revenue & Downloads Estimator (`gazidev/app-revenue-estimator`) Actor

Estimate App Store downloads and revenue for any iPhone app in 175 countries: Top Free, Paid and Grossing ranks, price, rating growth and low/mid/high bands from a rank model calibrated on published figures. Directional estimates, not Apple data.

- **URL**: https://apify.com/gazidev/app-revenue-estimator.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 app estimates

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## App Store Revenue & Downloads Estimator

Estimate **App Store downloads and revenue** for any iPhone app in **175 countries**. Give the Actor app IDs, App Store URLs, bundle IDs or developers, or ask it to estimate a whole top chart. For each app and storefront it returns:

- the app's **chart ranks**: Top Free, Top Paid and **Top Grossing**, overall and in its genre
- price, currency and an in-app purchase signal
- rating count, and **rating growth** since your last run
- **low / mid / high download and revenue ranges** per day and per month, each with a `method` and a `confidence` field

> **Directional estimates, not actual data.** Apple does not publish downloads or revenue for apps. Every figure in this Actor's output is a model estimate built from public chart ranks and rating counts. The model is calibrated against published third-party figures (median error about 1.6x for revenue and 1.3x for downloads in the US), but any single app can be several times off. Each row is labeled `isEstimate: true` and carries a disclaimer. Use the numbers to compare apps, markets and trends, not as accounting figures. This Actor is **not affiliated with, endorsed by or sponsored by Apple Inc.** App Store and iPhone are trademarks of Apple Inc.

### What it does

1. It looks up each app in each storefront with Apple's official **iTunes Lookup API**. That gives price, genre, rating and rating count. Lookups are batched up to 100 per call and throttled to Apple's documented ~20 calls per minute.
2. It reads Apple's public **RSS top charts** for each storefront: Top Free, Top Paid and Top Grossing iPhone apps (top 100), plus the same charts for each app's genre. It finds each app's rank in them.
3. It converts ranks into downloads and revenue with a **rank-to-demand power law**. The curve is calibrated on published figures for about 30 US apps and scaled to each country's market size (see Methodology).
4. Apps outside the top 100 are estimated from their genre-chart rank or their **rating velocity**: new ratings per day, read from a history store of your earlier runs, or the lifetime average on the first run. These estimates are capped below chart rank #101 and get low confidence and wide ranges.
5. Optionally, it adds **publisher rollups**: summed bands per developer and country.

### Use cases

- **Competitor research:** how big is a rival app in the US vs Germany vs Japan?
- **Market sizing:** estimate the whole Top Free or Top Paid chart of a country in one click.
- **App acquisition / investing screens:** spot apps whose rating growth is speeding up (schedule daily or weekly runs).
- **ASO and UA planning:** check how many downloads a chart position roughly represents in each storefront.
- **AI agents:** a cheap "how big is this app?" tool for research agents (see the MCP section).

### Input example

```json
{
  "apps": ["324684580", "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128", "com.midasplayer.apps.candycrushsaga"],
  "countries": ["us", "gb", "de"],
  "estimateTopChart": "none",
  "developers": [],
  "publisherRollups": false,
  "trackRatingGrowth": true
}
```

- `countries`: two-letter storefront codes. `top` gives the 30 largest storefronts and `all` gives all 175.
- `estimateTopChart`: `top-free`, `top-paid` or `top-grossing` adds the first `topChartLimit` apps (1-100) of that chart in each country.
- `scanGenreCharts` (default on): also reads the genre charts of each app's genre, so apps outside the overall top 100 can still get a rank.
- `developers`: developer IDs or developer URLs. The Actor takes each developer's most-rated apps, up to `maxAppsPerDeveloper`.
- `countryMultipliers`: optional overrides of a storefront's size, e.g. `{"de": {"downloads": 0.15, "revenue": 0.11}}`.

### Output example (one row, real run 2026-10-17, shortened)

```json
{
  "type": "estimate", "appId": 570060128, "name": "Duolingo: Learn Languages", "country": "us",
  "primaryGenre": "Education", "price": 0.0, "currency": "USD", "isFree": true,
  "hasInAppPurchases": true, "rating": 4.723, "ratingCount": 5511319,
  "topFreeRank": 67, "topPaidRank": null, "topGrossingRank": 26, "genreTopGrossingRank": null,
  "downloadsMonthly": {"low": 340000, "mid": 870000, "high": 2100000},
  "revenueMonthlyUsd": {"low": 7200000, "mid": 17000000, "high": 38000000},
  "downloadsMethod": "top-free-overall-rank-power-law",
  "revenueMethod": "top-grossing-overall-rank-power-law",
  "confidence": "medium", "downloadsConfidence": "medium", "revenueConfidence": "medium",
  "countryMultiplier": {"downloads": 1.0, "revenue": 1.0},
  "revenueBasis": "gross consumer spend in USD before Apple's commission and taxes",
  "isEstimate": true, "disclaimer": "Directional model estimate, not actual Apple data. Not affiliated with Apple. ..."
}
```

Daily bands (`downloadsDaily`, `revenueDailyUsd`) are included too. All values are rounded to 2 significant figures on purpose. Error rows (`type: "error"`: invalid ID, app not available in a storefront) are **free**. A run summary is saved to the `OUTPUT` record.

### Methodology (summary; full details and the calibration table in METHODOLOGY.md)

**Rank to demand.** Sales rank follows a power law: `value(rank) = A x rank^-b`. Chevalier & Goolsbee used this form for Amazon book ranks, and Garg & Telang (2013) used it for the App Store. The US curves (per day) are:

| Curve (US iPhone) | low | mid | high | Calibration |
|---|---|---|---|---|
| Top Grossing revenue (USD, gross) | 2.5M x r^-0.72 | 5.1M x r^-0.68 | 9.5M x r^-0.62 | 22 apps at ranks 1-90. Median error 1.6x, max 2.3x, 21 of 22 inside the band |
| Top Free downloads | 75k x r^-0.45 | 150k x r^-0.39 | 300k x r^-0.35 | 12 apps and studies at ranks 1-100. Median 1.3x, max 2.1x, all inside the band |
| Top Paid downloads | 5k x r^-1.0 | 12k x r^-0.946 | 25k x r^-0.90 | Not calibrated (Garg & Telang shape). Confidence is at most `low` |

The mid curves are least-squares fits to publicly reported US iPhone figures. Examples: Sensor Tower's published weekly revenue for MONOPOLY GO! (~$13M/week, #8 today), Royal Match (~$12M/week, #14), Tinder (~$9M/week, #25), Hinge, Bumble, Strava and Raya (#90, ~$0.8M/week). Appfigures' ChatGPT spend report gives the #1 point. For downloads, Sensor Tower's study puts the #1 app at about 94k/day and #10 at about 49k/day, and Reflection data puts the top-100 entry at about 11.7k/day. Each reference is matched to the app's US rank on 2026-10-17. METHODOLOGY.md lists every reference with its URL and date, and `tests/calibration.py` re-checks the tolerance.

**Genre charts.** A genre rank #r is converted to an overall-equivalent rank `r x 100 / k`, where k is the number of apps of that genre in the overall top 100. The estimate is capped below overall rank #101 and has confidence `low`.

**Countries.** The US curve is multiplied by a storefront factor for downloads and one for revenue. For example, Japan is 0.21 / 0.45, the UK 0.18 / 0.14, Germany 0.13 / 0.11, Brazil 0.21 / 0.03 and Turkey 0.06 / 0.015. Download factors come from AppTweak's 2025 downloads-by-country report. Revenue factors are rough tiers and are not validated app by app. Storefronts that are not listed default to 0.005 / 0.002. You can override any value with `countryMultipliers`.

**Apps without a chart rank** get low or very low confidence and wide ranges:

- Downloads = new ratings per day x 15 / 50 / 200 downloads per rating. The second and later runs use the actual rating growth (`low`); the first run uses the lifetime average (`very low`).
- Revenue = downloads x a revenue-per-download range of $0.01-$4 (games $0.02-$5), or price x downloads for paid apps (`very low` / `low`).
- Both are capped below the value at rank #101 of the scanned chart.

**Confidence** is `medium`, `low` or `very low`, never `high`.

- `medium`: a direct overall Top Free or Top Grossing rank in a top-15 storefront. Even then a single app can be 2-5x off, because ranks move and category matters (dating apps earn more per rank than the curve shows).
- The row-level `confidence` is the lower of the download and revenue confidences.

#### Sources

- Garg, R. & Telang, R. (2013). *Inferring App Demand from Publicly Available Data.* MIS Quarterly 37(4). https://aisel.aisnet.org/misq/vol37/iss4/14/
- Sensor Tower blog, quarterly US iOS top-5 revenue and download posts (Jul 2025 - Jan 2026), e.g. https://sensortower.com/blog/2025-q4-ios-top-5-free-to-play-games-revenue-us-620e5136afb48b4f71fc7c60 and https://sensortower.com/blog/2025-q3-ios-top-5-dating-revenue-us-64c9b6bbe1714cfff1c9d0e8
- Sensor Tower (Sep 2019), downloads needed to reach No. 1. https://sensortower.com/blog/app-downloads-to-number-one
- Appfigures (Dec 2025), ChatGPT crosses $3B in mobile revenue. https://appfigures.com/resources/insights/chatgpt-hits-3b-consumer-spend
- Statista (2022), daily downloads needed to rank in the US top 10. https://www.statista.com/statistics/1317770/us-daily-downloads-needed-rank-first-10-positions-ios-apps/
- PocketGamer.biz / Reflection (2017), top ranking download requirements. https://www.pocketgamer.biz/sponsored-app-stores-top-ranking-download-requirements/
- AppTweak (Dec 2025), App downloads by country. https://www.apptweak.com/en/reports/app-downloads-by-country
- Match Group, Grindr and Duolingo FY2025 10-K filings (cross-check, links in METHODOLOGY.md)

### Data sources

The Actor uses only Apple's public endpoints. These are the same endpoints, with the same throttling and retries, as our live [App Store ASO Keyword Rank Tracker & Top Charts](https://apify.com/gazidev/app-store-top-charts) Actor:

- **iTunes Lookup API** (`https://itunes.apple.com/lookup`): throttled to Apple's documented ~20 calls per minute.
- **Apple iTunes RSS top charts** (`https://itunes.apple.com/{cc}/rss/topfreeapplications|toppaidapplications|topgrossingapplications/limit=100[/genre=ID]/json`): limited to 30 calls per minute, with up to 4 tries and backoff.
- **Apple Marketing Tools RSS** (`https://rss.marketingtools.apple.com/api/v2/{cc}/apps/top-free|top-paid/100/apps.json`): fallback for the overall Top Free and Top Paid charts when the feed above fails.

It does not use the Search API, `apps.apple.com` pages, Google Play, proxies, a browser or a login.

### Pricing

| | This Actor | seibs.co revenue estimator | apivault_labs / codebyte |
|---|---|---|---|
| 1 app, 1 country, ranks + estimate bands | **$0.004** | $0.01 record + $0.02 estimate enrichment | $0.002 per result |
| Each extra country | **$0.001** | per record | per result |
| Publisher rollup | **$0.005** | $0.03 | - |
| Error rows | free | - | - |

Competitor prices were taken from their Store pages in October 2026.

A 3-app x 3-country check costs $0.018. Estimating a US top-25 chart (Top Free, Paid or Grossing) costs $0.10. Set *Maximum cost per run* and the Actor stops cleanly when it is reached.

### FAQ

**How accurate is it?** In the US, the calibrated curves land within about 2x of published third-party figures for most chart apps. The median error is 1.6x for revenue and 1.3x for downloads, and the worst reference is 2.3x off. Those references are themselves estimates by Sensor Tower or Appfigures. Individual apps can still be 2-5x off: ranks move, events cause spikes, and subscription and dating apps earn more per rank than games. Off-chart apps and small storefronts are less certain, and their bands are 10x or more wide. Use the output for ranking and comparing apps, not for valuation or reporting.

**Why is revenue for some free apps so uncertain?** An app that is not on the Top Grossing chart, overall or in its genre, gets revenue from a wide revenue-per-download assumption, capped below Top Grossing rank #101. Apps that sell through the web (for example Spotify in the US) are not ranked by Apple's grossing chart, so their App Store revenue is low by design.

**Does it show in-app purchases?** Apple's public Lookup API does not expose in-app purchases. `hasInAppPurchases` is `true` for a free app that ranks on a Top Grossing chart, and `null` (unknown) otherwise.

**Why do rating growth fields start empty?** Growth needs an earlier snapshot. Schedule the Actor (for example daily) with the same `historyStoreName`. From the second run on you get `ratingCountChange` and `ratingsPerDay`, and downloads for off-chart apps switch to the rating-velocity method.

**iPad, Mac, Google Play?** No. This Actor covers iPhone App Store storefronts only.

**Why is it sometimes slow?** It reads 3 overall charts plus a few genre charts per storefront. RSS calls are limited to 30 per minute and Lookups to Apple's documented ~20 calls per minute. Failed calls are retried with backoff.

### Use with AI agents / Apify MCP

Add this Actor to an MCP client (Claude, Cursor, ChatGPT and others) through the Apify MCP server (`https://mcp.apify.com`), using the tool `gazidev/app-revenue-estimator`. An agent can call it with `{"apps": ["<id or URL>"], "countries": ["us"]}` and read `downloadsMonthly`, `revenueMonthlyUsd`, `confidence` and `method`. Tell the agent to present the values as estimated ranges. The `disclaimer` and `isEstimate` fields are there so it can do that automatically.

Related: [App Store ASO Keyword Rank Tracker & Top Charts](https://apify.com/gazidev/app-store-top-charts) for daily chart and keyword rank tracking.

# Actor input Schema

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

Apps to estimate. Accepts numeric App Store IDs (324684580), App Store URLs (https://apps.apple.com/us/app/spotify/id324684580) or bundle IDs (com.spotify.client).

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

Two-letter storefront codes (us, gb, de, jp, tr...). "top" = 30 largest storefronts, "all" = all 175. The first country of each app is charged as an app estimate, each further country as an extra country.

## `estimateTopChart` (type: `string`):

Adds every app of this chart (per country, up to the limit below) to the run. Uses Apple's public RSS top charts (iPhone, overall).

## `topChartLimit` (type: `integer`):

How many apps of the chart to estimate per country (1-100).

## `developers` (type: `array`):

Optional. Estimates the apps of these developers, e.g. 284882218 or https://apps.apple.com/us/developer/meta-platforms-inc/id284882218. Apps are taken by rating count, up to the limit below.

## `maxAppsPerDeveloper` (type: `integer`):

Most-rated apps taken per developer and country.

## `publisherRollups` (type: `boolean`):

Adds one row per developer and country with the summed download and revenue bands of that developer's apps in this run (charged as publisher-rollup). Made for each developer listed above and for any developer with 2+ apps in the run.

## `trackRatingGrowth` (type: `boolean`):

Saves rating counts in a named key-value store. From the second (scheduled) run on, rows include rating count change and ratings per day, which improves estimates for apps that are not on a chart.

## `scanGenreCharts` (type: `boolean`):

Also reads the genre top charts (top 100 per genre) of each app's primary genre. Gives a rank to apps that are outside the overall top 100 but high in their genre. Adds a few Apple RSS calls per genre and country.

## `historyStoreName` (type: `string`):

Named key-value store for rating history. Use different names to keep separate projects apart.

## `countryMultipliers` (type: `object`):

Optional overrides of the storefront size relative to the US, e.g. {"de": {"downloads": 0.15, "revenue": 0.11}}. Defaults are listed in the README.

## `maxRequestsPerMinute` (type: `integer`):

Apple documents a limit of about 20 calls per minute for the iTunes Lookup API.

## Actor input object example

```json
{
  "apps": [
    "324684580",
    "com.duolingo.DuolingoMobile"
  ],
  "countries": [
    "us",
    "gb",
    "de"
  ],
  "estimateTopChart": "none",
  "topChartLimit": 25,
  "maxAppsPerDeveloper": 20,
  "publisherRollups": false,
  "trackRatingGrowth": true,
  "scanGenreCharts": true,
  "historyStoreName": "app-revenue-estimator-history",
  "maxRequestsPerMinute": 20
}
```

# Actor output Schema

## `estimates` (type: `string`):

No description

## `rollups` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `summary` (type: `string`):

No description

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "apps": [
        "324684580",
        "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128",
        "com.midasplayer.apps.candycrushsaga"
    ],
    "countries": [
        "us",
        "gb",
        "de"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/app-revenue-estimator").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 = {
    "apps": [
        "324684580",
        "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128",
        "com.midasplayer.apps.candycrushsaga",
    ],
    "countries": [
        "us",
        "gb",
        "de",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("gazidev/app-revenue-estimator").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "apps": [
    "324684580",
    "https://apps.apple.com/us/app/duolingo-language-lessons/id570060128",
    "com.midasplayer.apps.candycrushsaga"
  ],
  "countries": [
    "us",
    "gb",
    "de"
  ]
}' |
apify call gazidev/app-revenue-estimator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/app-revenue-estimator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/f2Pm83SyBcYWdqlgA/builds/MXKltF7ZGB0FWcxX1/openapi.json
