Download APKs from Google Play Store using anonymous authentication. Downloads base APKs, split APKs (App Bundles), OBB expansion files, and Play Asset Delivery packs — all by default.
v2.0 — Complete Rewrite. Ground-up rewrite with a new CLI, pure-Python protobuf decoding (no
gpapidependency), and automatic token management.
- Anonymous authentication via Aurora Store's token dispenser (no Google account needed)
- Multiple device profiles with automatic rotation for reliable token acquisition
- Downloads base APK, split APKs, OBB files, and asset packs in one go
- Streaming gzip decompression for Play Asset Delivery packs
- Beautiful terminal UI with real-time download progress bars
- Architecture support: ARM64 (modern phones) and ARMv7 (older phones)
- Custom token dispenser URL support
- Search and browse app details from the command line
- Find the latest available version by sampling multiple fresh GSF IDs
For servers, Docker images, or any environment that uses pip directly:
pip install git+https://github.com/appknox/gplaydl.gitIn a Dockerfile:
RUN pip3 install git+https://github.com/appknox/gplaydl.gitTo pin to a specific release tag or commit (recommended for production):
RUN pip3 install git+https://github.com/appknox/gplaydl.git@v2.0.0
# or by commit SHA:
RUN pip3 install git+https://github.com/appknox/gplaydl.git@46d0b1fIn a requirements.txt:
git+https://github.com/appknox/gplaydl.git
Requirements: Python 3.9+, uv
This package is not published to PyPI. Install directly from source:
git clone https://github.com/appknox/gplaydl.git
cd gplaydl
uv sync
uv pip install .# 1. Get an auth token (automatic, anonymous)
uv run gplaydl auth
# 2. Download an app (base APK only)
uv run gplaydl download com.whatsappAll commands below use uv run gplaydl .... If you activate the virtual environment (source .venv/bin/activate) you can drop the uv run prefix.
gplaydl auth # Default (arm64)
gplaydl auth --arch armv7 # Token for older ARM devices
gplaydl auth -d https://my-server/api # Use a custom dispenser
gplaydl auth --clear # Remove all cached tokens
gplaydl auth --country IN # Register device with India MCC/MNC
gplaydl auth --proxy socks5://host:1080 # Route dispenser call through proxy
gplaydl auth --profile "Galaxy S25 Ultra" # Use a specific device profile| Flag | Short | Default | Description |
|---|---|---|---|
--arch |
arm64 |
Architecture: arm64 or armv7 |
|
--dispenser |
-d |
Aurora Store | Custom token dispenser URL |
--clear |
false |
Remove all cached tokens | |
--country |
-c |
— | 2-letter country code; registers device with that region's MCC/MNC |
--proxy |
-p |
— | Proxy URL for dispenser calls (e.g. socks5://host:port) |
--profile |
— | Device profile key or name substring (e.g. Pv or Samsung). Run gplaydl profiles to list all |
Tokens are cached at ~/.config/gplaydl/auth-{arch}.json and reused automatically by other commands.
Probes multiple fresh GSF IDs (Google Services Framework IDs) from the token dispenser. Because Google stages rollouts by device cohort (tied to the GSF ID), sampling many IDs and taking the maximum version gives the most accurate latest version available.
gplaydl latest com.instagram.android
gplaydl latest com.instagram.android --stable 5
gplaydl latest com.instagram.android --profile "Galaxy S25 Ultra"
gplaydl latest com.instagram.android --country IN
gplaydl latest com.instagram.android --proxy socks5://host:1080
gplaydl latest com.instagram.android -s 4 -c US -p socks5://host:1080| Flag | Short | Default | Description |
|---|---|---|---|
--stable |
-s |
3 |
Stop early when the highest version code is unchanged for this many consecutive probes |
--profile |
top-ranked | Device profile for all probes (e.g. Galaxy S25 Ultra). Defaults to the highest SDK + Vending version profile |
|
--country |
-c |
— | 2-letter country code sent with FDFE requests |
--dispenser |
-d |
Aurora Store | Custom token dispenser URL |
--proxy |
-p |
— | Proxy URL for dispenser + FDFE calls (e.g. socks5://host:port) |
--arch |
arm64 |
Architecture for token acquisition |
How the pool works: The tool maintains a regional pool of 5 GSF ID / token pairs on disk (~/.config/gplaydl/token-pool-{arch}-{country}.json). Before every latest or download call, it checks how many valid (unexpired) tokens exist in that region's pool and fetches only the deficit from Aurora's dispenser — so if the pool is already full, zero dispenser calls are made. Tokens are valid for 50 minutes. If a token dies mid-request (HTTP 401), it is automatically replaced in the pool.
How convergence works: After each probe, if the best version code seen so far hasn't increased for --stable consecutive probes, the command stops early.
Output: A table with each probe's GSF ID prefix, version string, and version code. The highest version code is highlighted and printed as the final result with its version code.
By default, download fetches the base APK, all split APKs, and any additional files (OBB expansion files, Play Asset Delivery packs).
gplaydl download com.whatsapp # Everything (base + splits + extras)
gplaydl download com.whatsapp -o ./apks # Custom output directory
gplaydl download com.whatsapp -a armv7 # ARMv7 build
gplaydl download com.whatsapp -v 231205015 # Specific version code
gplaydl download com.instagram.android -v 434.0.0.44.74 # Specific version string
gplaydl download com.whatsapp --no-splits # Skip split APKs
gplaydl download com.whatsapp --no-extras # Skip OBB / asset packs
gplaydl download com.whatsapp -d https://... # Use custom dispenser
gplaydl download com.whatsapp --country IN # Country header for regional variant
gplaydl download com.whatsapp --proxy socks5://host:1080 # Route through proxy
gplaydl download com.whatsapp --profile "Galaxy S25 Ultra" # Specific device profile| Flag | Short | Default | Description |
|---|---|---|---|
--output |
-o |
. (current dir) |
Output directory |
--arch |
-a |
arm64 |
Architecture: arm64 or armv7 |
--version |
-v |
latest | Version code (e.g. 384009971) or version string (e.g. 434.0.0.44.74). When a version string is given, the tool probes fresh GSF IDs until it finds a cohort that sees that version |
--dispenser |
-d |
Aurora Store | Custom token dispenser URL |
--no-splits |
false |
Skip downloading split APKs | |
--no-extras |
false |
Skip downloading OBB files and asset packs | |
--country |
-c |
— | 2-letter country code (e.g. IN, US). Combine with --proxy for true regional APK variants |
--proxy |
-p |
— | Proxy URL for FDFE calls (e.g. socks5://host:port or http://host:port) |
--profile |
— | Device profile key or name substring (e.g. D2 or Samsung). Run gplaydl profiles to list all |
Output files:
| Type | Naming | Example |
|---|---|---|
| Base APK | {package}-{vc}.apk |
com.whatsapp-231205015.apk |
| Split APK | {package}-{vc}-{split}.apk |
com.whatsapp-231205015-config.arm64_v8a.apk |
| OBB (main/patch) | {type}.{vc}.{package}.obb |
main.20925.com.tencent.ig.obb |
| Asset pack | {package}-{vc}-asset.apk |
com.tencent.ig-20925-asset.apk |
Split APKs can be installed to a device with:
adb install-multiple *.apkgplaydl info com.whatsapp
gplaydl info com.whatsapp --country IN
gplaydl info com.whatsapp --proxy socks5://host:1080
gplaydl info com.whatsapp --profile "Galaxy S25 Ultra"| Flag | Short | Default | Description |
|---|---|---|---|
--arch |
arm64 |
Architecture for token | |
--dispenser |
-d |
Aurora Store | Custom token dispenser URL |
--country |
-c |
— | 2-letter country code; sets gl= and locale headers |
--proxy |
-p |
— | Proxy URL for FDFE calls |
--profile |
— | Device profile key or name substring |
Displays app name, version, developer, rating, download count, and Play Store URL.
gplaydl search "whatsapp"
gplaydl search "file manager" --limit 5
gplaydl search "whatsapp" --country IN| Flag | Short | Default | Description |
|---|---|---|---|
--limit |
-l |
10 |
Max results |
--arch |
arm64 |
Architecture for token | |
--dispenser |
-d |
Aurora Store | Custom token dispenser URL |
--country |
-c |
— | 2-letter country code for regional results |
--proxy |
-p |
— | Proxy URL for FDFE calls |
--profile |
— | Device profile key or name substring |
gplaydl list-splits com.whatsapp| Flag | Short | Default | Description |
|---|---|---|---|
--arch |
arm64 |
Architecture for token | |
--dispenser |
-d |
Aurora Store | Custom token dispenser URL |
Shows all split APK names (config splits, language splits, etc.) without downloading.
gplaydl profiles # All profiles
gplaydl profiles --arch arm64 # ARM64 only
gplaydl profiles --arch armv7 # ARMv7 onlyUse the Key column value with --profile in any command.
After uv sync, you can also invoke via the module directly:
uv run python -m gplaydl auth
uv run python -m gplaydl download com.whatsapp- Authentication — Gets an anonymous token from Aurora Store's dispenser, rotating through device profiles for reliability
- Details — Fetches app metadata (version, size, splits) via Google Play's protobuf API
- Purchase — "Purchases" the free app to get download authorization
- Delivery — Gets download URLs for the base APK, split APKs, OBB files, and asset packs
- Download — Streams all files in parallel from Google Play CDN with progress tracking
Google stages app rollouts by device cohort, which is determined by the GSF ID (Google Services Framework ID) — a device registration number assigned during token acquisition. Different GSF IDs may see different active versions (e.g. 434 vs 435 for the same app).
The latest command exploits this by sampling multiple fresh GSF IDs and reporting the highest version code seen:
gplaydl latest com.instagram.android --probes 10 --stable 3- Each probe fetches a fresh token → fresh GSF ID → queries Play Store for that cohort's version
- Probing stops early once the max version has been stable for
--stableconsecutive probes - The device profile (
--profile) affects which SDK level is presented; higher SDK profiles tend to receive new versions first
The tool uses Aurora Store's public token dispenser by default (https://auroraoss.com/api/auth). This service provides anonymous Google Play authentication tokens — no personal Google account required.
You can point to a custom/self-hosted dispenser with the --dispenser / -d flag on any command:
gplaydl auth -d https://my-dispenser.example.com/api/auth
gplaydl download com.whatsapp -d https://my-dispenser.example.com/api/authThe tool includes multiple device profiles, used to authenticate with Google Play's token dispenser. Profiles are rotated automatically during token acquisition to maximise compatibility.
Run gplaydl profiles to see all available profiles and their keys. Use --profile with any command to pin a specific device.
Profiles are stored as .properties files in the gplaydl/profiles/ directory.
| Flag | ABI | Devices |
|---|---|---|
arm64 (default) |
arm64-v8a | Modern phones (2017+) |
armv7 |
armeabi-v7a | Older 32-bit phones |