Google Play Store API Search Android apps, fetch full app details, and pull user reviews from Google Play Store as structured JSON
The Google Play Store API returns structured data from the Play Store across three endpoints:
Search : find apps by query, category, or top-chart and get titles, ratings, prices, and package identifiers.
App Details : fetch the full details page for a single app (description, version, downloads, screenshots, release notes, developer info).
Reviews : pull paginated user reviews with ratings, dates, app version, and developer responses.
Three endpoints, one schema family : search, product, and reviews all return structured JSON with consistent field naming.
Search by query, category, or chart : keyword search, Play Store category browsing (GAME_PUZZLE, MEDICAL, …), or top-chart listings (topselling_free, topselling_paid, topgrossing).
Device filters : restrict search results to phone, tablet, tv, chromebook, watch, or car.
Family / age filters : when browsing the FAMILY category, filter by age bucket.
Localization : per-request hl (language) and gl (country) for region-specific results.
Paginated reviews : 20 reviews per page, unlimited depth via next_page_token.
Developer responses : review payloads include the developer's reply when present.
Returns a list of apps matching your query, category, or chart.
GET https://api.scrape.do/plugin/google/play-store
curl python node go ruby java csharp php
curl --location --request GET 'https://api.scrape.do/plugin/google/play-store?token=<SDO-token>&q=weather' import requests
import json
token = "<SDO-token>"
url = f "https://api.scrape.do/plugin/google/play-store?token= { token } &q=weather"
response = requests.request( "GET" , url)
print (json.dumps(response.json(), indent = 2 )) const axios = require ( 'axios' );
const token = "<SDO-token>" ;
const url = `https://api.scrape.do/plugin/google/play-store?token=${ token }&q=weather` ;
axios. get (url)
. then ( response => {
console. log ( JSON . stringify (response.data, null , 2 ));
})
. catch ( error => {
console. error (error);
}); package main
import (
" fmt "
" io/ioutil "
" net/http "
)
func main () {
token := "<SDO-token>"
url := fmt. Sprintf (
"https://api.scrape.do/plugin/google/play-store?token= %s &q=weather" ,
token,
)
resp, err := http. Get (url)
if err != nil {
panic (err)
}
defer resp.Body. Close ()
body, _ := ioutil. ReadAll (resp.Body)
fmt. Println ( string (body))
} require 'net/http'
require 'json'
token = "<SDO-token>"
url = URI ( "https://api.scrape.do/plugin/google/play-store?token= #{token} &q=weather" )
response = Net :: HTTP . get (url)
puts JSON . pretty_generate ( JSON . parse (response)) import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class PlayStoreSearch {
public static void main ( String [] args ) throws Exception {
String token = "<SDO-token>" ;
String url = String. format (
"https://api.scrape.do/plugin/google/play-store?token=%s&q=weather" ,
token
);
HttpURLConnection conn = (HttpURLConnection) new URL (url). openConnection ();
conn. setRequestMethod ( "GET" );
BufferedReader reader = new BufferedReader (
new InputStreamReader (conn. getInputStream ())
);
String line;
StringBuilder response = new StringBuilder ();
while ((line = reader. readLine ()) != null ) {
response. append (line);
}
reader. close ();
System.out. println (response. toString ());
}
} using System ;
using System . Net . Http ;
using System . Threading . Tasks ;
class Program
{
static async Task Main ()
{
string token = "<SDO-token>" ;
string url = $"https://api.scrape.do/plugin/google/play-store?token= { token } &q=weather" ;
using HttpClient client = new HttpClient ();
string response = await client. GetStringAsync (url);
Console. WriteLine (response);
}
} <? php
$token = "<SDO-token>" ;
$url = "https://api.scrape.do/plugin/google/play-store?token={ $token }&q=weather" ;
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_URL , $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER , true );
$response = curl_exec ($ch);
curl_close ($ch);
echo json_encode ( json_decode ($response), JSON_PRETTY_PRINT );
?>
curl "https://api.scrape.do/plugin/google/play-store?token= $TOKEN &q=weather"
You must provide at least one of q, apps_category, or chart.
Parameter Type Description tokenstring Your Scrape.do API authentication token
Parameter Type Description qstring Search query (e.g., weather, fitness tracker) apps_categorystring Category identifier (e.g., ART_AND_DESIGN, MEDICAL, GAME_PUZZLE) chartstring Top charts: topselling_free, topselling_paid, topgrossing
Parameter Type Default Description hlstring enLanguage code (e.g., en, es, fr) glstring usCountry code (e.g., us, gb, de)
Parameter Type Default Description numinteger 20Number of results per page (1–50) next_page_tokenstring From the previous response's pagination.next_page_token. Pass back unchanged
Parameter Type Description store_devicestring Device type: phone, tablet, tv, chromebook, watch, car agestring Age filter (only valid with apps_category=FAMILY): AGE_RANGE1 (up to 5), AGE_RANGE2 (6–8), AGE_RANGE3 (9–12)
# Search apps
curl "https://api.scrape.do/plugin/google/play-store?token= $TOKEN &q=coffee"
# Search with localization
curl "https://api.scrape.do/plugin/google/play-store?token= $TOKEN &q=fitness&gl=de&hl=de"
# Browse by category
curl "https://api.scrape.do/plugin/google/play-store?token= $TOKEN &apps_category=GAME_PUZZLE"
# Top free charts
curl "https://api.scrape.do/plugin/google/play-store?token= $TOKEN &chart=topselling_free"
# Paginate with 10 results per page
curl "https://api.scrape.do/plugin/google/play-store?token= $TOKEN &q=coffee&num=10"
{
"search_parameters" : {
"q" : "coffee" ,
"hl" : "en" ,
"gl" : "us" ,
"store" : "apps"
},
"organic_results" : [
{
"items" : [
{
"title" : "Good Coffee, Great Coffee" ,
"link" : "https://play.google.com/store/apps/details?id=com.tapblaze.coffeebusiness" ,
"product_id" : "com.tapblaze.coffeebusiness" ,
"rating" : 4.4 ,
"author" : "TapBlaze" ,
"video" : "https://www.youtube.com/embed/RFUNyVrGCzE?..." ,
"thumbnail" : "https://play-lh.googleusercontent.com/..."
},
{
"title" : "Coffee Roaster" ,
"link" : "https://play.google.com/store/apps/details?id=de.brettspielwelt.coffee_roaster" ,
"product_id" : "de.brettspielwelt.coffee_roaster" ,
"rating" : 3.8 ,
"author" : "Brettspielwelt GmbH" ,
"price" : "$3.99" ,
"extracted_price" : 3.99 ,
"thumbnail" : "https://play-lh.googleusercontent.com/..." ,
"feature_image" : "https://play-lh.googleusercontent.com/..."
}
]
}
],
"pagination" : {
"next_page_token" : "eyJvIjoyMH0"
}
}
Field Type Description titlestring App name linkstring Google Play Store URL product_idstring Package identifier (e.g., com.example.app) ratingfloat Rating 0–5. Omitted if unrated authorstring Developer name pricestring Price string (e.g., $3.99). Omitted for free apps extracted_pricefloat Numeric price. Omitted for free apps videostring YouTube embed URL. Present when the app has a promo video thumbnailstring App icon URL feature_imagestring Feature banner or screenshot URL. Present when available
Field Type Description next_page_tokenstring Pass this value as next_page_token to get the next page. Absent when no more results
Returns the full details page for one app: title, description, developer, version, downloads, screenshots, release notes, and more.
GET https://api.scrape.do/plugin/google/play-store/product
curl python node go ruby java csharp php
curl --location --request GET 'https://api.scrape.do/plugin/google/play-store/product?token=<SDO-token>&product_id=com.discord' import requests
import json
token = "<SDO-token>"
url = f "https://api.scrape.do/plugin/google/play-store/product?token= { token } &product_id=com.discord"
response = requests.request( "GET" , url)
print (json.dumps(response.json(), indent = 2 )) const axios = require ( 'axios' );
const token = "<SDO-token>" ;
const url = `https://api.scrape.do/plugin/google/play-store/product?token=${ token }&product_id=com.discord` ;
axios. get (url)
. then ( response => {
console. log ( JSON . stringify (response.data, null , 2 ));
})
. catch ( error => {
console. error (error);
}); package main
import (
" fmt "
" io/ioutil "
" net/http "
)
func main () {
token := "<SDO-token>"
url := fmt. Sprintf (
"https://api.scrape.do/plugin/google/play-store/product?token= %s &product_id=com.discord" ,
token,
)
resp, err := http. Get (url)
if err != nil {
panic (err)
}
defer resp.Body. Close ()
body, _ := ioutil. ReadAll (resp.Body)
fmt. Println ( string (body))
} require 'net/http'
require 'json'
token = "<SDO-token>"
url = URI ( "https://api.scrape.do/plugin/google/play-store/product?token= #{token} &product_id=com.discord" )
response = Net :: HTTP . get (url)
puts JSON . pretty_generate ( JSON . parse (response)) import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class PlayStoreProduct {
public static void main ( String [] args ) throws Exception {
String token = "<SDO-token>" ;
String url = String. format (
"https://api.scrape.do/plugin/google/play-store/product?token=%s&product_id=com.discord" ,
token
);
HttpURLConnection conn = (HttpURLConnection) new URL (url). openConnection ();
conn. setRequestMethod ( "GET" );
BufferedReader reader = new BufferedReader (
new InputStreamReader (conn. getInputStream ())
);
String line;
StringBuilder response = new StringBuilder ();
while ((line = reader. readLine ()) != null ) {
response. append (line);
}
reader. close ();
System.out. println (response. toString ());
}
} using System ;
using System . Net . Http ;
using System . Threading . Tasks ;
class Program
{
static async Task Main ()
{
string token = "<SDO-token>" ;
string url = $"https://api.scrape.do/plugin/google/play-store/product?token= { token } &product_id=com.discord" ;
using HttpClient client = new HttpClient ();
string response = await client. GetStringAsync (url);
Console. WriteLine (response);
}
} <? php
$token = "<SDO-token>" ;
$url = "https://api.scrape.do/plugin/google/play-store/product?token={ $token }&product_id=com.discord" ;
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_URL , $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER , true );
$response = curl_exec ($ch);
curl_close ($ch);
echo json_encode ( json_decode ($response), JSON_PRETTY_PRINT );
?>
curl "https://api.scrape.do/plugin/google/play-store/product?token= $TOKEN &product_id=com.discord"
Parameter Type Description tokenstring Your Scrape.do API authentication token product_idstring App package identifier (e.g., com.discord, com.whatsapp)
Parameter Type Default Description hlstring enLanguage code glstring usCountry code
# Default (US / English)
curl "https://api.scrape.do/plugin/google/play-store/product?token= $TOKEN &product_id=com.discord"
# Localized to Germany
curl "https://api.scrape.do/plugin/google/play-store/product?token= $TOKEN &product_id=com.duolingo&gl=de&hl=de"
{
"search_parameters" : {
"product_id" : "com.discord" ,
"hl" : "en" ,
"gl" : "us"
},
"title" : "Discord - Talk, Play, Hang Out" ,
"product_id" : "com.discord" ,
"description" : "Discord is designed for gaming and great for just chilling with friends ..." ,
"category" : "Communication" ,
"category_id" : "COMMUNICATION" ,
"content_rating" : "Teen" ,
"rating" : 4.28 ,
"rating_count" : 6769967 ,
"free" : true ,
"downloads" : "500,000,000+" ,
"in_app_purchases" : "$1.99 - $274.94 per item" ,
"version" : "327.12 - Stable" ,
"min_android" : "7.0" ,
"updated" : "May 8, 2026" ,
"release_notes" : "We've been hard at work making Discord better for you. ..." ,
"icon" : "https://play-lh.googleusercontent.com/..." ,
"header_image" : "https://play-lh.googleusercontent.com/..." ,
"screenshots" : [
"https://play-lh.googleusercontent.com/..." ,
"https://play-lh.googleusercontent.com/..."
],
"developer" : {
"name" : "Discord Inc." ,
"url" : "https://discord.com/" ,
"email" : "[email protected] "
}
}
Field Type Description titlestring App display name product_idstring Package identifier descriptionstring Long-form description categorystring Display category (e.g., "Communication") category_idstring Category identifier (e.g., "COMMUNICATION") content_ratingstring "Everyone", "Teen", "Mature 17+", etc.ratingfloat Average rating, 1–5 rating_countint Total number of ratings pricestring Price + currency. Omitted on free apps freebool true if the app is freedownloadsstring Download bucket (e.g., "500,000,000+") in_app_purchasesstring Price range for IAPs. Omitted if none versionstring Current published version. Absent when the developer ships device-targeted bundles ("Varies with device" in the Play Store UI) min_androidstring Minimum Android version (e.g., "7.0") updatedstring Last-updated date (e.g., "May 8, 2026") release_notesstring What's new text. Omitted if not published iconstring App icon URL header_imagestring Feature graphic / header image URL screenshotsstring[] Screenshot URLs
Field Type Description namestring Developer / publisher name urlstring Developer website emailstring Developer contact email addressstring Physical address. Omitted if not published
Returns user reviews for a specific app, with pagination support.
GET https://api.scrape.do/plugin/google/play-store/reviews
curl python node go ruby java csharp php
curl --location --request GET 'https://api.scrape.do/plugin/google/play-store/reviews?token=<SDO-token>&product_id=com.tapblaze.coffeebusiness' import requests
import json
token = "<SDO-token>"
url = f "https://api.scrape.do/plugin/google/play-store/reviews?token= { token } &product_id=com.tapblaze.coffeebusiness"
response = requests.request( "GET" , url)
print (json.dumps(response.json(), indent = 2 )) const axios = require ( 'axios' );
const token = "<SDO-token>" ;
const url = `https://api.scrape.do/plugin/google/play-store/reviews?token=${ token }&product_id=com.tapblaze.coffeebusiness` ;
axios. get (url)
. then ( response => {
console. log ( JSON . stringify (response.data, null , 2 ));
})
. catch ( error => {
console. error (error);
}); package main
import (
" fmt "
" io/ioutil "
" net/http "
)
func main () {
token := "<SDO-token>"
url := fmt. Sprintf (
"https://api.scrape.do/plugin/google/play-store/reviews?token= %s &product_id=com.tapblaze.coffeebusiness" ,
token,
)
resp, err := http. Get (url)
if err != nil {
panic (err)
}
defer resp.Body. Close ()
body, _ := ioutil. ReadAll (resp.Body)
fmt. Println ( string (body))
} require 'net/http'
require 'json'
token = "<SDO-token>"
url = URI ( "https://api.scrape.do/plugin/google/play-store/reviews?token= #{token} &product_id=com.tapblaze.coffeebusiness" )
response = Net :: HTTP . get (url)
puts JSON . pretty_generate ( JSON . parse (response)) import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class PlayStoreReviews {
public static void main ( String [] args ) throws Exception {
String token = "<SDO-token>" ;
String url = String. format (
"https://api.scrape.do/plugin/google/play-store/reviews?token=%s&product_id=com.tapblaze.coffeebusiness" ,
token
);
HttpURLConnection conn = (HttpURLConnection) new URL (url). openConnection ();
conn. setRequestMethod ( "GET" );
BufferedReader reader = new BufferedReader (
new InputStreamReader (conn. getInputStream ())
);
String line;
StringBuilder response = new StringBuilder ();
while ((line = reader. readLine ()) != null ) {
response. append (line);
}
reader. close ();
System.out. println (response. toString ());
}
} using System ;
using System . Net . Http ;
using System . Threading . Tasks ;
class Program
{
static async Task Main ()
{
string token = "<SDO-token>" ;
string url = $"https://api.scrape.do/plugin/google/play-store/reviews?token= { token } &product_id=com.tapblaze.coffeebusiness" ;
using HttpClient client = new HttpClient ();
string response = await client. GetStringAsync (url);
Console. WriteLine (response);
}
} <? php
$token = "<SDO-token>" ;
$url = "https://api.scrape.do/plugin/google/play-store/reviews?token={ $token }&product_id=com.tapblaze.coffeebusiness" ;
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_URL , $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER , true );
$response = curl_exec ($ch);
curl_close ($ch);
echo json_encode ( json_decode ($response), JSON_PRETTY_PRINT );
?>
curl "https://api.scrape.do/plugin/google/play-store/reviews?token= $TOKEN &product_id=com.tapblaze.coffeebusiness"
Parameter Type Description tokenstring Your Scrape.do API authentication token product_idstring App package identifier (e.g., com.tapblaze.coffeebusiness)
Parameter Type Default Description hlstring enLanguage code glstring usCountry code
Parameter Type Default Description sort_byinteger 1Sort order. Currently only 1 (most relevant) is supported next_page_tokenstring From the previous response's pagination.next_page_token. Pass back unchanged
# First page of reviews
curl "https://api.scrape.do/plugin/google/play-store/reviews?token= $TOKEN &product_id=com.tapblaze.coffeebusiness"
# Next page using the returned token
curl "https://api.scrape.do/plugin/google/play-store/reviews?token= $TOKEN &product_id=com.tapblaze.coffeebusiness&next_page_token=CrkBIrAB..."
{
"search_parameters" : {
"product_id" : "com.tapblaze.coffeebusiness" ,
"hl" : "en" ,
"gl" : "us" ,
"store" : "apps" ,
"sort_by" : 1 ,
"num" : 20
},
"reviews" : [
{
"id" : "707d91c4-0510-455d-9288-71eddf9784be" ,
"title" : "Rebecca Saurer" ,
"avatar" : "https://play-lh.googleusercontent.com/a-/ALV-..." ,
"rating" : 4 ,
"snippet" : "generally speaking, this games great! ..." ,
"likes" : 52 ,
"date" : "February 16, 2026" ,
"iso_date" : "2026-02-16T02:26:14Z" ,
"app_version" : "1.18.0" ,
"response" : {
"title" : "TapBlaze" ,
"snippet" : "Hello! Thank you so much for your feedback ..." ,
"date" : "February 16, 2026" ,
"iso_date" : "2026-02-16T23:30:38Z"
}
}
],
"pagination" : {
"next_page_token" : "CrkBIrABAYw1..."
}
}
Field Type Description idstring Unique review identifier titlestring Reviewer name avatarstring Reviewer avatar URL ratingfloat Rating 1–5 snippetstring Review text likesint Number of people who found this review helpful datestring Human-readable date (e.g., "February 16, 2026") iso_datestring ISO 8601 date app_versionstring App version installed when the review was written. Absent on older reviews responseobject Developer response. Absent if the developer hasn't replied
Field Type Description titlestring Developer name snippetstring Response text datestring Human-readable date iso_datestring ISO 8601 date
Field Type Description next_page_tokenstring Pass this value as next_page_token to get the next page. Absent when no more results
Search returns up to ~30 apps total. With the default num=20, you get two pages.
Reviews return 20 per page with unlimited pagination depth.
The rating field is omitted for apps and reviews that have no rating.
The response field on reviews is only present when the developer has replied.
On the product endpoint, version is absent for apps that publish device-targeted bundles (these show as "Varies with device" in the Play Store UI). For per-review installed versions, use app_version on each review.
Known limitation: apps_category=MEDICAL currently returns 500 failed to parse play store results. Other categories (GAME_PUZZLE, FAMILY, COMMUNICATION, etc.) work normally. Browsing the medical app catalog via q=medical returns matching apps.