Google Play Apps Scraper avatar

Google Play Apps Scraper

Pricing

from $0.25 / 1,000 google play apps

Go to Apify Store
Google Play Apps Scraper

Google Play Apps Scraper

Google Play prints an install count as a band, 1,000,000+, and that is what lands on the row, next to title, developer, rating, review count, price, in-app purchases, content rating, version, last update, icon and screenshots. $0.25 per 1,000 apps.

Pricing

from $0.25 / 1,000 google play apps

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Give it search terms, a Play Store category, or Android package ids, and get the app listings back as flat rows: title, developer, star rating, rating and review counts, install band, price and currency, in-app purchase range, whether it carries ads, content rating, release date, last update, version, the full description, the icon and every screenshot.

No account, no cookies, no login, no browser.

  • Three ways in, all producing the same row shape: search terms, a store category, or a list of package ids and Play links.
  • Reads whichever country and language you ask for, so prices, install bands and availability are the ones a user there would see.
  • Every row carries the numeric field next to the display field. score as well as 4.5, minInstalls and realInstalls as well as 10,000,000+, price in units as well as $0.99.
  • Apps that don't exist, or aren't distributed in the country you asked for, come back as free diagnostic rows rather than as silence or a failed run.

Price

$0.25 per 1,000 apps, plus a $0.001 start fee per run (billed per gigabyte of run memory, so exactly that on the default 1 GB).

The $0.25 is the same on the free plan as on any paid one. Nothing is tiered, and there's no minimum spend or monthly fee underneath it.

AppsTotal cost
100$0.026
1,000$0.251
10,000$2.501
100,000$25.001

What is actually charged

  • One app-scraped event per app row written to the dataset. Nothing else is metered per row.
  • Never charged: the sample row, and any diagnostic row, so a blocked store, a dead package id and a search that matched nothing all cost you nothing. They carry "charged": false.
  • An app that appears under two of your search terms is delivered and charged once, not twice.
  • Package ids Play has no listing for produce an uncharged diagnostic row, never a charged one.
  • A run that comes back with nothing costs the start fee alone.
  • Every charge has a row behind it and every row has a charge, so the two always reconcile. The billed event is named app-scraped, not Apify's generic per-item event.

Input

{
"searchTerms": ["budget tracker", "habit tracker"],
"appIds": [
"com.whatsapp",
"https://play.google.com/store/apps/details?id=com.spotify.music"
],
"category": "PRODUCTIVITY",
"country": "us",
"language": "en",
"maxItems": 50
}
FieldWhat it does
searchTermsWords or phrases to search the Play Store for, the way the store search box works. Up to 20 per run. Each term takes its share of the row budget.
appIdsPackage ids (com.whatsapp) or full Play links. Both forms accepted in the same list, and these are fetched before anything else because they're exactly what you asked for.
categoryA Play category id such as PRODUCTIVITY, COMMUNICATION, GAME_PUZZLE, or the roll-ups APPLICATION and GAME. Returns the apps Play features on that category page: top free, top grossing, top paid and trending shelves, in Play's own order.
countryTwo-letter country code, default us. Play is a store per country: price, currency, install band, content rating and even whether the app exists depend on this.
languageTwo-letter language code, default en. Controls the title, summary, description, changelog and content-rating text.
maxItemsTotal rows across everything you asked for. Package ids are taken first, then the remaining budget splits evenly between the search terms and the category, so two terms and 50 rows gives 25 each. Default 20, hard ceiling 2,000.
proxyUrlsLeave empty. Fill it in only if you want the traffic to leave through proxy servers you already pay for.

Start it with nothing filled in and it writes one labelled sample row, uncharged, so you can look at the shape first.

Output

One row per app. Real row from a real run, long text trimmed where noted:

