ApkJSON documentation

REST API with Google Play data: 4 million apps, developers, new and removed apps, title keywords. Format: JSON, UTF-8 encoding, CORS enabled.

Quick start

Base URL: https://apiapk.cc/api/v1. Sign up, create an API key in your account and send your first request:

Machine-readable API description: OpenAPI 3.1 · Postman collection — import it into Postman, Insomnia or a client generator (openapi-generator) to get a ready SDK for your language.

curl -H "X-API-Key: YOUR_KEY" "https://apiapk.cc/api/v1/app?id=com.whatsapp"

The data covers over 4 million Google Play apps from the US storefront in English (from another country if an app is not available in the US), refreshed nightly. Apps that disappear from the store stay in the database with their last data.

Authentication

Every request except /v1/health must include the API key in a header:

X-API-Key: ak_live_…

Also accepted: Authorization: Bearer …. Passing the key in URL parameters is not allowed: it would end up in logs and browser history.

Keep the key on your server. If you embed it in page JavaScript, any visitor can copy it. Route frontend requests through your backend.

Credits & limits

Each call costs 0–3 credits depending on the endpoint, regardless of the number of rows in the response (up to 100); the batch apps call costs 1 credit per app. Plan credits for the current month are used first, then the prepaid balance. If a request fails on our side, the credits are returned. Plans & packs

HeaderMeaning
X-Credits-Costcredits this request cost
X-Credits-Remainingcredits left (plan + balance)
X-CacheHIT — served from cache (faster), MISS — fresh query to the index
X-RateLimit-Limit / -Remainingthe key's per-minute limit and what's left
X-Planfree | pro | scale | business

Your remaining credits are also in the _credits field of every response and in /v1/account (free).

Response format and errors

Every response has an ok field. Lists contain results, total, page, per, pages. Error: ok = false, error is the explanation, code is a machine-readable code. Dates are ISO 8601 in UTC.

{ "ok": true, "app": { "id": "com.whatsapp", "title": "WhatsApp", "installs": { "label": "10,000,000,000+", "min": 10000000000, "real": 12445120489 }, … },
  "_credits": { "cost": 1, "plan_remaining": 1999, "balance": 0, "available": 1999, "cached": false } }

{ "ok": false, "code": "insufficient_credits", "error": "Not enough credits: this call costs 2, you have 1. …" }
HTTPcodeWhen
400invalid_param, invalid_requestinvalid or missing parameter
401missing_api_key, invalid_api_keyno key, or the key is revoked
402insufficient_creditsnot enough credits — top up or upgrade your plan
403account_blocked, plan_requiredthe account is blocked, or the endpoint requires a higher plan
404not_foundthe app or developer isn't in the database, or the endpoint is unknown
429rate_limitedper-minute request limit exceeded
503service_unavailablea temporary database problem — retry later; no credits are charged

Endpoints

All endpoints are GET /api/v1/{name}. Pagination: page (from 1) and per (1–100), up to the 10,000th result. Sorting: sort + order=asc|desc.

GET/api/v1/accountfree

Your plan, plan credits and balance, the credit reset date and the per-minute limit.

Apps
GET/api/v1/app 1 cr.

The full app record: title, description, what's new, installs (threshold and exact number), rating, number of ratings and reviews, star distribution, price, in-app purchases, ads, category, content rating, version, minimum Android, release and update dates, icon, screenshots, video, developer and their website. For removed apps: the last saved data and the removal date.

id *app package name
GET · POST/api/v1/apps 1 credit per app

Up to 100 apps in one call: GET ?ids=a,b,c or POST with the list in the body (one per line, or JSON {"ids": […]}). 1 credit per app; ids we don't have come back in not_found.

ids *package names, comma-separated, up to 100
GET/api/v1/suggest free

Suggestions by the start of a title: the 10 most popular matches. Free.

q *start of the title, 2+ characters
Developers
GET/api/v1/developer 2 cr.

A developer and all their apps: counts (in the store and removed), total installs, average rating, first release, categories, website. On the Business plan: email, phone, address and legal name.

iddeveloper ID (from an app: developer.id)
nameor the exact developer name
statusall (default), live or removed
sortrelevance | installs | real_installs | score | ratings | reviews | released | updated | price
pagepage, from 1
perrows per page, 1–100 (default 20)
Store changes
GET/api/v1/new 2 cr.

New apps by first release date, newest first.

sincefrom this date, YYYY-MM-DD (default: 7 days ago)
untilup to this date, inclusive
categorycategory ID, e.g. GAME_PUZZLE (see /v1/categories)
min_installsminimum installs (Google Play thresholds: 1000, 10000…)
langtitle language, ISO code: en, de, pt…
sortrelevance | installs | real_installs | score | ratings | reviews | released | updated | price
pagepage, from 1
perrows per page, 1–100 (default 20)
GET/api/v1/removed 2 cr.

