Google Play App Ratings Scraper
Under maintenancePricing
from $3.00 / 1,000 app rating results
Google Play App Ratings Scraper
Under maintenanceExtract one Google Play app's public aggregate rating and rating count as timestamped JSON. Enter an app URL and page language; no EliDev key or Google login. Native, bounded runs with strict URL validation. Individual reviews are not included. Pay per delivered snapshot, plus a small start fee.
Pricing
from $3.00 / 1,000 app rating results
Rating
5.0
(1)
Developer
EliDev
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
Google Play App Ratings Scraper - EliDev
Get an Android app’s public aggregate rating and rating count as a timestamped JSON snapshot. Enter one official Google Play app URL and a page language. This Actor runs natively on Apify: no EliDev API key, Google login, browser or proxy required.
Aggregate ratings only. Individual written reviews, reviewer profiles, downloads, rankings, app binaries and catalog search are outside this product.
What you receive
| Field | Meaning |
|---|---|
| source / kind / status | google_play / ratings / completed for a valid snapshot |
| url / app_id | Validated source URL and Android package identifier |
| language | Requested page language; not a guaranteed country-specific rating |
| data.rating | Observed finite aggregate rating from 1 to 5 |
| data.rating_count | Public aggregate count, or null if unavailable; not written-review count |
| observed_at | UTC observation timestamp |
A missing rating fails extraction instead of fabricating zero. Rating count may be null. Values can change and need not match every country, device or Google Play account.
Use it to record app-quality indicators, populate a small dashboard, or compare dated snapshots your application retains. One app per run; no batch processing or continuous monitoring is bundled.
Quick start
- Open Input and keep the prefilled WhatsApp example, or supply an official app-details URL you are entitled to access.
- Choose en, fr, de, es, it, pt or nl. Example listings: https://play.google.com/store/apps/details?id=com.whatsapp and https://play.google.com/store/apps/details?id=com.google.android.youtube (the app listing, not YouTube channel statistics).
- Click Run with the default settings (256 MB RAM, 120 seconds). The Actor's configured default spending ceiling is $0.02. Console may supply its own higher platform default; this is an allowance, not the amount charged. One ordinary success produces one $0.003 result plus one $0.00005 start event. You can choose a lower sufficient ceiling in Apify's run options.
- After SUCCEEDED, open Output → App Ratings to see App ID, App Rating (1–5) and Number of Ratings first, followed by language, URL, observation time, source, kind and status. The separate OUTPUT key-value record contains the business/billing summary. An old OUTPUT alone does not prove the current status of a resurrected run.
- Export JSON/CSV within your retention period. Keep the run ID when investigating errors; do not blindly start another chargeable run.
Input
{"url":"https://play.google.com/store/apps/details?id=com.whatsapp","language":"en"}
Both fields have defaults. HTTPS, exact hostname play.google.com and path /store/apps/details are required, with one valid id parameter. Optional hl must match language. Explicit ports, credentials, fragments, tracking/unknown/duplicate parameters, other hosts, lists and search pages are rejected. Unknown INPUT fields are refused. Provider and kind are fixed; there is no apiKey, userId, runId, review limit, dates or arbitrary destination.
Never put a secret in INPUT, even in an unknown field: Apify can store INPUT before validation.
Observed Dataset example
The App Ratings view flattens the nested data object for display only: its columns use data.rating and data.rating_count. Raw Dataset JSON keeps the historical nested data object. Use Storage → Dataset → Preview or the authenticated GET /v2/datasets/{datasetId}/items endpoint without a view parameter for raw JSON. This is one stored item with two ways to read it, not two billed results. Display schemas are attached to each run's storage; a new release does not necessarily repair older runs' saved views.
This is a real private-cloud snapshot from 30 October 2026, not a live promise for WhatsApp:
{"source": "google_play","kind": "ratings","url": "https://play.google.com/store/apps/details?id=com.whatsapp","app_id": "com.whatsapp","language": "en","status": "completed","data": {"rating": 4.6240997314453125, "rating_count": 246712920},"observed_at": "2026-10-30T20:17:06.765308+00:00"}
OUTPUT is a separate summary. Example successful summary (budget-dependent values can differ):
{"status":"completed","source":"google_play","kind":"ratings","item_count":1,"billing":{"mode":"ppe-dataset","event":"apify-default-dataset-item","charged_count":1,"event_charge_limit_reached":true,"chargeable_within_limit":0}}
Business failure produces OUTPUT with status failed and a safe error code, not a paid error row. Require both terminal run status and business output to indicate success. A valid row delivered before interruption may remain chargeable even if the final run status is not SUCCEEDED.
Pricing and spending limits
| Event | USD | Unit |
|---|---|---|
| App Rating Result — primary event | $0.003 | One valid snapshot written to the default Dataset |
| Actor Start | $0.00005 | One platform start event at the supported 128–256 MB allocation |
A million underlying app ratings still produce one result event, not a million. Both events are synthetic and charged automatically by Apify. This Actor never manually charges the same synthetic event. No separate PPE + platform-usage surcharge is enabled by EliDev; consult the price and account terms displayed for your run.
A start event may apply to invalid input, unavailable sources, aborts or restarts without a result. An ordinary successful run totals $0.00305, before platform discounts/taxes. We do not promise a single start fee across retries or resurrections. A private resurrection counted another startup under the same run ID; customer accounting of that case has not yet been independently verified.
The configured Actor default is maxTotalChargeUsd $0.02. REST requests that omit this option use the platform's effective run defaults; Console or integrations may supply a different ceiling, including Apify's $5 default. Any positive finite sufficient ceiling is accepted: a larger allowance does not create more results or increase the unit price. Explicit client limits are never raised by this Actor. A ceiling below $0.00305 cannot cover an ordinary start and one result; after restarts, the SDK also checks the actual remaining allowance. Zero, negative, invalid or unbounded effective budgets are refused; an absent effective budget is not silently replaced with unlimited spending. Startup may already have happened before a refusal, but no extraction or fake result follows. Apify enforces event limits; after one delivered result the workflow ends. The limit is per run, not your monthly bill or combined concurrent runs. Shutdown/bookkeeping may still consume creator resources after a limit.
API integration
Use your own Apify token in server-side Authorization headers. It authenticates to Apify only; no EliDev key is required. Never expose it in browsers, public repositories, INPUT or query strings. These examples use the official asynchronous run/status/storage API.
Python: asynchronous run lifecycle
Server-side example. Install httpx and load APIFY_TOKEN from a secret store. Tokens stay in Authorization headers, not query strings or INPUT.
import osimport timeimport httpxroot = "https://api.apify.com/v2"actor = "MqFAPgPTheRv2gMGA"with httpx.Client(headers={"Authorization": "Bearer " + os.environ["APIFY_TOKEN"]},timeout=15,follow_redirects=False,trust_env=False,) as client:response = client.post(f"{root}/actors/{actor}/runs",params={"memory": 256, "timeout": 120, "maxTotalChargeUsd": 0.02},json={"url": "https://play.google.com/store/apps/details?id=com.whatsapp", "language": "en"},)response.raise_for_status()run = response.json()["data"]deadline = time.monotonic() + 150while run["status"] in {"READY", "RUNNING", "ABORTING", "TIMING-OUT"}:if time.monotonic() >= deadline:raise TimeoutError("Polling deadline reached; inspect the existing run before retrying")time.sleep(3)response = client.get(f"{root}/actor-runs/{run['id']}")response.raise_for_status()run = response.json()["data"]if run["status"] != "SUCCEEDED":raise RuntimeError("Actor did not succeed: " + run["status"])response = client.get(f"{root}/key-value-stores/{run['defaultKeyValueStoreId']}/records/OUTPUT")response.raise_for_status()if response.json().get("status") != "completed":raise RuntimeError("Business result is not completed")response = client.get(f"{root}/datasets/{run['defaultDatasetId']}/items", params={"limit": 1})response.raise_for_status()rows = response.json()if len(rows) != 1 or rows[0].get("status") != "completed":raise RuntimeError("Missing valid result")print(rows)
Do not automatically retry an ambiguous POST: it may have created a billable second run. Keep the returned run ID. For HTTP 429, respect Retry-After when retrying safe status reads; authentication and validation errors require correcting the cause.
JavaScript / Node.js
Server only; never expose APIFY_TOKEN in browser code or NEXT_PUBLIC variables. This example starts a run and returns its ID for later polling:
const token = process.env.APIFY_TOKEN;if (!token) throw new Error('APIFY_TOKEN is required');const root = 'https://api.apify.com/v2';const response = await fetch(`${root}/actors/MqFAPgPTheRv2gMGA/runs?memory=256&timeout=120&maxTotalChargeUsd=0.02`,{ method: 'POST', redirect: 'error', signal: AbortSignal.timeout(15000),headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },body: JSON.stringify({url:'https://play.google.com/store/apps/details?id=com.whatsapp',language:'en'}) });if (!response.ok) throw new Error(`Apify HTTP ${response.status}`);const {data: run} = await response.json();console.log({runId:run.id, status:run.status});// GET /actor-runs/{run.id} every ~3 s, with a 150 s overall deadline.// After SUCCEEDED: GET /datasets/{defaultDatasetId}/items?limit=1// and GET /key-value-stores/{defaultKeyValueStoreId}/records/OUTPUT.
cURL
Linux shell, APIFY_TOKEN already supplied securely in the environment; input contains no token:
curl --silent --show-error --fail-with-body --max-time 20 \-X POST 'https://api.apify.com/v2/actors/MqFAPgPTheRv2gMGA/runs?memory=256&timeout=120&maxTotalChargeUsd=0.02' \-H "Authorization: Bearer ${APIFY_TOKEN:?APIFY_TOKEN required}" \-H 'Content-Type: application/json' \--data '{"url":"https://play.google.com/store/apps/details?id=com.whatsapp","language":"en"}'
Do not use verbose shell tracing, recorded terminals or logs that capture Authorization. On a shared host, use your platform’s secret-injection mechanism; command-line arguments may be inspectable. Keep the run ID and use the authenticated status/Dataset/OUTPUT endpoints above.
Errors, interruptions and recovery
- invalid_input / source_kind_mismatch / language_conflict: correct URL or fields; no result row.
- run_budget_required / unsafe_run_budget / event_budget_exhausted: set a supported positive ceiling; no fabricated result.
- provider_not_found / provider_data_unavailable / provider_rate_limited: inspect availability; do not evade source restrictions.
- robots_denied / unsafe_dns / redirect_rejected: the Actor stops without a proxy or access-control bypass.
- replay_conflict / replay_requires_review: stored state is inconsistent or incomplete; inspect the existing run before retrying.
A client timeout does not prove the remote run stopped. Poll the existing run with a finite deadline; respect Retry-After on safe GET retries. Never automatically repeat an ambiguous POST. Abort the existing run through Apify when necessary. Non-graceful aborts need not execute cleanup handlers.
Persistent RESULT_STATE binds input, run and verified user. Confirmed same-run delivery can restore OUTPUT without a second Dataset write; uncertain writes/charges require manual reconciliation. Cloud resurrection is best effort, not a promised recovery service. Fresh-context checks reject stale runs. A historical 20-second resurrection timed out; successful customer recovery is not claimed. A distinct run has distinct storage and is separately chargeable. Deleting a row or retrying is not a refund.
Security, privacy and retention
Public admission still requires an authenticated, matching Apify run: actor, user, run, status, time/resource limits and storage IDs are verified. No customer-declared userId proves identity. Run, Dataset and key-value store access are set to RESTRICTED. Publishing the Actor does not publish your results; authorized members/tokens and voluntary debug shares can still access them. Anonymous denial has been tested; independent customer isolation and paid billing remain a separate validation.
No raw HTML, Google cookie, reviewer identity or token is exported. Only the aggregate snapshot is in Dataset. Input, OUTPUT, state and operational metadata reside in Apify storage under its access/retention policy. Unnamed storage retention observed for the creator’s Free account is seven days; your plan, named stores and exports may differ. This is not permanent archiving. Retain exports/support material only as long as your purposes require.
Technical limits and source restrictions
One app/snapshot per run; 128–256 MB RAM, maximum 120-second container timeout, 45-second source workflow, at most four source requests and 8.6 MB decoded downloads. DNS/IPs and every redirect are revalidated. Robots rules and source refusals are respected. No login, CAPTCHA solver, residential proxy, browser or circumvention fallback.
Source changes, consent challenges, missing aggregates, rate limits and regions can prevent extraction. No uptime SLA, universal coverage, store ranking or country-specific accuracy is promised. This Actor grants no source-data licence: factual statistics, copyrighted content, database rights and contractual access restrictions are separate questions. Use it for lawful, permitted purposes, respecting applicable Google/Google Play terms. Do not use repeated runs as an unauthorized bulk database export.
FAQ
Does it collect written reviews? No: aggregate rating and count only.
Does rating_count mean written-review count? No. It follows the listing’s aggregate count and may be null.
Can I submit multiple apps, a country or a search URL? No. One app URL and a page language; no country-specific guarantee.
Why can a failed run cost something? Startup events can be counted without a result; a valid row delivered before interruption may also remain chargeable. Check actual pricing and counters.
Is every retry free? No. New runs are separate billable operations; startups after resurrection are not promised free. Persistent-state checks prevent duplicating confirmed same-run result delivery, but are not a financial transaction guarantee.
Is this an official Google service? No. EliDev is independent, not affiliated with, endorsed by or sponsored by Google. Google Play and app names belong to their respective owners. No source licence or partnership is claimed.
Support and permitted use
Open an issue in this Actor’s Issues tab with the run ID, safe error code and a minimal non-sensitive description. Do not post tokens, cookies, private INPUT, customer identities or billing details publicly. Use Apify’s private support flow when sensitive run sharing is necessary. No guaranteed response time is advertised.
Respect access controls, source limits, intellectual-property/database rights, applicable contracts and data protection. Do not collect unauthorized personal information or misrepresent affiliation. These conditions grant no Google licence. Financial incidents require run-specific reconciliation and, where applicable, Apify’s compensation procedure; no automatic refund or synthetic-event deletion is promised.