# App Store Publisher Leads — iOS & Android App Developers (`inovaflow/app-store-publisher-leads`) Actor

Find iOS and Android app publishers by store category, keyword or country and get one row per publisher: apps, ratings, downloads band, privacy labels, website, support email, plus emails and socials from their website. No login, dataset-only, MCP-ready.

- **URL**: https://apify.com/inovaflow/app-store-publisher-leads.md
- **Developed by:** [inovaflow](https://apify.com/inovaflow) (community)
- **Categories:** Lead generation, Business, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 publishers

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

If you sell to mobile app companies — analytics, attribution, ad networks, localization, testing, backend, payments, user research — your prospect list is sitting in two public places: the **App Store** and **Google Play**. Both show who publishes every app, how big it is and, on Google Play, the developer's support email, address and phone. **App Store Publisher Leads** turns a category, a keyword or a country chart into that list: **one row per publisher**, merged across both stores, with their apps, ratings, downloads band, privacy labels, website, support email and the **emails and social profiles found on their website**.

- **Mobile SaaS & SDK vendors** — every publisher in *Health & Fitness* with 1M+ downloads and an email.
- **Ad networks, mediation & UA agencies** — game studios by sub-genre (puzzle, casual, strategy) and country chart.
- **Localization, QA, ASO and analytics agencies** — publishers with many apps, or apps that track users (privacy labels).
- **Recruiters & investors** — indie studios that just broke into the top charts of a country.

### What does App Store Publisher Leads do?

It is an **app publisher finder and contact extractor** for iOS and Android. You give it store categories (`health-fitness`, `finance`, `games-puzzle` …), keywords (`meditation`), countries (`us`, `de`, `jp`) or pasted developer / app URLs. It reads the App Store charts and search (Apple's public iTunes API), the Google Play category, cluster and search pages, then looks each developer up on their store — every app of the developer on the App Store, the developer page on Google Play — and reads one app page per developer for the contact block, downloads and data-safety / privacy labels. Publishers found on both stores are merged into one row by website domain (or name). Finally it visits the publisher website (home + contact / about / imprint pages) for **email addresses, phone numbers and Facebook, Instagram, LinkedIn, X, YouTube, TikTok and WhatsApp links**. No login, no API key, no browser.

### Why use this app publisher scraper?

- **Publishers, not apps.** Other Actors give you 200 app rows with the same developer repeated; this gives you the company once, with its whole portfolio, on both stores.
- **Real contact data.** Google Play's developer support email, address and phone are on every Android row; the website crawl adds the rest. Nothing is guessed — a field is real or `null`.
- **Traction built in.** Apps count, top apps, total ratings, ratings-weighted average rating, Play downloads band (`10,000,000+`), and a 0–100 `leadScore` so you can sort by "big and reachable".
- **Privacy / SDK hints.** App Store privacy labels (`Tracks: Identifiers, Usage Data`) and Play data-safety lines (`Shares: Personal info, Financial info and 2 others`) — a strong signal for adtech, analytics and privacy vendors.
- **Predictable pricing.** A small per-publisher price; the contact fee applies **only when the row has an email or a social profile**. Filtered-out publishers and duplicates are free.
- **CRM- and agent-ready.** Flat rows with stable ids, `PUBLISHERS.csv` in the key-value store, and an `OUTPUT` run summary. Call it from the API, Zapier / Make / n8n, or an AI agent through MCP.

### What data does it extract?

| Field | Description |
| --- | --- |
| `publisherName`, `publisherId` | Publisher (developer) name and a stable id: `android:<devId>\|ios:<artistId>` |
| `stores` | `["ios"]`, `["android"]` or both |
| `iosDeveloperId`, `iosDeveloperUrl`, `androidDeveloperId`, `androidDeveloperUrl` | Developer ids and store pages per store |
| `website`, `domain` | Publisher website (App Store seller URL / Play developer website) and its domain |
| `supportEmail` | The developer email Google Play shows on the app page (Apple publishes none) |
| `supportUrl`, `privacyPolicyUrl` | App Store support link and the privacy policy URL |
| `address`, `country`, `phone` | Developer address, country and phone as shown on Google Play |
| `appsCount`, `iosAppsCount`, `androidAppsCount`, `appsCountIsLowerBound` | Portfolio size per store (`true` when Play listed more than the 110 apps read) |
| `topApps[]` | Up to 10 apps: store, id, name, url, rating, ratings count, installs, genre, free |
| `topAppName`, `topAppUrl` | The most-rated app |
| `categories[]`, `primaryCategory` | Store genres across the portfolio |
| `avgRating`, `totalRatings`, `ratingsCountedApps` | Ratings-weighted average and the sum of rating counts the stores report (App Store: all apps; Play: the app read in detail) |
| `downloadsBand`, `minInstalls` | Google Play downloads band of the largest app read (`50,000,000+`, `50000000`) |
| `privacyLabels[]`, `usesTracking` | App Store privacy types + Play data-safety summary; `usesTracking` = any "Tracks" / "Shares" label |
| `emails[]`, `primaryEmail` | Support email + emails found on the website (same-domain role addresses first) |
| `phonesFromWebsite[]`, `socials{}` | Extra phones and Facebook / Instagram / LinkedIn / X / YouTube / TikTok / Pinterest / WhatsApp links |
| `contactStatus`, `websitePagesCrawled` | `ok`, `no_contacts`, `no_website`, `unreachable`, `skipped` |
| `leadScore` | 0–100: reachability (email, website, phone, socials) + traction (ratings, installs) + portfolio size |
| `matchedBy[]`, `sources[]`, `scrapedAt` | Which chart / keyword / URL produced the row, the store URLs read, provenance |

### How to find app publishers by category

1. Open the Actor and click **Try for free**.
2. Under **Categories** add one or more ids — `health-fitness`, `finance`, `productivity`, `games-puzzle` … (the full list is in the field description; Apple genre ids like `6013` and Play ids like `HEALTH_AND_FITNESS` also work). Add **Keywords** for a niche (`meditation`, `invoice`) and **Store countries** (`us`, `gb`, `de`, `jp`, `br`) for local charts.
3. Set **Max publishers** (default 50). Turn on **Only publishers with an email address** to pay only for emailable rows.
4. Click **Start**. A 25-publisher run takes under a minute; rows appear in the **Output** tab.
5. Export as **CSV, Excel, JSON** or open `PUBLISHERS.csv` and import it into HubSpot, Pipedrive, Lemlist, Instantly or Google Sheets.

#### Enrich your own list of publishers

Paste App Store developer pages (`https://apps.apple.com/us/developer/…/id571800813`), Google Play developer pages (`…/store/apps/dev?id=…` or `…/developer?id=Name`) or app pages (`…/app/…/id…`, `…/details?id=com.x.y`) into **Developer or app URLs**. Each becomes a publisher row, merged with anything else the run finds.

### How much does it cost?

Pay-per-event, no subscription: **$0.02 per publisher delivered** plus **$0.01 when the row carries at least one email or social profile**, and a $0.005 run-start fee. 1,000 fully enriched publishers cost at most **$30**; publishers without any contact cost $0.02. Filtered-out publishers, duplicates and empty runs are free. Compute is tiny (a 25-publisher run uses ~0.01 compute units), and the stores are read through the run's own connection, so no proxy traffic is needed by default.

### Input

Nothing is strictly required — give at least one category, keyword or URL. Example:

```json
{
    "categories": ["health-fitness", "medical"],
    "keywords": ["meditation"],
    "countries": ["us", "gb"],
    "maxPublishers": 100,
    "onlyWithEmail": true,
    "minRatings": 10000
}
```

### Output

One dataset item per publisher:

```json
{
    "publisherName": "Strava, Inc.",
    "publisherId": "android:Strava Inc.|ios:331028478",
    "stores": ["android", "ios"],
    "iosDeveloperId": "331028478",
    "iosDeveloperUrl": "https://apps.apple.com/us/developer/id331028478",
    "androidDeveloperId": "Strava Inc.",
    "androidDeveloperUrl": "https://play.google.com/store/apps/developer?id=Strava+Inc.",
    "website": "https://www.strava.com/",
    "domain": "strava.com",
    "supportEmail": "support@strava.com",
    "supportUrl": "https://support.strava.com/",
    "privacyPolicyUrl": "https://www.strava.com/legal/privacy",
    "address": "208 Utah St, Suite 300\nSan Francisco, CA 94103\nUnited States",
    "country": "United States",
    "phone": null,
    "appsCount": 6,
    "iosAppsCount": 3,
    "androidAppsCount": 3,
    "topApps": [
        { "store": "ios", "appId": "426826309", "name": "Strava: Run, Bike, Hike", "url": "https://apps.apple.com/us/app/strava-run-bike-hike/id426826309", "rating": 4.8, "ratingsCount": 1088245, "installs": null, "genre": "Health & Fitness", "free": true },
        { "store": "android", "appId": "com.strava", "name": "Strava: Run, Bike, Walk", "url": "https://play.google.com/store/apps/details?id=com.strava", "rating": 4.62, "ratingsCount": 513122, "installs": "100,000,000+", "genre": "Health & Fitness", "free": true }
    ],
    "topAppName": "Strava: Run, Bike, Hike",
    "categories": ["Health & Fitness", "Sports"],
    "primaryCategory": "Health & Fitness",
    "avgRating": 4.65,
    "totalRatings": 1601367,
    "downloadsBand": "100,000,000+",
    "minInstalls": 100000000,
    "privacyLabels": ["Tracks: Identifiers, Usage Data", "Linked: Purchases, Location, Contact Info, …", "Shares: Location, Personal info and 3 others", "Collects: Location, Personal info and 7 others"],
    "usesTracking": true,
    "emails": ["support@strava.com", "press@strava.com"],
    "primaryEmail": "support@strava.com",
    "socials": { "facebook": "https://www.facebook.com/Strava", "instagram": "https://www.instagram.com/strava", "linkedin": "https://www.linkedin.com/company/strava", "twitter": "https://twitter.com/strava", "youtube": "https://www.youtube.com/strava", "tiktok": null, "pinterest": null, "whatsapp": null },
    "contactStatus": "ok",
    "leadScore": 96,
    "matchedBy": ["ios:category:health-fitness:top-free:us", "android:category:health-fitness:us"],
    "scrapedAt": "2026-09-26T13:53:52.615Z"
}
```

The key-value store also holds **`PUBLISHERS.csv`** and **`OUTPUT`** (run summary: publishers delivered, with email, merged across stores, per store / per chart, candidates seen, requests, failed sources).

### Tips

- **Combine charts and keywords.** Category charts give the market leaders; keywords give the long tail of a niche. Both merge into one deduplicated list.
- **Use country charts for local lists.** `countries: ["de"]` returns the German top charts — publishers there are often German companies with `.de` websites.
- `usesTracking = true` + `downloadsBand ≥ 1,000,000+` is a good adtech / analytics segment; `appsCount ≥ 5` a good segment for tooling and localization.
- **iOS-only publishers have no store email** (Apple does not publish one) — their emails come from the website crawl, so keep `enrichContacts` on.

### FAQ

#### Does it need an Apple or Google account?

No. It reads Apple's public iTunes Search / Lookup API, public App Store and Google Play web pages, and public publisher websites.

#### How are publishers merged across stores?

By website domain first (site builders and social profiles are ignored as keys), then by normalised name ("Calm.com, Inc." = "Calm.com"). Two developer accounts of the same store are never merged.

#### Why is `appsCount` a lower bound for some Android publishers?

Google Play lists a developer's apps in pages of 100 through the store's own RPC; the Actor reads the first page. Publishers with more than ~110 apps get `appsCountIsLowerBound: true`.

#### Why do some rows have `totalRatings` but no `downloadsBand`?

Only Google Play shows downloads. App Store-only publishers have ratings counts (for every app) but no install numbers.

#### Can it read reviews or app descriptions?

No — this Actor is built for publisher lead generation. Use a dedicated App Store / Google Play reviews scraper for that.

#### Is this legal?

The Actor extracts only what publishers have chosen to publish on the stores and on their own websites — business contact information published for business purposes. You are responsible for complying with GDPR, CAN-SPAM and similar laws when you contact them.

### Support

Open an issue in the **Issues** tab with your run ID and the input that misbehaved. The **API** tab shows how to call this Actor from code or from any MCP-capable AI agent.

# Actor input Schema

## `categories` (type: `array`):

Store categories to read the charts of (App Store: top free + top grossing per genre; Google Play: the category page and its "see more" clusters). Ids: `business`, `developer-tools`, `education`, `entertainment`, `finance`, `food-drink`, `graphics-design`, `health-fitness`, `lifestyle`, `medical`, `music`, `navigation`, `news`, `photo-video`, `productivity`, `reference`, `shopping`, `social`, `sports`, `travel`, `utilities`, `weather`, `dating`, `parenting`, `personalization`, `communication`, `auto-vehicles`, `house-home`, `events`, `beauty`, `games`, `games-action`, `games-adventure`, `games-arcade`, `games-board`, `games-card`, `games-casino`, `games-casual`, `games-educational`, `games-music`, `games-puzzle`, `games-racing`, `games-role-playing`, `games-simulation`, `games-sports`, `games-strategy`, `games-trivia`, `games-word`. Apple genre ids (`6013`) and Play ids (`HEALTH_AND_FITNESS`) work too.

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

Search terms, one per line — App Store search (up to 200 apps each) and Google Play search (~20–30 apps each). Publishers of the matching apps are collected.

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

Two-letter storefront codes: `us`, `gb`, `de`, `fr`, `jp`, `br`, `in` … Charts and search results differ per country; publishers found in several countries are delivered once.

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

Which stores to read. Both by default; a publisher present on both is one row with both developer ids.

## `developerUrls` (type: `array`):

Paste App Store / Google Play developer pages (`apps.apple.com/us/developer/…/id123`, `play.google.com/store/apps/dev?id=…`, `…/developer?id=Name`) or app pages (`…/app/…/id123`, `…/details?id=com.x.y`) to build or enrich a list of specific publishers.

## `maxPublishers` (type: `integer`):

Stop after this many publisher rows (after merging and filtering). Only delivered rows are charged.

## `enrichContacts` (type: `boolean`):

Visits the publisher website (home + contact/about/imprint pages) for email addresses, phone numbers and Facebook / Instagram / LinkedIn / X / YouTube / TikTok links. Google Play's developer support email is always included, with or without this.

## `includePrivacyLabels` (type: `boolean`):

Fetches one App Store web page per iOS publisher (their top app) for the App Privacy labels ("Tracks: Identifiers, Usage Data"), the support URL and privacy policy URL. Google Play data-safety labels come from the app page regardless.

## `onlyWithEmail` (type: `boolean`):

Deliver (and pay for) only publishers with at least one email — the store's support email or one found on the website.

## `onlyWithWebsite` (type: `boolean`):

Skip publishers that list no website on either store.

## `minRating` (type: `number`):

Skip publishers whose apps average below this rating (1–5).

## `minRatings` (type: `integer`):

Skip publishers with fewer ratings than this across the apps the stores report counts for (App Store: all their apps; Google Play: the app found in the chart).

## `minApps` (type: `integer`):

Skip publishers with fewer published apps than this.

## `iosCharts` (type: `array`):

Which charts to read for each category on the App Store (200 apps each).

## `maxAppsPerSource` (type: `integer`):

How deep to read each chart, category page or search (top of the chart first).

## `maxContactPages` (type: `integer`):

How many pages of each publisher website to read when extracting contacts.

## `maxConcurrency` (type: `integer`):

How many store pages and publisher websites are fetched in parallel.

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

Store endpoints are read through the run's own connection first and fall back to this proxy only when blocked. Apify datacenter proxies are enough; residential is rarely needed.

## Actor input object example

```json
{
  "categories": [
    "health-fitness"
  ],
  "countries": [
    "us"
  ],
  "stores": [
    "ios",
    "android"
  ],
  "maxPublishers": 25,
  "enrichContacts": true,
  "includePrivacyLabels": true,
  "onlyWithEmail": false,
  "onlyWithWebsite": false,
  "iosCharts": [
    "top-free",
    "top-grossing"
  ],
  "maxAppsPerSource": 100,
  "maxContactPages": 3,
  "maxConcurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `publishers` (type: `string`):

One row per publisher: name, stores, developer ids, apps count, top apps, categories, ratings, downloads band, website, support email, privacy labels.

## `leads` (type: `string`):

The lead view: emails, phone, socials, address and lead score per publisher.

## `csv` (type: `string`):

Spreadsheet-ready copy of the dataset (first 5,000 rows).

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

Publishers delivered and charged, per store and per category/keyword, candidates seen, requests made, failed sources and notices.

# 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 = {
    "categories": [
        "health-fitness"
    ],
    "countries": [
        "us"
    ],
    "stores": [
        "ios",
        "android"
    ],
    "maxPublishers": 25,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("inovaflow/app-store-publisher-leads").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 = {
    "categories": ["health-fitness"],
    "countries": ["us"],
    "stores": [
        "ios",
        "android",
    ],
    "maxPublishers": 25,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("inovaflow/app-store-publisher-leads").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 '{
  "categories": [
    "health-fitness"
  ],
  "countries": [
    "us"
  ],
  "stores": [
    "ios",
    "android"
  ],
  "maxPublishers": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call inovaflow/app-store-publisher-leads --silent --output-dataset

```

## MCP server setup

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

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/UmMDY4DNctFNSUgIy/builds/hr1HqdaINn5LW5Sj9/openapi.json