Apps that disappeared from Google Play (missing in all 19 countries we check), by removal date. The app record keeps its last data.

sincefrom this date, YYYY-MM-DD (default: 7 days ago)
untilup to this date, inclusive
categorycategory ID, e.g. GAME_PUZZLE (see /v1/categories)
min_installsminimum installs (Google Play thresholds: 1000, 10000…)
sortremoved_at | installs | score
pagepage, from 1
perrows per page, 1–100 (default 20)
Market
GET/api/v1/keywords 2 cr.

Words and phrases from app titles for each language: how many apps and developers use them, how many of those are strong (100K+ installs), total installs, the leader's share and an opportunity score.

langlanguage, default en
qword or phrase
phrasetrue — two-word phrases only, false — single words only
min_appsminimum apps
max_appsmaximum apps
sortopportunity | apps | installs | strong | devs | max_installs
orderdesc | asc
pagepage, from 1
perrows per page, 1–100 (default 20)
GET/api/v1/categories free

All categories with app counts and total installs. Free.

statuslive (in the store, default), removed or all
GET/api/v1/free_domains 3 cr.Pro+

Apps whose developer website domain is available to register, with the app's popularity. Pro plan and higher.

categorycategory ID, e.g. GAME_PUZZLE (see /v1/categories)
min_installsminimum installs (Google Play thresholds: 1000, 10000…)
statuslive (in the store, default), removed or all
tlddomain zone, e.g. com
sortrelevance | installs | real_installs | score | ratings | reviews | released | updated | price
pagepage, from 1
perrows per page, 1–100 (default 20)
GET/api/v1/charts 2 cr.

A Google Play top chart for one country and category: up to 200 positions, rank change since the previous snapshot (change: how many places it moved up, "new" for new entries), icon and installs.

country *country, ISO code: US, DE, BR…
category *category, e.g. GAME_PUZZLE
collectionfree | paid | grossing
pagepage, from 1
perrows per page, 1–100 (default 20)
GET/api/v1/rankings 1 cr.

Every chart the app is in, in the latest snapshot: country, category, collection, position; the number of charts and countries, and the best position.

id *app package name
countryone country only
collectionfree | paid | grossing
GET/api/v1/availability 1 cr.

Countries where the app is available on Google Play (from hreflang in the store sitemap). With 190+ countries, worldwide = true is returned without a list.

id *app package name
GET/api/v1/markets 1 cr.

Market competition based on free charts: the entry threshold for the top 100 and top 200 (installs of the app at that position), the share of new (last 12 months) and local (≤3 countries) apps in the top, and the size of the local market. No parameters: all countries; country: the categories of one country; category: one category across all countries.

countrycountry, ISO code
categorycategory ID, e.g. GAME_PUZZLE (see /v1/categories)
sortentry100 | entry200 | new_share | local_share | local_apps | local_installs | local_new
orderdesc | asc
pagepage, from 1
perrows per page, 1–100 (default 20)
GET/api/v1/stats free

Database size: apps in the store and removed, developers, new and removed in the last 7 days, time of the last update. Free.

* — required parameter

Code examples

# curl — one app
curl -H "X-API-Key: $KEY" "https://apiapk.cc/api/v1/app?id=org.telegram.messenger"

# curl — puzzle games with 10M+ installs, best rated first
curl -H "X-API-Key: $KEY" "https://apiapk.cc/api/v1/search?category=GAME_PUZZLE&min_installs=10000000&sort=score"

# curl — up to 100 apps in one call (POST, one package per line)
curl -H "X-API-Key: $KEY" --data-binary $'com.whatsapp\norg.telegram.messenger' "https://apiapk.cc/api/v1/apps"
# Python — apps removed from Google Play this week
import os, requests
r = requests.get("https://apiapk.cc/api/v1/removed",
                 params={"since": "2026-10-20", "min_installs": 100000, "per": 100},
                 headers={"X-API-Key": os.environ["KEY"]}, timeout=30)
r.raise_for_status()
data = r.json()
for app in data["results"]:
    print(app["removed_seen_at"], app["id"], app["installs"]["label"])
print("credits left:", data["_credits"]["available"])
// Node.js 18+ (on the server — not in the browser)
const res = await fetch("https://apiapk.cc/api/v1/developer?id=5191370068110375942", { headers: { "X-API-Key": process.env.KEY } });
const d = await res.json();
if (!d.ok) throw new Error(d.error);
console.log(d.developer.name, d.developer.apps, d.developer.total_installs);
// PHP
$ch = curl_init('https://apiapk.cc/api/v1/keywords?lang=en&q=vpn&per=50');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('KEY')]]);
$d = json_decode(curl_exec($ch), true);
foreach ($d['results'] as $k) echo $k['keyword'], ' — ', $k['apps'], PHP_EOL;

Try it

You can create a key in your account. The request goes straight from your browser. The key is not stored anywhere and is gone after a page reload. Requests from the console spend credits like any other.