# Google Play Scraper: Support Emails, Sites & Dead Links (`aiqlabs/google-play-audit`) Actor

Google Play requires a support email on every listing and never rechecks it. This audits them: addresses whose domain bounces, domains nobody has registered at all - anyone can take that address - developer websites that lead nowhere, and apps left behind the target API level requirement.

- **URL**: https://apify.com/aiqlabs/google-play-audit.md
- **Developed by:** [Ai-Q Labs](https://apify.com/aiqlabs) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Google Play Audit

Google Play requires a support email on every listing. All 225 listings sampled in July 2026 had one. Nobody ever checks them again.

This Actor does.

- **Support addresses that bounce.** The domain does not resolve, or resolves and publishes no MX. Either way, mail to the address the store shows your users goes nowhere.
- **Support domains nobody has registered.** The severe case. Anyone can register the domain and start receiving the app's official support address — which is where password resets and account recovery are sent.
- **Developer websites that lead nowhere**, and the registrations behind them.
- **Apps left behind**, with the base rate attached so the number means something.

### The finding this exists for

`com.succocloud.tipcalculator` — a live app, last updated February 2026 — publishes `admin@succocloud.com` on its Play listing. That domain is not registered. Not lapsed, not parked: **free**.

`com.communitycompass`, run by a food-assistance non-profit and updated the day before this was written, publishes an address on `indyhunger.com`. Also unregistered.

Neither is unusual enough to be a coincidence and neither is common enough to be noise: of 108 developer-owned mail domains in the sample, **3 (2.8%)** could not receive mail.

### What comes out

One row per app: the listing metadata, what each check found, a list of issues with severities, and an overall `riskLevel` of `critical` / `high` / `medium` / `low` / `ok`.

| Record | Contents |
|---|---|
| `SUMMARY` | Counts by severity, how many apps carried each finding, the base rates, and every caveat that applies to this run |
| `ACTION_LIST` | Findings ranked by severity, then by how many people rated the app |
| `CONTACT_REPORT` | Three lists, kept apart on purpose: addresses **anyone could take**, addresses that merely **bounce**, and **dead developer sites** |

### Input

```json
{
  "apps": [
    "com.succocloud.tipcalculator",
    "https://play.google.com/store/apps/details?id=com.whatsapp"
  ],
  "searchTerms": ["flashlight"],
  "staleAfterDays": 1095
}
```

Package ids, Play store URLs, or search terms to survey a category.

### What it will not do

**It does not read Data safety pages.** Those live under `/store/apps/datasafety`, which `play.google.com/robots.txt` disallows. robots.txt is re-read at the start of every run, and if Play ever disallows the listing path the run stops rather than continuing.

**It does not contact a mail server.** No SMTP connection, no address verification, no probing whether a mailbox exists. Only whether the domain is capable of receiving mail at all — which is a DNS question and answers the one that matters.

**It does not pretend to be a browser.** Some developer sites, `whatsapp.com` among them, answer an automated request with 403. That is a live server declining to talk to a program, and it is reported as `developer_site_blocked`, severity `low` — "the server is up and refused an automated request; that says nothing about whether a person clicking through from Play reaches a page."

**It does not tell you why.** Play answers the same way for an app that was removed, one that was never published, and one restricted to other countries.

### Severities, and why they sit where they do

Measured on 225 live Play listings, July 2026:

- **100%** published a support email. So a listing with none is reported as *a probable change in the page*, at `low` — not as an app without support.
- **About half** those addresses were free webmail. The developer does not run that mail server, so those are **never flagged**.
- **87%** published a developer site. The other 13% are **not a finding**; Play does not require one.
- **2.7%** had gone three years without an update.

A warning that fires on healthy input erases the `ok` rows, which is the only thing that makes the other rows worth reading.

| Finding | Severity |
|---|---|
| `app_not_found` | critical |
| `support_email_domain_unregistered` — the address is free to take | critical |
| `developer_site_domain_unregistered` | critical |
| `support_email_undeliverable` — no MX, or the domain does not resolve | high |
| `developer_site_dead` | high |
| `developer_site_domain_reregistered` | high |
| `no_update_in_years`, `developer_site_offsite`, `developer_site_error`, `developer_site_server_error`, `developer_site_invalid` | medium |
| `support_email_not_found`, `support_email_check_failed`, `developer_site_blocked`, `developer_site_insecure`, `update_date_unreadable`, `listing_not_read` | low |

A domain whose registration could not be read is `unknown`, never `ok`.

### Cost and courtesy

One request per listing with a deliberate pause between them, **one DNS check per distinct mail domain** (a developer with forty apps has one domain, not forty), one probe per distinct developer URL, and a registry lookup only where it changes a verdict. RDAP runs two at a time because registries operate those servers as a public service.

### Verification

33 unit tests and 21 live checks against the real store, real DNS and real registries. Every true positive in the live file has a negative control beside it.

# Actor input Schema

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

Apps to audit, as package ids (com.whatsapp) or Play store URLs (https://play.google.com/store/apps/details?id=com.whatsapp).

## `searchTerms` (type: `array`):

Audit the top Play search results for these terms. Useful for surveying a category rather than a known list of apps.

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

Two-letter country code for the Play storefront to read.

## `language` (type: `string`):

Two-letter language code for the listing pages. Leave as 'en': the support email and update date are read from Play's English accessibility labels, and another language may return them empty.

## `checkDeveloperSites` (type: `boolean`):

Follow the developer website shown on each listing and report where it ends up. One request per distinct URL, not per app.

## `checkDomainRegistration` (type: `boolean`):

Read the registry record (RDAP) for mail domains that bounce and for websites that failed. This is what distinguishes an address that merely bounces from one anyone could register and start receiving.

## `staleAfterDays` (type: `integer`):

How long without an update before it is worth reporting. Default is 1095 days (three years). Only 2.7% of a 225-app sample measured in July 2026 were this old, because Google hides apps from new installs once they fall behind the target API level requirement.

## `searchLimit` (type: `integer`):

How many apps to take from each search term.

## `onlyIssues` (type: `boolean`):

Drop the rows where nothing was found. The counts in SUMMARY still cover every app checked.

## `maxApps` (type: `integer`):

Upper bound on how many apps are audited in one run, after search terms are expanded.

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

How many listings to read at once. RDAP lookups are capped lower than this because registries run those servers as a public service.

## `requestDelayMs` (type: `integer`):

A deliberate pause after each listing page. These are ordinary page loads on someone else's server; a burst would be rude whatever robots.txt permits.

## `requestTimeoutSecs` (type: `integer`):

Per-request timeout for Play, developer websites and RDAP.

## Actor input object example

```json
{
  "apps": [
    "com.succocloud.tipcalculator",
    "com.communitycompass",
    "com.whatsapp"
  ],
  "country": "us",
  "language": "en",
  "checkDeveloperSites": true,
  "checkDomainRegistration": true,
  "staleAfterDays": 1095,
  "searchLimit": 25,
  "onlyIssues": false,
  "maxApps": 200,
  "maxConcurrency": 4,
  "requestDelayMs": 600,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

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

No description

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

No description

## `actionList` (type: `string`):

No description

## `contactReport` (type: `string`):

No description

## `summary` (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": [
        "com.succocloud.tipcalculator",
        "com.communitycompass",
        "com.whatsapp"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("aiqlabs/google-play-audit").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": [
        "com.succocloud.tipcalculator",
        "com.communitycompass",
        "com.whatsapp",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("aiqlabs/google-play-audit").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 '{
  "apps": [
    "com.succocloud.tipcalculator",
    "com.communitycompass",
    "com.whatsapp"
  ]
}' |
apify call aiqlabs/google-play-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=aiqlabs/google-play-audit",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1EMUASlEEdlyOH9eL/builds/Hr7ItBRLPU65klzfX/openapi.json