{
"ok": true,
"charged": true,
"recordType": "app",
"query": "budget tracker",
"searchType": "search",
"appId": "com.raha.app.mymoney.free",
"url": "https://play.google.com/store/apps/details?id=com.raha.app.mymoney.free&hl=en&gl=us",
"title": "MyMoney—Track Expense & Budget",
"summary": "Daily Expense Tracker, Personal Finance Manager & Budgeting App - simple & easy.",
"description": "MyMoney is a personal money manager & budget app that helps you manage money use. … (full listing text)",
"developer": "Ananta Raha",
"developerId": "Ananta Raha",
"developerLegalName": "Ananta Raha",
"developerEmail": "contact.ananta.raha@gmail.com",
"developerWebsite": null,
"developerAddress": "Solemanpur (Pal Para), Kotchandpur\nJhenaidah 7330\nBangladesh",
"privacyPolicy": "https://anantaraha.github.io/mymoney/privacy.html",
"genre": "Finance",
"genreId": "FINANCE",
"score": 4.747449,
"scoreText": "4.7",
"ratings": 66251,
"reviews": 1841,
"histogram": { "1": 674, "2": 506, "3": 1856, "4": 8774, "5": 54404 },
"installs": "1,000,000+",
"minInstalls": 1000000,
"realInstalls": 2586846,
"price": 0,
"currency": "USD",
"priceText": "Free",
"free": true,
"offersIAP": false,
"inAppPurchaseRange": null,
"containsAds": false,
"contentRating": "Everyone",
"released": "Nov 16, 2019",
"releasedAt": "2019-11-17T07:59:34.000Z",
"updated": "2026-07-31T19:15:16.000Z",
"updatedText": "Jul 31, 2026",
"recentChanges": "This version of MyMoney introduces record duplication to quickly create similar entries…",
"version": "6.6-free",
"androidVersion": "6.0",
"icon": "https://play-lh.googleusercontent.com/uIq-712cZvKbZo7uQoefCo000U2Y-qwDDzRf4PkvXEAcSm5FkJXYZlfILEiwLO7xNEGLMcnBvbGSS0ANUeIh0aE",
"headerImage": "https://play-lh.googleusercontent.com/u2jvRHPVcaH9hQmGv4gkBOO7S6CxZzlN42bgokQV6mSQufIuLZDSwqkyxnz172GkGuwZ_8xsnNHKBNM52v6Gpw",
"screenshots": ["https://play-lh.googleusercontent.com/…", "…"],
"topChartRank": null,
"available": true,
"country": "us",
"language": "en",
"scrapedAt": "2026-08-20T19:53:24.290Z"
}

Rows also carry descriptionHtml, developerUrl, androidMinSdk, adsLabel and video where Play publishes them.

Field notes

  • query — the search term, category id or package id that produced this row, so a multi-term run can be split back apart afterwards. searchType says which of the three it was.
  • appId — the Android package id. Stable, unique, the right primary key when you re-run.
  • score — the star rating as a float (4.747449). scoreText is the rounded string Play prints.
  • ratings — how many people left a star rating. reviews is the smaller number who also wrote text. histogram breaks the ratings down one star at a time.
  • installs — Play only publishes a band (1,000,000+). minInstalls is that band as a number and realInstalls is the finer figure Play exposes behind it.
  • price — in whole currency units, so 6.99 not 6990000. priceText is what the store button says, and free is simply price === 0.
  • inAppPurchaseRange — the "$0.99 - $54.99 per item" line, present only when the app sells something inside itself. offersIAP is the boolean form.
  • updated — the last update as an ISO 8601 timestamp in UTC. updatedText is Play's own localised rendering of the same moment, so the two can differ by a day either side of midnight.
  • version — null for apps Google delivers per device rather than as one build. The store shows "Varies with device" for those, so there's no version string to report. Same for androidVersion.
  • screenshots — every screenshot on the listing, in the order Play shows them, as full-size image URLs. icon and headerImage are separate fields.
  • available — whether Play will actually let somebody in the country you asked for install it. A listing that exists but isn't distributed there comes back with its metadata and
    available: false
    .
  • topChartRank — set only while the app is sitting in a Play top chart, as "#1 in top free communication".

How it works

