# App Store Price Scraper - Compare by Country (`dataio/app-store-price-intelligence`) Actor

Scrape App Store app data across up to 60 countries in one run: local price converted to USD, rating, localized name, days since the last update, and the countries where an app is not distributed at all. Compare iOS app pricing market by market. No API key.

- **URL**: https://apify.com/dataio/app-store-price-intelligence.md
- **Developed by:** [Tom Awake](https://apify.com/dataio) (community)
- **Categories:** E-commerce, SEO tools, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 app rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### What does App Store Price Scraper do?

The same app across **every market at once** — local price converted to
USD, local rating, localised name, release cadence, and the countries
where it is not distributed at all.

Apple's search API answers for **one country per request**. Asking "what
does my competitor charge in Brazil, Japan and India" means one request
per market and a manual reconciliation afterwards. Almost nobody does it,
and that is exactly where the gaps are.

No API key. No account.

***

### What the gaps actually look like

Measured, not illustrative. One paid app across 18 markets:

| App | Cheapest | Dearest | Spread |
|---|---|---|---|
| **Procreate** | $10.40 (India, ₹999) | $18.23 (Sweden, 179 kr) | **+75%** |
| **Streaks** | $5.99 (US) | $8.04 (Germany, €6.99) | **+34%** |

And ratings diverge further than prices do:

| App | Lowest | Highest | Gap |
|---|---|---|---|
| **Procreate** | 3.56 (Korea) | 4.59 (Sweden) | **1.03 points** |
| **Habitica** | 4.01 (UK) | 4.48 (Brazil) | 0.47 |
| **Instagram** | 4.50 (UAE) | 4.81 (Mexico) | 0.31 |

A full point of rating gap on the same software is not a curiosity — it
is a market where something is wrong, and the global average hides it
completely.

***

### The four things this does that the source does not

**1. One row per app *and per market*.**

The source returns one row per request. Here, 200 apps across 20 countries
is 4,000 rows in a single run, already aligned and comparable.

**2. Local price converted to USD.**

₹999, 179 kr and ¥1,800 are not comparable until they are. Converted at
the day's rates across 166 currencies, so `priceUsd` sorts correctly. The
local price and currency are kept alongside — the conversion never
replaces the source figure.

**3. Non-distribution, stated.**

Spotify returns nothing in China. Procreate is absent from several
markets. Six of Meta's sixteen apps are not distributed in France, five
not in Japan.

A missing row looks like a collection failure. A row marked
`available: false` tells you a competitor decided not to enter that
market — and those rows are **not charged**.

**4. Days since the last update.**

An abandoned app keeps its rating; only the gap since its last release
gives it away. Measured on one keyword search: **12% had not been updated
in over a year**, the worst standing at 2,343 days. The source gives a
date, never a delay.

***

### Field coverage

Measured on 71 available rows across 18 markets.

| Field | Coverage |
|---|---|
| `appName`, `developer`, `bundleId` | 100% |
| `rating`, `ratingCount` | 100% |
| `version`, `releaseDate`, `lastUpdatedAt` | 100% |
| `daysSinceUpdate`, `appAgeYears` | 100% |
| `fileSizeMb`, `languages`, `appUrl` | 100% |
| `price`, `priceUsd` | every paid app |

`appName` is the **localised** name: 抖音 in China, "Spotify Musik und
Podcasts" in Germany, "Spotify (스포티파이)" in Korea. That is the real
listing, not a translation — and in China it is a different product
entirely, with 52 million ratings of its own.

***

### What it is for

- **International pricing.** Set your price in 40 markets from what
  competitors actually charge there, not from a spreadsheet conversion.
- **ASO and localisation.** Which markets rate you worst, and how your
  competitor names the same app in Japanese or Portuguese.
- **Competitive monitoring.** A developer's whole catalogue, with release
  cadence per app — who ships weekly, who has stopped.
- **Market entry.** The countries your competitors skipped are either an
  opportunity or a warning, and you cannot see either without the
  non-distribution rows.
- **Acquisition screening.** Apps with strong ratings, real review volume
  and no update in two years.

Three dataset views ship with the Actor: **Apps by market**, **Price by
market** and **Release cadence**.

***

### Limits

Stated plainly, because they affect what you can conclude.

- **Keyword search caps at about 195 apps.** That is Apple's ceiling, not
  ours. Narrow the term, or supply app IDs directly.
- **No ranking or download numbers.** Apple does not publish chart
  position or install counts through this API, and this Actor does not
  invent them. Rating volume is the closest available proxy.
- **Ratings are cumulative, and lifetime by default.**
  `currentVersionRating` is the honest one when a recent release changed
  things; the headline `rating` can be years of history.
- **Exchange rates are same-day.** `priceUsd` is a comparison aid, not an
  accounting figure — and a price set at ₹999 does not move when the
  rupee does, so spreads partly reflect currency drift rather than
  deliberate pricing.
- **In-app purchases are not priced here.** A free app with a $99/year
  subscription shows as free, because that is what the store API returns.
- **Some markets genuinely differ in product, not just listing.** The
  Chinese entry for TikTok is Douyin — a separate app with its own
  ratings. Treat cross-market comparison with care where the product
  itself diverges.
- **Not every country code is an App Store market.** Unknown codes simply
  return nothing.

***

### Use App Store Price Scraper as an API

Call it from your own code with the Apify client, here in Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("DataIO/app-store-price-intelligence").call(run_input={
    'searchTerm': 'habit tracker',
    'countries': ['us', 'gb', 'de', 'jp', 'br'],
    'minReviews': 100,
    'maxItems': 800,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

It also works from JavaScript, Make, Zapier, n8n, and from AI agents through the Apify MCP server.

### Other actors you might like

- [App Store Reviews Scraper](https://apify.com/DataIO/app-store-reviews-by-country-version): By Country & Version
- [Steam Price Scraper](https://apify.com/DataIO/steam-regional-pricing-intelligence): Regional Game Prices
- [Steam Reviews Scraper](https://apify.com/DataIO/steam-reviews-playtime-scraper): With Playtime Data

### FAQ

#### Is it legal to use this data?

The actor reads public data from its official source, without logging in and without bypassing any access control. What you do with the data, for example contacting people listed in it, is your responsibility under the laws that apply to you, such as GDPR in Europe.

#### Can I run it on a schedule?

Yes. Create a schedule in Apify Console, daily or weekly for example, and each run delivers a fresh dataset, which you can send by email, webhook or integration.

#### Can AI agents use it?

Yes. It is available through the Apify MCP server, and every input field is described in its input schema, so an agent can call it directly.

### Source

Apple's public [iTunes Search
API](https://itunes.apple.com), the same endpoint that powers App Store
links across the web, plus [open.er-api.com](https://open.er-api.com) for
exchange rates. Both public, no authentication. This Actor is not
affiliated with Apple.

# Actor input Schema

## `searchTerm` (type: `string`):

Keyword, as a user would type it in the App Store — habit tracker, budget, meditation. Returns up to about 195 apps, which is Apple's own ceiling.

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

Numeric App Store IDs, the digits after /id in an App Store URL. Use this to track a fixed set of competitors across markets.

## `developerIds` (type: `array`):

Numeric developer IDs. Returns that developer's entire catalogue — the fastest way to see everything a competitor ships.

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

Two-letter country codes: us, gb, de, fr, jp, cn, in, br, kr, au… Every country adds one row per app. This is where the value is — the same app has a different price, a different rating and sometimes a different name in each market.

## `platform` (type: `string`):

iPhone, iPad or Mac apps.

## `pricing` (type: `string`):

Paid apps are where price comparison matters — measured spread on one paid app across 18 markets was 75%.

## `minRating` (type: `integer`):

0 to 5. Applied per market, so an app can pass in one country and fail in another — which is itself the finding.

## `minReviews` (type: `integer`):

A rating with no volume behind it means nothing. 100 removes most of the noise from a keyword search.

## `updatedWithinDays` (type: `integer`):

Removes abandoned apps. Measured on a keyword search: 12% had not been updated in over a year, the worst in 2,343 days.

## `includeUnavailable` (type: `boolean`):

On by default, and deliberately: a missing row looks like a collection error. A row marked not available tells you a competitor chose not to enter that market.

## `maxItems` (type: `integer`):

One row per app per country. 200 apps across 20 countries is 4,000 rows.

## Actor input object example

```json
{
  "searchTerm": "habit tracker",
  "countries": [
    "us",
    "gb",
    "de",
    "jp",
    "br"
  ],
  "platform": "iphone",
  "pricing": "all",
  "includeUnavailable": true,
  "maxItems": 1000
}
```

# Actor output Schema

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

Every row produced by the run, in JSON.

# 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 = {
    "searchTerm": "habit tracker",
    "countries": [
        "us",
        "gb",
        "de",
        "jp",
        "br"
    ],
    "maxItems": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataio/app-store-price-intelligence").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 = {
    "searchTerm": "habit tracker",
    "countries": [
        "us",
        "gb",
        "de",
        "jp",
        "br",
    ],
    "maxItems": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("dataio/app-store-price-intelligence").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 '{
  "searchTerm": "habit tracker",
  "countries": [
    "us",
    "gb",
    "de",
    "jp",
    "br"
  ],
  "maxItems": 1000
}' |
apify call dataio/app-store-price-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataio/app-store-price-intelligence"
        }
    }
}
```

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/Tw50rDj1qLZeE2ymZ/builds/Rt16U9WhRoSfaubkK/openapi.json
