# App Store Revenue & Download Estimator - iOS and Google Play (`seibs.co/app-store-revenue-estimator`) Actor

Estimate App Store and Google Play downloads and revenue from public signals (rank, rank history, ratings velocity, review deltas). Per-app records, modeled estimate bands, and publisher rollups. For app devs, UA/growth teams, and investors - the gated Sensor Tower/data.ai layer, priced per call.

- **URL**: https://apify.com/seibs.co/app-store-revenue-estimator.md
- **Developed by:** [Seibs.co](https://apify.com/seibs.co) (community)
- **Categories:** Business, Marketing, E-commerce
- **Stats:** 3 total users, 1 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 app records

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 Revenue & Download Estimator - iOS and Google Play

> **TL;DR for app developers, UA/growth teams, and investors:** Estimated download and revenue **bands** for any iOS or Google Play app, modeled from public signals - chart rank, ratings velocity, ratings-count deltas, Google Play install buckets, price, and in-app-purchase presence. Every estimate ships with a stated **confidence** level (low / medium / high), a one-sentence **methodology** that names which signals drove it, and a **caveats** list. This is the kind of modeled number Sensor Tower and data.ai gate at $25k+/yr - rebuilt here from public data, honestly, as bands with stated uncertainty rather than measurements. Logged-out, public-data only. Not affiliated with Apple, Google, Sensor Tower, or data.ai.

The honest pitch: raw store metadata (title, rating, price) is a commodity a dozen scrapers already sell. The hard part - the part people pay for - is turning public signals into a credible download/revenue estimate. That is what this actor does, and it tells you exactly how confident it is and why.

### Run it in 30 seconds

```python
## Via the Apify Python SDK
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("seibs.co/app-store-revenue-estimator").call(run_input={
    "mode": "app_estimate",
    "apps": ["310633997", "com.spotify.music"],
    "country": "us"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
````

Or via curl:

```bash
curl -X POST "https://api.apify.com/v2/acts/seibs.co~app-store-revenue-estimator/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"mode": "app_estimate", "apps": ["310633997", "com.spotify.music"], "country": "us"}'
```

Or click "Try for free" on this page if you prefer the no-code UI.

### What you get

Each run produces:

- A clean dataset, filterable in the Apify console and downloadable as CSV or JSON
- An OUTPUT.html dashboard preview of your top records
- A sample-output preview at [`.actor/sample-output.json`](./.actor/sample-output.json)

Per record, the two things that matter:

- `app_record` - full public store metadata (title, developer, category, price, rating, ratings count, Play install bucket, dates, content rating, store URL)
- `estimate_enrichment` - the modeled `downloads_band {low, mid, high, period}` and `revenue_band_usd {low, mid, high, period}`, plus `confidence`, a human `methodology` sentence, and `caveats`

### Live example output

These are the shapes you get back. Bands are intentionally wide where the signal is weak and tighten as more signals agree.

- **A free app with a Play install bucket + ratings velocity** -> `downloads_band` anchored to the `10,000,000+` bucket and tightened by velocity, `confidence: high` (two independent signals agreeing), revenue modeled from the category IAP coefficient.
- **A paid app ranked #8 on the top-paid chart** -> daily `downloads_band` from the rank power law, gross `revenue_band_usd` = price x downloads, `confidence: medium` (one strong signal).
- **A long-tail app with only a ratings count** -> wide lifetime `downloads_band`, `confidence: low`, with a caveat telling you to run it on a schedule to add velocity and tighten it.

See [`.actor/sample-output.json`](./.actor/sample-output.json) for full, field-by-field examples.

### What does the App Store Revenue & Download Estimator do?

It pulls an app's public metadata from the official Apple iTunes endpoints (lookup / search / developer) and, for Android, from the logged-out public Google Play app page. Then it runs the **estimator**: it picks the strongest available download signal - a Google Play install bucket, a known chart rank, live ratings velocity, or (failing those) the lifetime ratings count - and produces a download band. It converts that to a revenue band: gross `price x downloads` for paid apps, or a per-category in-app-purchase coefficient times downloads for free/IAP apps. Finally it scores its own confidence by how many independent signals agree, and writes a plain-English sentence naming the signals it used. Run it on a schedule and it keeps a small per-app history so ratings velocity - the single best free proxy for daily downloads - sharpens every future estimate.

### Responsible use / data scope

This actor is a **public-data tool**. It reads only logged-out, publicly-served sources: Apple's official open iTunes endpoints and Google's public, logged-out Play app pages - no accounts, no cookies, no paywalls, no login walls. It behaves like a proportionate visitor (real browser TLS on Play, modest concurrency, polite request spacing). It minimizes PII: records are app and publisher firmographics (titles, categories, prices, ratings), not personal data. The download and revenue figures are **estimates with stated uncertainty, not measurements** - you are responsible for how you use them. This actor is **not affiliated with or endorsed by Apple, Google, Sensor Tower, or data.ai**.

### AI / RAG / Agent

A turn-key estimate feed for app-analytics agents, BD copilots, and investor-research bots. Each estimate arrives pre-modeled with `downloads_band`, `revenue_band_usd`, `confidence`, and a `methodology` string, so an agent can answer "roughly how big is this app, and how sure are we?" without building a model. Compatible with **LangChain**, **LlamaIndex**, **Pinecone**, **Weaviate**, **Chroma**, and any **MCP**-aware agent runtime (see the sibling `mcp-app-store-revenue-estimator` actor for direct tool-call wiring with agentic payments). An AI agent that needs a download/revenue estimate has no clean MCP source today - this is one.

### Features

- **Two stores, one schema** - Apple App Store (official iTunes endpoints) and Google Play (logged-out public page), normalized into a single `app_record`.
- **The estimate model** - four download-signal paths (Play install bucket, chart-rank power law, ratings velocity, lifetime ratings count) and a revenue model (gross for paid, category-coefficient for IAP), all in one auditable `CALIBRATION` table.
- **Stated confidence + methodology** - every estimate says how sure it is and why, in one human sentence, with caveats.
- **Publisher rollups** - point it at a developer and get every app under them plus a combined portfolio download/revenue band, top app, and category mix.
- **Top charts** - the top N apps in a country's chart, each estimated (Apple feeds; Play degrades gracefully with a note).
- **Time-series accuracy** - a per-app history KVStore means estimates tighten on scheduled re-runs as ratings velocity comes into focus.
- **Cost-control** - per-run budget guard + demo-mode soft-fail so runs finish SUCCEEDED.

### Use cases

- **Competitive benchmarking** - size a rival app's downloads and revenue before you build against it.
- **UA / growth planning** - estimate the scale of apps in your category and chart to set realistic targets.
- **Investor / M\&A diligence** - size an app business or a whole publisher's portfolio from public signals, with confidence flags.
- **Market mapping** - run a top chart and rank the category by estimated revenue.
- **Agent tooling** - give an LLM agent a callable "how big is this app" estimate with a built-in confidence score.

### Modes

| Mode | What it returns |
|---|---|
| `app_estimate` (default) | For each app id/URL: the full `app_record` plus an `estimate_enrichment` (download band, revenue band, confidence, methodology, caveats). |
| `publisher_rollup` | For each publisher (name or Apple artistId): every app under them, a per-app estimate, and one `publisher_rollup` (combined bands, top app, category mix). |
| `top_charts` | The top N apps in a country's chart (`top-free` / `top-paid`), each estimated. `top-grossing` falls back to `top-free` + ratings-velocity revenue (no public Apple grossing feed). Apple-only - Play has no public top-charts feed. |
| `estimate_monitor` | A watchlist of apps built for Apify Schedules: standard monitor-mode delta digest, and the mode that writes the per-app history so estimates sharpen over time. |

### Resolving apps (what you can paste)

- **iOS numeric track id**: `310633997`
- **Apple App Store URL**: `https://apps.apple.com/us/app/whatsapp-messenger/id310633997`
- **Google Play package id**: `com.whatsapp`
- **Google Play URL**: `https://play.google.com/store/apps/details?id=com.whatsapp`

Mix iOS and Android freely in one `apps` list - the actor routes each token to the right store.

### Input

See [`.actor/input_schema.json`](./.actor/input_schema.json) for the full form. Key fields:

```json
{
    "mode": "app_estimate",
    "apps": ["310633997", "com.spotify.music"],
    "country": "us",
    "include_play": true
}
```

```json
{
    "mode": "publisher_rollup",
    "publishers": ["Calm.com, Inc."],
    "country": "us"
}
```

```json
{
    "mode": "top_charts",
    "country": "us",
    "chart": "top-free",
    "top_n": 25
}
```

No API key or login is required - the Apple endpoints are open and Google Play is read logged-out.

### Output

In `app_estimate` mode you get one `estimate_enrichment` record (the headline) plus one `app_record` per app.

```json
{
    "record_type": "estimate_enrichment",
    "store": "google_play",
    "title": "Lumina - Habit Tracker",
    "developer": "Northwind Labs",
    "category": "Health & Fitness",
    "downloads_band": {"low": 10000000, "mid": 22360680, "high": 50000000, "period": "lifetime"},
    "revenue_band_usd": {"low": 36000.0, "mid": 201246.0, "high": 1125000.0, "period": "monthly"},
    "confidence": "high",
    "methodology": "Estimated from Play install bucket '10,000,000+'; ratings velocity 410.0/day; health_fitness IAP coefficient $0.045/download/mo x downloads.",
    "caveats": [
        "Estimate derived from public signals, not the publisher's actual figures.",
        "Grossing revenue assumes ~20% of lifetime installs are active monetizing users."
    ],
    "signals_used": ["play_install_bucket", "ratings_velocity"]
}
```

```json
{
    "record_type": "app_record",
    "store": "app_store",
    "app_id": "310633997",
    "title": "WhatsApp Messenger",
    "developer": "WhatsApp Inc.",
    "category": "Social Networking",
    "price": 0.0,
    "currency": "USD",
    "rating": 4.69,
    "ratings_count": 18059797,
    "store_url": "https://apps.apple.com/us/app/whatsapp-messenger/id310633997"
}
```

Apps that cannot be fetched (a blocked Play page, a bad id, an unsupported chart) still emit a `fetch_error` record with a human `reason`, so the run is auditable and never crashes.

### Pricing

Pay-per-event:

| Event | Price | When charged |
|---|---|---|
| `app_record` | $0.010 | Per app whose public store metadata is returned. |
| `estimate_enrichment` | $0.020 | Per app's modeled download + revenue band (the premium - the gated Sensor Tower / data.ai-style number). |
| `publisher_rollup` | $0.030 | Once per publisher portfolio record (combined bands, top app, category mix). |
| `scheduled_delta_run` | $0.050 | Once per scheduled monitor-mode run (also appends the ratings-velocity point that sharpens future estimates). |

A run that returns nothing costs nothing. A typical 2-app `app_estimate` run costs about $0.06 (two `app_record` + two `estimate_enrichment`). A 25-app `top_charts` run costs about $0.75.

### FAQ

**Q: How accurate are these numbers?**
A: They are **order-of-magnitude bands, not measurements.** We never have a publisher's real figures - we model from public signals and report a low/mid/high range with a stated confidence. A `high`-confidence estimate has two independent signals agreeing within 3x; a `low`-confidence one is a single weak signal and the band is deliberately wide. The honest expectation: the right ballpark and a credible range, with the model's reasoning shown. Run the same apps on a schedule and the bands tighten as ratings velocity comes into focus.

**Q: Why do Google Play install buckets help so much?**
A: Google publishes a coarse install count on every Play page (`10,000,000+`). That is a hard *lower bound the store itself states*, which anchors the download band directly - no modeling needed for the floor. Apple exposes no equivalent, so iOS-only estimates lean more on chart rank and ratings velocity and tend to be a touch wider.

**Q: Why do some apps come back low-confidence?**
A: Because the only signal available was a lifetime ratings count (no install bucket, no chart rank, no velocity history yet). That pins lifetime downloads loosely but says nothing about *daily* rate, so the band is wide and we flag it honestly rather than inventing precision. Adding the app to an `estimate_monitor` schedule fixes this over a few runs.

**Q: How does the estimate sharpen over time?**
A: Each run that sees an app appends `{date, ratings_count, rank, install bucket}` to a small per-app history (capped at 90 entries). Ratings velocity - new ratings per day - is the single best free proxy for daily downloads, and it needs at least two dated points. So a one-shot run has no velocity, but a scheduled run accumulates it and can lift an estimate from `medium` to `high`. Run it on a schedule and estimates tighten.

**Q: What about top-grossing charts?**
A: Apple's public v2 marketing feeds expose `top-free` and `top-paid` but **not** `top-grossing` (we verified this returns a 404 during the build). So `chart="top-grossing"` falls back to the top-free chart and estimates revenue from ratings velocity and category coefficients instead of a grossing-rank curve. The run notes this so you are never misled.

**Q: Can you estimate Google Play top charts?**
A: Not as a chart - Google exposes no public, stable top-charts feed, so `top_charts` is Apple-only. You can still estimate any Play app by passing its package id to `app_estimate` or `publisher_rollup`.

**Q: Is this legal?**
A: It reads only logged-out, public data - Apple's official open endpoints and Google's public Play pages - with no login, no cookies, and no paywall. It minimizes PII (app/publisher firmographics, not personal data). You are responsible for lawful use of the outputs. See "Responsible use / data scope" above.

**Q: Are you affiliated with Sensor Tower, data.ai, Apple, or Google?**
A: No. This is an independent public-data tool. The Sensor Tower / data.ai reference is to set expectations about what kind of modeled number this is; it is not a claim of affiliation or of matching their proprietary panels.

### Save your input as an Apify Task

Apify Tasks let you save a configured input once and re-run it with one click - the foundation for schedules, monitor mode, and the time-series accuracy (estimates sharpen most when the same app list runs on a cadence).

1. Click `Run` with your input configured.
2. Click `Save as task`.
3. Name it (e.g. `competitor app estimates - weekly`).
4. Reload the task page and click `Start` anytime.

### Run this weekly with Apify Schedules

1. Save your input as a Task (above) - use `mode: estimate_monitor` for a watchlist.
2. Go to https://console.apify.com/schedules and `Create new schedule`.
3. Pick your Task and set a cron expression (weekly Mondays 9am: `0 9 * * 1`).
4. Save. Each run appends a ratings-velocity point and tightens the bands.

### Monitor mode (beta)

When this actor runs under an Apify Schedule (typically with `mode: estimate_monitor`), monitor mode emits a change digest of estimate movements with a digest record at the top, and appends the velocity point to each app's history. Provide `monitor_webhook_url` and the digest also fires to your Slack channel. Cost: one `scheduled_delta_run` event ($0.05) per scheduled run plus standard PPE on the records emitted.

### Related Actors

- [google-maps-reviews-pro](https://apify.com/seibs.co/google-maps-reviews-pro) - review sentiment and topic intelligence, the same modeling muscle pointed at local-business reviews.
- [shopify-store-discovery](https://apify.com/seibs.co/shopify-store-discovery) - revenue-estimate sizing for e-commerce stores; the e-commerce analog of this actor.
- [sec-edgar-intel](https://apify.com/seibs.co/sec-edgar-intel) - public-filings intel for sizing the company behind a public app publisher.

### Support

Open an issue via the Apify Store contact link. Include the run ID and input config so the issue is reproducible.

### Changelog

See [CHANGELOG.md](./CHANGELOG.md).

### Found this useful?

If this actor saved you time or money, please leave a quick review on the Apify Store. Reviews help other buyers find work that solves their problem: https://apify.com/seibs.co/app-store-revenue-estimator#reviews

# Actor input Schema

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

app\_estimate = app ids/URLs -> full metadata + a modeled download/revenue band per app. publisher\_rollup = publisher names or Apple developer ids -> all their apps + per-app estimates + one portfolio rollup. top\_charts = country + chart -> the top N apps with estimates (Apple feeds; Play degrades gracefully). estimate\_monitor = a watchlist for Apify Schedules; standard monitor mode AND the mode that builds the time-series accuracy (each run adds a ratings-velocity point that sharpens future estimates).

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

Apps to estimate. Accepts: an iOS numeric track id (e.g. '310633997'), an Apple App Store URL (e.g. 'https://apps.apple.com/us/app/whatsapp-messenger/id310633997'), a Google Play package id (e.g. 'com.whatsapp'), or a Play URL (e.g. 'https://play.google.com/store/apps/details?id=com.whatsapp'). Used by app\_estimate and estimate\_monitor. Hard cap of 100.

## `publishers` (type: `array`):

Publishers to roll up (publisher\_rollup mode). Accepts a developer/company name (e.g. 'Calm.com, Inc.') resolved via App Store search, or an Apple developer artistId (e.g. '479516143'). Returns every app under that developer plus a combined portfolio band. Hard cap of 10.

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

Two-letter storefront code for lookups and charts (e.g. 'us', 'gb', 'jp', 'de'). Affects pricing, chart contents, and the rank->downloads scaling (US is tier 1; large markets tier 2; the rest tier 3). Default 'us'.

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

Which chart to pull in top\_charts mode. top-free and top-paid use Apple's public marketing RSS feeds. top-grossing has no public Apple v2 feed, so it falls back to the top-free chart and estimates revenue from ratings velocity / category coefficients instead of a grossing-rank curve (noted on the run).

## `chart_category` (type: `string`):

Optional Apple genre filter for top\_charts (a genre id like '6014' for Games, or a name). Leave empty for the overall chart. Note: the Apple marketing RSS feeds are overall-only in most storefronts, so this is best-effort and may be ignored when the storefront does not expose a per-genre feed.

## `top_n` (type: `integer`):

How many top-chart apps to estimate (top\_charts mode). Default 25. Hard cap of 200.

## `include_play` (type: `boolean`):

When true, Play package ids are scraped from the public Play app page (best-effort; any block becomes a fetch\_error and the run continues). When false, only Apple App Store ids are processed. Play has no top-charts feed, so top\_charts is always Apple-only.

## `monitor_webhook_url` (type: `string`):

When this actor runs under an Apify Schedule (estimate\_monitor / monitor mode), post the change digest to this Slack-compatible webhook URL.

## `use_apify_proxy` (type: `boolean`):

Route requests through Apify Proxy. DATACENTER is sufficient for the Apple iTunes endpoints and usually for Google Play; escalate to RESIDENTIAL only if Play starts blocking.

## `apify_proxy_groups` (type: `array`):

Apify Proxy groups. DATACENTER is the default and fine for Apple. Add RESIDENTIAL if Google Play blocks your datacenter IPs.

## `concurrency` (type: `integer`):

Parallel app fetches. Default 4. Kept modest to stay a polite, proportionate visitor.

## Actor input object example

```json
{
  "mode": "app_estimate",
  "apps": [
    "310633997",
    "com.spotify.music"
  ],
  "publishers": [],
  "country": "us",
  "chart": "top-free",
  "chart_category": "",
  "top_n": 25,
  "include_play": true,
  "monitor_webhook_url": "",
  "use_apify_proxy": true,
  "apify_proxy_groups": [
    "DATACENTER"
  ],
  "concurrency": 4
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Narrow, token-efficient slice of every record. Consumer: LLM agents (Claude, GPT, LangChain tools), MCP hosts, app-analytics dashboards.

## `datasetItemsEstimates` (type: `string`):

One row per estimated app: band, confidence, methodology, velocity. Consumer: UA/growth teams, competitive benchmarking, investors sizing app businesses.

## `datasetItemsPublishers` (type: `string`):

One row per publisher: combined portfolio download/revenue bands, top app, category mix. Consumer: investors, BD, competitive intel.

## `datasetItemsMcp` (type: `string`):

First 50 overview records as a clean JSON array. Wrap on the agent side in an MCP tool-call envelope. Consumer: MCP servers, Claude Desktop, Cursor, OpenAI Assistants tool calls.

## `datasetItemsCsv` (type: `string`):

Spreadsheet-friendly export of the overview view. Consumer: analysts in Excel / Google Sheets.

# 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 = {
    "mode": "app_estimate",
    "apps": [
        "310633997",
        "com.spotify.music"
    ],
    "country": "us",
    "chart": "top-free",
    "top_n": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("seibs.co/app-store-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 = {
    "mode": "app_estimate",
    "apps": [
        "310633997",
        "com.spotify.music",
    ],
    "country": "us",
    "chart": "top-free",
    "top_n": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("seibs.co/app-store-revenue-estimator").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 '{
  "mode": "app_estimate",
  "apps": [
    "310633997",
    "com.spotify.music"
  ],
  "country": "us",
  "chart": "top-free",
  "top_n": 25
}' |
apify call seibs.co/app-store-revenue-estimator --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "App Store Revenue & Download Estimator - iOS and Google Play",
        "description": "Estimate App Store and Google Play downloads and revenue from public signals (rank, rank history, ratings velocity, review deltas). Per-app records, modeled estimate bands, and publisher rollups. For app devs, UA/growth teams, and investors - the gated Sensor Tower/data.ai layer, priced per call.",
        "version": "0.1",
        "x-build-id": "EQxRaC2oplEd8NUHT"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/seibs.co~app-store-revenue-estimator/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-seibs.co-app-store-revenue-estimator",
                "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/seibs.co~app-store-revenue-estimator/runs": {
            "post": {
                "operationId": "runs-sync-seibs.co-app-store-revenue-estimator",
                "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/seibs.co~app-store-revenue-estimator/run-sync": {
            "post": {
                "operationId": "run-sync-seibs.co-app-store-revenue-estimator",
                "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": [
                            "app_estimate",
                            "publisher_rollup",
                            "top_charts",
                            "estimate_monitor"
                        ],
                        "type": "string",
                        "description": "app_estimate = app ids/URLs -> full metadata + a modeled download/revenue band per app. publisher_rollup = publisher names or Apple developer ids -> all their apps + per-app estimates + one portfolio rollup. top_charts = country + chart -> the top N apps with estimates (Apple feeds; Play degrades gracefully). estimate_monitor = a watchlist for Apify Schedules; standard monitor mode AND the mode that builds the time-series accuracy (each run adds a ratings-velocity point that sharpens future estimates).",
                        "default": "app_estimate"
                    },
                    "apps": {
                        "title": "Apps (iOS ids, Apple URLs, Play packages, or Play URLs)",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Apps to estimate. Accepts: an iOS numeric track id (e.g. '310633997'), an Apple App Store URL (e.g. 'https://apps.apple.com/us/app/whatsapp-messenger/id310633997'), a Google Play package id (e.g. 'com.whatsapp'), or a Play URL (e.g. 'https://play.google.com/store/apps/details?id=com.whatsapp'). Used by app_estimate and estimate_monitor. Hard cap of 100.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "publishers": {
                        "title": "Publishers (developer name or Apple artistId)",
                        "maxItems": 10,
                        "type": "array",
                        "description": "Publishers to roll up (publisher_rollup mode). Accepts a developer/company name (e.g. 'Calm.com, Inc.') resolved via App Store search, or an Apple developer artistId (e.g. '479516143'). Returns every app under that developer plus a combined portfolio band. Hard cap of 10.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "country": {
                        "title": "Country / storefront (ISO-2)",
                        "type": "string",
                        "description": "Two-letter storefront code for lookups and charts (e.g. 'us', 'gb', 'jp', 'de'). Affects pricing, chart contents, and the rank->downloads scaling (US is tier 1; large markets tier 2; the rest tier 3). Default 'us'.",
                        "default": "us"
                    },
                    "chart": {
                        "title": "Chart (top_charts mode)",
                        "enum": [
                            "top-free",
                            "top-paid",
                            "top-grossing"
                        ],
                        "type": "string",
                        "description": "Which chart to pull in top_charts mode. top-free and top-paid use Apple's public marketing RSS feeds. top-grossing has no public Apple v2 feed, so it falls back to the top-free chart and estimates revenue from ratings velocity / category coefficients instead of a grossing-rank curve (noted on the run).",
                        "default": "top-free"
                    },
                    "chart_category": {
                        "title": "Chart category (optional)",
                        "type": "string",
                        "description": "Optional Apple genre filter for top_charts (a genre id like '6014' for Games, or a name). Leave empty for the overall chart. Note: the Apple marketing RSS feeds are overall-only in most storefronts, so this is best-effort and may be ignored when the storefront does not expose a per-genre feed.",
                        "default": ""
                    },
                    "top_n": {
                        "title": "Top N apps (top_charts mode)",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "How many top-chart apps to estimate (top_charts mode). Default 25. Hard cap of 200.",
                        "default": 25
                    },
                    "include_play": {
                        "title": "Include Google Play",
                        "type": "boolean",
                        "description": "When true, Play package ids are scraped from the public Play app page (best-effort; any block becomes a fetch_error and the run continues). When false, only Apple App Store ids are processed. Play has no top-charts feed, so top_charts is always Apple-only.",
                        "default": true
                    },
                    "monitor_webhook_url": {
                        "title": "Monitor webhook URL (Slack / email, optional)",
                        "type": "string",
                        "description": "When this actor runs under an Apify Schedule (estimate_monitor / monitor mode), post the change digest to this Slack-compatible webhook URL.",
                        "default": ""
                    },
                    "use_apify_proxy": {
                        "title": "Use Apify Proxy",
                        "type": "boolean",
                        "description": "Route requests through Apify Proxy. DATACENTER is sufficient for the Apple iTunes endpoints and usually for Google Play; escalate to RESIDENTIAL only if Play starts blocking.",
                        "default": true
                    },
                    "apify_proxy_groups": {
                        "title": "Proxy groups",
                        "type": "array",
                        "description": "Apify Proxy groups. DATACENTER is the default and fine for Apple. Add RESIDENTIAL if Google Play blocks your datacenter IPs.",
                        "default": [
                            "DATACENTER"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "concurrency": {
                        "title": "Max concurrent requests",
                        "minimum": 1,
                        "maximum": 8,
                        "type": "integer",
                        "description": "Parallel app fetches. Default 4. Kept modest to stay a polite, proportionate visitor.",
                        "default": 4
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