It talks to the Play Store the way the store's own web front end does: one request per app for the listing data, and one per search term or category to find which apps to look up. No page rendering, no headless browser, no login, no cookies.

Because it asks for data rather than for a page, a listing costs about thirteen kilobytes instead of the better part of a megabyte. That's most of the reason it can hold this rate at volume.

Requests leave through a large pool of rotating datacenter addresses, so a per-address rate limit is answered by moving rather than by waiting.

Country and language are passed through on every request, so one run can only describe one storefront. Run it twice for two countries.

Diagnostic rows

Nothing fails silently, and a run that hits trouble still finishes as succeeded. The trouble comes back as a row carrying "_diagnostic": true, "charged": false and an errorCode: NOT_FOUND when Play has no listing for a package id in that country, NO_RESULTS when a search term or category matched nothing, BLOCKED when the store refused the request, NETWORK when it couldn't be reached, TIME_BUDGET when the run ran out of time, BAD_INPUT when a category id wasn't one Play recognises. Each carries a plain-English error and the query and appId it belongs to.

The free sample row is tagged "_sample": true and shows up only when the run was given no search terms, package ids or category. Filter on charged == true for the data alone, and nothing is metered that isn't sitting in the dataset where you can count it.

Country and language

Play isn't one store, it's a store per country, and the difference isn't cosmetic. An app can be free in one country and paid in another, carry a different content rating, sit in a different chart, or simply not be distributed there at all.

country picks the storefront (us, gb, de, in, br, …) and decides price, currency, install band, content rating and availability. language picks the language of the text (title, summary, description, changelog) and doesn't change any of the numbers.

One run describes one storefront. If you need five countries, run it five times with the same appIds and compare on the country column.

Limitations

  • A search term returns roughly the first 20 to 30 apps Play ranks for it, which is what the store's own search results page shows. For deeper coverage, use more specific terms or add a category.
  • A category returns the apps Play features on that category page (top free, top grossing, top paid, trending), usually 40 to 80 apps. Not the entire category, which Play doesn't publish.
  • version and androidVersion are null for apps Google delivers per device rather than as a single build. The store shows "Varies with device"; there's no version string behind it.
  • Ratings, review counts and install bands are a snapshot at read time and keep moving. Two runs minutes apart will differ in the last digits.
  • Install counts are bands, not exact figures. That's all Play publishes. realInstalls is the finest number available and is still rounded by Google.
  • Prices are the storefront price before tax, in that storefront's currency. Regional promotions and personalised offers aren't visible to a logged-out reader.
  • Editorial fields Play only shows to some readers (pre-registration state, early-access badges, A/B-tested listings) aren't returned.
  • App reviews aren't included. This reads the listing. Review text is a different job.
  • Hard ceilings: 2,000 rows per run, 20 search terms, 500 package ids.

Questions

What do I put in appIds, the package id or the link?

Either, and you can mix them in the same list. com.whatsapp and https://play.google.com/store/apps/details?id=com.whatsapp&hl=de are both understood; the id is read out of the link.

What happens if a package id doesn't exist?

One uncharged diagnostic row for it with errorCode: "NOT_FOUND", and the run carries on with the rest. Same when the app exists but isn't distributed in the country you asked for.

Why is version empty for some apps?

Because Google doesn't publish one for them. Large apps are often delivered as per-device builds and the store shows "Varies with device" instead of a version. Returning null is the honest answer.

Can I get reviews too?

Not from this Actor. It reads the app listing: metadata, ratings summary, media, developer details. Review text is a separate job with a very different row shape.

Do I need a proxy?

No. Egress is included in the price above and there's nothing to set up. proxyUrls is there for people who already run their own servers and want the traffic to go out through those.

Will the run fail if something goes wrong?

No. A blocked, empty or broken target produces an uncharged diagnostic row explaining what happened and the run finishes as succeeded. Failing it would still bill the start fee, so you'd be paying to hear that a package id was wrong.

Can I run this on a schedule?

Yes. Nothing holds state between runs. Key on appId and diff on version, updated, score and ratings to see what moved since last time.