gplaydl-web
August 1, 2026 ยท View on GitHub
Live site: gplaydl.com
gplaydl-web is a server-rendered Go service that downloads APK files from
Google Play using a Google account paired through
gplaydl-dispenser.
Important: This project uses unofficial Google Play access. Google may flag, lock, or restrict accounts used with it. Please use a separate account and continue at your own risk.
The service does not save APKs. It redirects the browser to an allowlisted
Google CDN URL whenever the URL authorizes itself (token-authenticated
play.googleapis.com links do, even though Google attaches an optional
cookie), and streams without buffering to disk only for gzip-wrapped payloads
or hosts where the delivery cookie may genuinely be required.
How it works
- The user adds their own Google account in gplaydl Authenticator.
- The browser exchanges a one-time pairing code for a dispenser API key.
- The API key is stored in an authenticated, encrypted, HTTP-only cookie.
- The service asks the dispenser for a short-lived Play token and calls Google Play's details, purchase, and delivery endpoints.
- Delivery manifests are cached in memory for one hour by default. Users can request a fresh link from the advanced form control.
Cache entries are isolated by a hash of the pairing key, package, locale, and device profile. Tokens, API keys, cookies, and CDN capability URLs are not logged.
Local development
Go 1.26 or newer is required.
cp .env.example .env
export PUBLIC_URL=http://localhost:8081
export SESSION_KEY="$(openssl rand -base64 32)"
go run ./cmd/gplaydl-web
The service listens on 127.0.0.1:8081 by default. Environment files are not
loaded automatically; export them or use your process supervisor.
Configuration:
GPLAYDL_ADDR: listen address.PUBLIC_URL: canonical external origin.DISPENSER_URL: HTTPS dispenser origin.SESSION_KEY: base64-encoded 32-byte AES key; required for HTTPS deployments.CACHE_ENABLED: enables the in-memory manifest cache.CACHE_TTL: manifest lifetime, default1h.CACHE_MAX_ENTRIES: bounded cache size, default1000.UPSTREAM_TIMEOUT: response-header timeout, default30s.
Verification
gofmt -w .
go vet ./...
go test -race ./...
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath ./cmd/gplaydl-web
Tests cover protobuf decoding, cache isolation and bypass, encrypted session tamper resistance, and CDN host validation.
Deployment
The files in deploy install the binary as a hardened systemd
service on 127.0.0.1:8081 and proxy gplaydl.com through Caddy. The GitHub
Actions workflow builds a static Linux/amd64 binary and supports atomic
deployment with health checks and rollback.
Production requires a unique SESSION_KEY. Restrict the deployment user to
writing /opt/gplaydl-web and restarting only gplaydl-web; Caddy and initial
systemd installation should remain administrator-controlled.
Related projects
- gplaydl provides the full command-line downloader.
- gplaydl Authenticator (source) adds your Google account.
- gplaydl dispenser (source) keeps accounts private and mints short-lived Play sessions.
Important limitations
- This is an unofficial Google Play client and is not affiliated with Google.
- Google can change its private Play protocol without notice.
- Availability depends on the paired account, region, and selected Android device profile. Paid or unacquired apps may not be downloadable.
- Split APK apps require the base APK and all relevant configuration splits.
- The user is responsible for the downloaded app's license and publisher terms.
- Unofficial clients can trigger account security checks or restrictions; a separate account without payment methods is advisable.