Fast CLI for Google Play Console, for developers optimized for your agentic development flows
SaferSkills independently audited play-console-cli (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<p align="center"> <img src="https://img.shields.io/badge/Go-1.24+-00ADD8?style=for-the-badge&logo=go" alt="Go Version"> <img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge" alt="License"> <img src="https://img.shields.io/badge/Homebrew-compatible-blue?style=for-the-badge" alt="Homebrew"> </p>
A fast, lightweight, and scriptable CLI for Google Play Console. Automate your Android app workflows from your terminal,optimized for your AI agentic development flows, claude code, codex, cursor
Stop clicking through Play Console. Ship your Android apps with a single command.
Compared against Fastlane supply and gradle-play-publisher (GPP). Areas where all three wrap the same Play Publisher API equivalently (APK/AAB upload, tracks, staged rollout, release notes, store listing text fields, app details, screenshots, mapping files, internal app sharing) are omitted.
API coverage gplay has that the others lack
| Capability | gplay | Fastlane | gradle-play-publisher |
|---|---|---|---|
| Monetization depth | IAPs, subscriptions, base plans, offers, pricing | No support | Basic IAPs + subscriptions (no base plans or offers) |
| Purchase verification | Products + subscriptions + acknowledge + orders refund | No support | No support |
| Vitals (crashes, ANRs, perf) | Clusters, reports, startup/rendering/battery metrics | No support | No support |
| Review management | Read + reply | No support | No support |
| Financial & stats reports | GCS download (earnings, sales, installs, ratings) | No support | No support |
| User & permission management | Developer users + per-app grants CRUD | No support | No support |
| Tester management | List and update closed-track tester emails | No support | No support |
| Data safety | Declarations management | No support | No support |
| Webhook notifications | Slack, Discord, generic (gplay notify) | No support | No support |
Runtime and ergonomics
| Capability | gplay | Fastlane | gradle-play-publisher |
|---|---|---|---|
| Runtime | Compiled Go binary, instant startup, no deps | Ruby + gems + bundler, slow to load | JVM + Gradle daemon, must run inside an AGP project |
| Agent-friendly output | JSON by default (saves tokens) | Human-oriented, colorized | Gradle task logs |
Publish & Release
Store Presence
Monetization
Purchases & Orders
Monitor Your App
Testing & Distribution
Team & Permissions
Reports & Notifications
Built for Automation
jq, scripts, or dashboardsinit, auth doctor)docs generate)# Via Homebrew (recommended)
brew tap tamtom/tap
brew install tamtom/tap/gplay
# Install script (macOS/Linux)
curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bash
# Build from source
git clone https://github.com/tamtom/play-console-cli.git
cd play-console-cli
make build
./gplay --helpgplay checks for updates on startup and shows upgrade hints. Disable with --no-update or GPLAY_NO_UPDATE=1.
Fastest path — automated setup (recommended):
# One command: creates a GCP service account, enables the API, downloads the key,
# and wires the profile into ~/.gplay/config.json.
gplay auth setup --auto --project <your-gcp-project-id>
# Preview the gcloud commands without running them
gplay auth setup --auto --project <your-gcp-project-id> --dry-runRequirements: gcloud installed and authenticated (gcloud auth login). After the wizard finishes, it prints a Play Console link to grant the service account access — that's the only manual step left.
Manual path — full control:
Step 1: Create a Google Cloud Project
Step 2: Enable the API
Step 3: Create a Service Account
Step 4: Grant Access in Play Console
[email protected])Step 5: Login with gplay
gplay auth login --service-account /path/to/service-account.json
# Verify it works
gplay auth doctor--pretty when debugging--paginate to automatically fetch all pages--sort (prefix - for descending): --sort -uploadedDate--limit + --next for manual pagination control# Edit lifecycle
gplay edits create --package com.example.app
gplay edits list --package com.example.app
gplay edits validate --package com.example.app --edit <id>
gplay edits commit --package com.example.app --edit <id>
# Upload artifacts
gplay bundles upload --package com.example.app --edit <id> --file app.aab
gplay apks upload --package com.example.app --edit <id> --file app.apk
# Manage tracks
gplay tracks list --package com.example.app --edit <id>
gplay tracks get --package com.example.app --edit <id> --track production
gplay tracks update --package com.example.app --edit <id> --track internal --json @release.json# One-command release (creates edit, uploads, updates track, commits)
gplay release --package com.example.app --track internal --bundle app.aab
# With release notes and staged rollout
gplay release --package com.example.app --track production --bundle app.aab \
--release-notes @notes.json --rollout 10
# Promote between tracks
gplay promote --package com.example.app --from internal --to beta
# Manage staged rollout
gplay rollout update --package com.example.app --track production --rollout 50
gplay rollout halt --package com.example.app --track production
gplay rollout resume --package com.example.app --track production
gplay rollout complete --package com.example.app --track production
# Release with metadata and screenshots
gplay release --package com.example.app --track production --bundle app.aab \
--listings-dir ./metadata --screenshots-dir ./screenshots
# Dry-run any command (intercepts write operations)
gplay --dry-run release --package com.example.app --track internal --bundle app.aab# List apps accessible by your service account
gplay apps list
# Initialize project configuration
gplay init
gplay init --package com.example.app --service-account /path/to/sa.json# Full environment health check (16 checks: gcloud, config, SA, DNS, disk, clock, ...)
gplay doctor
gplay doctor --output json --pretty
# Offline compliance scan on an AAB or APK (no API calls)
# Checks: manifest, bundle size, native ABIs, dex, debuggable, testOnly,
# cleartext traffic, dangerous permissions, secret scan, misplaced files.
gplay preflight --file app.aab
gplay preflight --file app.aab --max-size 100M --fail-on warning # CI gate
# Bundle size analysis (offline)
gplay bundles analyze --file app.aab --top-files 20
gplay bundles compare --base old.aab --candidate new.aab --threshold 2M
# Local audit log of every invocation (auto-written to ~/.gplay/audit.log)
gplay audit list --limit 50
gplay audit search --command vitals --status error
gplay audit clear --confirm
# Disable with GPLAY_AUDIT=0; override path with GPLAY_AUDIT_LOG.
# API quota usage (derived from audit log)
gplay quota status # daily + per-minute windows
gplay quota status --top 10
# Real-Time Developer Notifications (RTDN)
gplay rtdn setup --project <gcp-project> --topic play-rtdn
gplay rtdn status --project <gcp-project>
gplay rtdn decode --file payload.json # typed subscription/one-time/voided decoder
cat payload.json | gplay rtdn decode --file -# Crash reports
gplay vitals crashes clusters --package com.example.app
gplay vitals crashes reports --package com.example.app
# Performance metrics
gplay vitals performance startup --package com.example.app
gplay vitals performance rendering --package com.example.app
gplay vitals performance battery --package com.example.app
# Error tracking
gplay vitals errors issues --package com.example.app
gplay vitals errors reports --package com.example.app# Manage developer account users
gplay users list --developer <id>
gplay users create --developer <id> --email [email protected] --json @permissions.json
gplay users delete --developer <id> --email [email protected] --confirm
# Manage per-app grants
gplay grants create --developer <id> --email [email protected] --package com.example.app --json @grant.json
gplay grants update --developer <id> --email [email protected] --package com.example.app --json @grant.json
gplay grants delete --developer <id> --email [email protected] --package com.example.app --confirmReports are stored as CSV/ZIP files in Google Cloud Storage buckets (pubsite_prod_rev_<developer_id>). The service account must have access to the GCS bucket (granted automatically when added to Play Console).
Important: The--developerID for reports is not the developer ID in your Play Console URL. To find the correct ID, go to Play Console > Download reports > Copy Cloud Storage URI. The URI looks likegs://pubsite_prod_rev_XXXX/— the number afterpubsite_prod_rev_is your developer ID.
# Financial reports (earnings, sales, payouts)
gplay reports financial list --developer <id>
gplay reports financial list --developer <id> --type earnings --from 2026-01 --to 2026-06
gplay reports financial download --developer <id> --from 2026-01 --type earnings --dir ./reports
# Statistics reports (installs, ratings, crashes, store_performance, subscriptions)
gplay reports stats list --developer <id>
gplay reports stats list --developer <id> --package com.example.app --type installs
gplay reports stats download --developer <id> --package com.example.app --from 2026-01 --type installs --dir ./reports# Send webhook notifications (Slack, Discord, generic)
gplay notify send --webhook-url https://hooks.slack.com/... --message "Deploy complete" --format slack
gplay notify send --webhook-url https://discord.com/... --message "New release" --format discord# Listings
gplay listings list --package com.example.app --edit <id>
gplay listings get --package com.example.app --edit <id> --locale en-US
gplay listings update --package com.example.app --edit <id> --locale en-US --json @listing.json
# Images
gplay images list --package com.example.app --edit <id> --locale en-US --type phoneScreenshots
gplay images upload --package com.example.app --edit <id> --locale en-US --type phoneScreenshots --file screenshot.png
# App details
gplay details get --package com.example.app --edit <id>
gplay details update --package com.example.app --edit <id> --contact-email [email protected]# In-app products
gplay iap list --package com.example.app
gplay iap create --package com.example.app --sku premium_upgrade --json @product.json
gplay iap update --package com.example.app --sku premium_upgrade --json @product.json
gplay iap batch-update --package com.example.app --json @products.json
# Subscriptions
gplay subscriptions list --package com.example.app
gplay subscriptions create --package com.example.app --json @subscription.json
# Base plans
gplay baseplans activate --package com.example.app --product-id sub_premium --base-plan monthly
gplay baseplans deactivate --package com.example.app --product-id sub_premium --base-plan monthly
# Offers
gplay offers list --package com.example.app --product-id sub_premium --base-plan monthly
gplay offers create --package com.example.app --product-id sub_premium --base-plan monthly --json @offer.json
# Price conversion
gplay pricing convert --package com.example.app --json @price.json# Verify purchases
gplay purchases products get --package com.example.app --product-id premium --token <token>
gplay purchases products acknowledge --package com.example.app --product-id premium --token <token>
gplay purchases subscriptions get --package com.example.app --token <token>
# Orders
gplay orders get --package com.example.app --order-id <id>
gplay orders refund --package com.example.app --order-id <id> --revoke
# External transactions (EU compliance)
gplay external-transactions create --package com.example.app --json @transaction.json# List and filter reviews
gplay reviews list --package com.example.app
gplay reviews list --package com.example.app --paginate
# Reply to reviews
gplay reviews get --package com.example.app --review-id <id>
gplay reviews reply --package com.example.app --review-id <id> --text "Thank you!"# Manage testers
gplay testers list --package com.example.app --edit <id> --track internal
gplay testers update --package com.example.app --edit <id> --track internal --emails [email protected]
# Internal app sharing (quick sharing without review)
gplay internal-sharing upload-bundle --package com.example.app --file app.aab
gplay internal-sharing upload-apk --package com.example.app --file app.apk# Export metadata to FastLane format
gplay sync export-listings --package com.example.app --dir ./fastlane/metadata/android
# Import metadata from FastLane format
gplay sync import-listings --package com.example.app --dir ./fastlane/metadata/android
# Compare local metadata with Play Store
gplay sync diff-listings --package com.example.app --dir ./fastlane/metadata/android
# Validate before upload
gplay validate listing --dir ./fastlane/metadata/android --locale en-US
gplay validate screenshots --dir ./fastlane/metadata/android/en-US/images
gplay validate bundle --file app.aab# Bash
gplay completion bash > /etc/bash_completion.d/gplay
# Zsh
gplay completion zsh > "${fpath[1]}/_gplay"
# Fish
gplay completion fish > ~/.config/fish/completions/gplay.fish
# PowerShell
gplay completion powershell >> $PROFILE| Format | Flag | Use Case |
|---|---|---|
| JSON (minified) | default | Scripting, automation |
| JSON (pretty) | --pretty | Debugging |
| Table | --output table | Terminal display |
| Markdown | --output markdown | Documentation |
# Parse with jq
gplay tracks list --package com.example.app | jq '.tracks[].track'
# Human-readable
gplay reviews list --package com.example.app --output table# Good - self-documenting
gplay reviews list --package com.example.app --output table
# Avoid - cryptic flags (not supported)
# gplay reviews -p com.example.app -o tableAll commands output minified JSON by default for easy parsing:
gplay tracks list --package com.example.app | jq '.tracks[] | select(.track == "production")'Everything is flag-based for automation:
# Non-interactive (CI/CD safe)
gplay edits delete --package com.example.app --edit <id> --confirmbrew tap tamtom/tap
brew install tamtom/tap/gplaycurl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bashSpecify version:
GPLAY_VERSION=1.0.0 curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bashgit clone https://github.com/tamtom/play-console-cli.git
cd play-console-cli
make build
make install # Installs to /usr/local/binService accounts are required for the Google Play Android Developer API.
#### 1. Create Google Cloud Project & Enable API
Google Cloud Console → Create Project → APIs & Services → Library
→ Search "Google Play Android Developer API" → Enable#### 2. Create Service Account & Download Key
IAM & Admin → Service Accounts → Create Service Account
→ Name it (e.g., "gplay-cli") → Create → Done
→ Click the account → Keys → Add Key → Create new key → JSON
→ Save the JSON file securely (never commit to git!)#### 3. Grant Access in Play Console
Play Console → Users and permissions → Invite new users
→ Paste service account email (from JSON: "client_email" field)
→ Set permissions (Admin, or per-app access)
→ Invite user#### 4. Configure gplay
# Option A: Login command (saves to profile)
gplay auth login --service-account /path/to/service-account.json
# Option B: Environment variable
export GPLAY_SERVICE_ACCOUNT=/path/to/service-account.json
# Verify setup
gplay auth doctor| Variable | Description |
|---|---|
GPLAY_SERVICE_ACCOUNT | Path to service account JSON |
GPLAY_PACKAGE | Default package name |
GPLAY_PROFILE | Active profile name |
GPLAY_TIMEOUT | Request timeout (e.g., 90s, 2m) |
GPLAY_UPLOAD_TIMEOUT | Upload timeout (e.g., 5m, 10m) |
GPLAY_NO_UPDATE | Disable update checks (set to 1) |
GPLAY_DEBUG | Enable debug logging (1 or api) |
GPLAY_MAX_RETRIES | Max retries for failed requests |
GPLAY_RETRY_DELAY | Base delay between retries |
GPLAY_DEFAULT_OUTPUT | Default output format (json, table, markdown) |
Global: ~/.gplay/config.yaml Local (takes precedence): ./.gplay/config.yaml
default_package: com.example.app
timeout: 120s
upload_timeout: 5m
max_retries: 3
debug: false# Add profiles for different accounts/apps
gplay auth login --profile work --service-account /path/to/work-sa.json
gplay auth login --profile personal --service-account /path/to/personal-sa.json
# Switch default profile
gplay auth switch --profile work
# Check current status
gplay auth status
# Use specific profile for a command
GPLAY_PROFILE=personal gplay tracks list --package com.example.appname: Deploy to Play Store
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up gplay
run: |
curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Build app
run: ./gradlew bundleRelease
- name: Deploy to internal track
env:
GPLAY_SERVICE_ACCOUNT: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
run: |
gplay release \
--package com.example.app \
--track internal \
--bundle app/build/outputs/bundle/release/app-release.aabdeploy:
stage: deploy
image: ubuntu:latest
before_script:
- curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bash
- export PATH="$HOME/.local/bin:$PATH"
script:
- gplay release --package $PACKAGE_NAME --track internal --bundle app.aab
variables:
GPLAY_SERVICE_ACCOUNT: $PLAY_SERVICE_ACCOUNTCredentials are stored in config with file path reference only (not the key content).
make tools # installs gofumpt + golangci-lint
make format
make lint
make test
make build
./gplay --helpContributions are welcome! Please read CONTRIBUTING.md for details.
Use gplay with AI coding agents for assisted Android publishing workflows. Compatible with any agent that supports the Agent Skills format.
npx skills add tamtom/gplay-cli-skills| Skill | Description |
|---|---|
gplay-cli-usage | Guidance for running gplay commands (flags, pagination, output, auth) |
gplay-release-flow | End-to-end release workflows for internal, beta, and production tracks |
gplay-gradle-build | Build, sign, and package Android apps with Gradle before uploading |
gplay-metadata-sync | Metadata and localization sync (including FastLane format) |
gplay-rollout-management | Staged rollout orchestration and monitoring |
gplay-review-management | Review monitoring, filtering, and automated responses |
gplay-iap-setup | In-app products, subscriptions, base plans, and offers |
gplay-purchase-verification | Server-side purchase verification |
gplay-testers-orchestration | Beta testing groups and tester management |
gplay-signing-setup | Android app signing, keystores, and Play App Signing |
gplay-vitals-monitoring | App vitals monitoring for crashes, errors, and performance |
gplay-user-management | Developer account user and permission grant management |
gplay-migrate-fastlane | Migration from Fastlane metadata to gplay format |
gplay-reports-download | Financial and statistics report listing/downloading from GCS |
Skills repository: github.com/tamtom/gplay-cli-skills
MIT License - see LICENSE for details.
<p align="center"> Built with Go and the <a href="https://github.com/peterbourgon/ff">ffcli</a> framework </p>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.