accounts_list
List every Play Console account registered with the MCP server (names + key-file paths, no secrets).
Takes no parameters.

io.github.devinwangPublished by GitHub account devinwangv0.2.0Updated Oct 29, 2026
MCP server for Google Play: full Android Publisher API v3 and Play Developer Reporting API.
Local MCP server exposing Google Play Console via the Android Publisher API v3 and Play Developer Reporting API, so an assistant can manage releases…
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Follow the launch instructions in the repository.
The complete Model Context Protocol (MCP) server for Google Play. 157 tools. Full Android Publisher API v3 + Play Developer Reporting API v1beta1. No deprecated endpoints. Works with Claude, Cursor, VS Code Copilot, Gemini CLI, or any MCP client.
[npm version] [npm downloads] [CI] [License: MIT] [Node] [Tools: 157] [API: v3] [Reporting: v1beta1] [MCP] [TypeScript]
See also: app-store-connect-mcp — the same philosophy for Apple's App Store Connect.
Google Play Console has an API, but its surface is wide and moves fast. Existing community MCPs each cover a slice — one does store listings, another does releases, a third does reviews — and all lag behind Google's deprecations.
google-play-developer-mcp is the one that covers everything.
If you drive Google Play Console with an AI assistant — release automation, review triage, subscription catalog management, crash triage — this gives the assistant a full toolbox in one install.
157 tools across 33 groups. Every non-deprecated endpoint in both APIs.
Then in your MCP client config (e.g. ~/.config/claude/config.json, Cursor MCP config, or VS Code mcp.json):
Next, tell the server which Play Console account to use — see the setup guide below.
~/.config/google-play-developer-mcp/service-account.json.[email protected]).PERMISSION_DENIED, this is usually why.Launch any MCP client that has the server configured, then run:
(Or manually create ~/.google-play-developer-mcp/accounts.json — see the file format below.)
Should return { ok: true, email: "..." }.
Lists the apps the service account can see.
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%/Claude/claude_desktop_config.json
Or edit ~/.claude.json:
Settings → MCP → Add new MCP server:
.vscode/mcp.json:
Any MCP-compliant client accepts the same command entry — point it at the globally installed google-play-developer-mcp binary (or at node /path/to/dist/index.js if running from source).
Then in your MCP client config:
All tools use snake_case names following the resource_action convention, consistent with the Android Publisher URL structure. See the Feature matrix for the full group breakdown.
Each tool accepts a JSON object of arguments — inspect the schema from your MCP client (Claude Code: /mcp tools, Claude Desktop: show tool list in chat, Cursor: MCP panel) to see the exact shape.
Complex body arguments (e.g. subscription, offer, appRecoveryAction, subscription releases) accept the Google-documented JSON schema directly — see the official reference.
This repo ships with zero credentials. You bring a service-account JSON key; the server records only the path.
What is and isn't on disk:
.gitignore blocks*.json.key, *service-account*.json, *service_account*.json, *-sa.json, *-sa-key.jsongcp-key*.json, google-credentials*.json, play-credentials*.json.env, .env.* (but keeps .env.example)accounts.json, credentials/, keys/, secrets/*.pem, *.p12, *.pfx, *.key, id_rsa*accounts_update --keyFile <newPath>.auth_status never returns the actual token; only a boolean and the service-account email.Every write operation on the Android Publisher API is logged by Google Cloud IAM under the service account's identity. If you ever suspect misuse, IAM → Audit Logs in the Cloud Console will show which endpoints were called.
edits_insert / edits_commit / edits_delete directly so you can hold an edit open across many tool calls — the most common multi-step flow. If you forget to commit, nothing ships. Safe by default.accounts_switch. State lives in ~/.google-play-developer-mcp/accounts.json.monetization.onetimeproducts (not the deprecated inappproducts). Purchase verification uses purchasesV2 / subscriptionsV2.googleapis TypeScript typings, we cast through publisherAny() / reportingAny(). The HTTP calls are identical — only TypeScript's static check is skipped on the known-drifting surfaces.PRs welcome. Before you submit:
npm run typecheck passes (CI will also run this)X-Goog-Api-Client: ...REDACTED...).resource_action naming convention.orders_review_refund, purchases_products_acknowledge, purchases_products_consume, reports_anon_rss_swap_memory_{get,query}, reports_bitmap_memory_{get,query}.googleapis 171 → 187.monetization.onetimeproducts (replaces deprecated inappproducts), purchases.productsv2 / subscriptionsv2 (replaces v1).SubscriptionPurchaseV2.offerPhase, purchases.subscriptionsv2.cancel/defer, orders.batchGet, offerPhaseDetails, price step-up consent, outOfAppPurchaseContext..gitignore.monetization.onetimeproducts referencepurchases.subscriptionsv2 referenceMIT — see LICENSE.
Source: README.md at commit ffe25df
List every Play Console account registered with the MCP server (names + key-file paths, no secrets).
Takes no parameters.
Show which account is currently active. All subsequent API calls target this account.
Takes no parameters.
Register a new Play Console account. Provide a local filesystem path to a Google Cloud service-account JSON key. The key stays on disk — the MCP only records its path.
namerequiredkeyFilerequireddescriptionRemove an account from the local registry. Does NOT delete the key file.
namerequiredMake an existing registered account the active one.
namerequiredChange the key-file path or description of an existing account.
namerequiredkeyFiledescriptionVerify that the active account can acquire a Google OAuth token. Returns the service-account email plus whether a token was obtained.
Takes no parameters.
List every Android app the active service account can access. Uses the Play Developer Reporting API's apps.search.
pageSizepageTokenOpen a fresh edit and return the details resource (contact email/phone/website + default language) for one app.
packageNamerequiredOpen a new edit session for an app. Returns the edit id plus its expiry. Subsequent edits.* tool calls must pass this id.
packageNamerequiredFetch an existing edit — useful to check expiry before work.
editIdrequiredpackageNamerequiredValidate an edit without committing. Catches schema/media errors before you publish.
editIdrequiredpackageNamerequiredCommit and publish all changes in the edit. Pass changesNotSentForReview=true to skip automatic review submission.
editIdrequiredpackageNamerequiredchangesNotSentForReviewAbandon an edit. All pending changes are discarded.
editIdrequiredpackageNamerequiredGet app-level details (contact email/phone/website + default language).
editIdrequiredpackageNamerequiredOverwrite app-level details. Full replacement — unspecified fields are cleared.
editIdrequiredpackageNamerequiredcontactEmailcontactPhonecontactWebsitedefaultLanguagePartial update — only the provided fields change.
editIdrequiredpackageNamerequiredcontactEmailcontactPhonecontactWebsitedefaultLanguageFetch per-country availability for a given track within an edit.
trackrequirededitIdrequiredpackageNamerequiredList every locale listing within an edit.
editIdrequiredpackageNamerequiredGet one locale's listing.
editIdrequiredlanguagerequiredpackageNamerequiredFull replacement update of a locale listing. Fields: title (30), shortDescription (80), fullDescription (4000), video (YouTube URL).
titlevideoeditIdrequiredlanguagerequiredpackageNamerequiredfullDescriptionshortDescriptionPartial update — unspecified fields preserved.
titlevideoeditIdrequiredlanguagerequiredpackageNamerequiredfullDescriptionshortDescriptionDelete the listing for one locale.
editIdrequiredlanguagerequiredpackageNamerequiredDelete ALL locale listings in this edit. Irreversible within the edit.
editIdrequiredpackageNamerequiredList uploaded images for a specific type and locale.
editIdrequiredlanguagerequiredimageTyperequiredpackageNamerequiredUpload a new image. `file` is a local filesystem path. MIME is auto-detected from extension (png/jpg).
filerequirededitIdrequiredlanguagerequiredimageTyperequiredpackageNamerequiredDelete a single image by id.
editIdrequiredimageIdrequiredlanguagerequiredimageTyperequiredpackageNamerequiredDelete every image of a given type in one locale.
editIdrequiredlanguagerequiredimageTyperequiredpackageNamerequiredList all AAB uploads in the current edit.
editIdrequiredpackageNamerequiredUpload a new App Bundle (.aab). Returns versionCode and sha256. Commit the edit separately to publish to a track.
filerequirededitIdrequiredpackageNamerequireddeviceTierConfigIdackBundleInstallationWarningList all APK uploads in the edit.
editIdrequiredpackageNamerequiredUpload a new APK. Prefer AAB via `bundles_upload`.
filerequirededitIdrequiredpackageNamerequiredRegister an APK that is hosted outside Google Play (enterprise-only, requires allowlist).
editIdrequiredpackageNamerequiredexternallyHostedApkrequiredUpload a ProGuard mapping file for a specific version code. Use deobfuscationFileType='proguard' or 'nativeCode'.
filerequirededitIdrequiredpackageNamerequiredapkVersionCoderequireddeobfuscationFileTyperequiredGet expansion file metadata for a version code.
editIdrequiredpackageNamerequiredapkVersionCoderequiredexpansionFileTyperequiredUpload expansion file contents (OBB).
filerequirededitIdrequiredpackageNamerequiredapkVersionCoderequiredexpansionFileTyperequiredFull update of expansion file metadata.
editIdrequiredfileSizepackageNamerequiredapkVersionCoderequiredexpansionFileTyperequiredreferencesVersionPartial update of expansion file metadata.
editIdrequiredfileSizepackageNamerequiredapkVersionCoderequiredexpansionFileTyperequiredreferencesVersionList every track visible in this edit (includes default internal/alpha/beta/production + any custom closed-testing tracks).
editIdrequiredpackageNamerequiredGet one track — includes all releases currently staged.
trackrequirededitIdrequiredpackageNamerequiredFull replacement of track state. `releases` is an array of release objects — versionCodes, status (draft|inProgress|halted|completed), userFraction (0-1 for staged rollout), inAppUpdatePriority (0-5), countryTargeting, and releaseNotes.
trackrequirededitIdrequiredreleasesrequiredpackageNamerequiredPartial update of track state.
trackrequirededitIdrequiredreleasesrequiredpackageNamerequiredCreate a brand-new custom closed-testing track. The new id is set on the server. Type can only be closedTesting.
typetrackrequirededitIdrequiredpackageNamerequiredtrackConfigurationsGet the current tester allowlist for a track.
trackrequirededitIdrequiredpackageNamerequiredFull replacement of the tester allowlist.
trackrequirededitIdrequiredpackageNamerequiredgoogleGroupsPartial update of the tester allowlist.
trackrequirededitIdrequiredpackageNamerequiredgoogleGroupsList all one-time products.
pageSizepageTokenpackageNamerequiredGet a single one-time product.
productIdrequiredpackageNamerequiredCreate a one-time product. Pass the full OneTimeProduct body.
productrequiredproductIdrequiredpackageNamerequiredregionsVersionUpdate a one-time product (patch semantics, with updateMask).
productrequiredproductIdrequiredupdateMaskpackageNamerequiredregionsVersionlatencyToleranceDelete a one-time product.
productIdrequiredpackageNamerequiredlatencyToleranceFetch up to 100 one-time products in one call.
productIdsrequiredpackageNamerequiredUpdate up to 100 one-time products in one call.
requestsrequiredpackageNamerequiredDelete up to 100 one-time products in one call.
requestsrequiredpackageNamerequiredUpdate or create up to 100 purchase options for a one-time product.
requestsrequiredproductIdrequiredpackageNamerequiredActivate or deactivate up to 100 purchase options in one call.
requestsrequiredproductIdrequiredpackageNamerequiredDelete up to 100 purchase options.
requestsrequiredproductIdrequiredpackageNamerequiredList offers attached to a purchase option. `purchaseOptionId` is required — use '-' to list across all options.
pageSizepageTokenproductIdrequiredpackageNamerequiredpurchaseOptionIdrequiredGet one offer on a purchase option.
offerIdrequiredproductIdrequiredpackageNamerequiredpurchaseOptionIdrequiredBatch-get up to 100 offers.
requestsrequiredproductIdrequiredpackageNamerequiredpurchaseOptionIdrequiredBatch-update up to 100 offers (creates or updates).
requestsrequiredproductIdrequiredpackageNamerequiredpurchaseOptionIdrequiredActivate/deactivate/cancel up to 100 offers.
requestsrequiredproductIdrequiredpackageNamerequiredpurchaseOptionIdrequiredDelete up to 100 offers.
requestsrequiredproductIdrequiredpackageNamerequiredpurchaseOptionIdrequiredList all subscriptions.
pageSizepageTokenpackageNamerequiredshowArchivedGet a single subscription.
productIdrequiredpackageNamerequiredCreate a subscription.
productIdrequiredpackageNamerequiredsubscriptionrequiredregionsVersionPatch-update a subscription. Pass `updateMask` to limit the fields updated.
productIdrequiredupdateMaskpackageNamerequiredallowMissingsubscriptionrequiredregionsVersionlatencyToleranceDelete a subscription. Only works on subscriptions with no active base plans/offers.
productIdrequiredpackageNamerequiredlatencyToleranceArchive a subscription. Archived subscriptions are hidden from new purchases but existing subscribers keep access.
productIdrequiredpackageNamerequiredGet up to 100 subscriptions in one call.
productIdsrequiredpackageNamerequiredUpdate up to 100 subscriptions in one call.
requestsrequiredpackageNamerequiredActivate a base plan — starts making it available for purchase.
productIdrequiredbasePlanIdrequiredpackageNamerequiredDeactivate a base plan — no new purchases; existing subscribers unaffected.
productIdrequiredbasePlanIdrequiredpackageNamerequiredDelete a base plan (must be inactive).
productIdrequiredbasePlanIdrequiredpackageNamerequiredApply a price change to existing subscribers of a base plan in specific regions.
productIdrequiredbasePlanIdrequiredpackageNamerequiredregionsVersionlatencyToleranceregionalPriceMigrationsrequiredMigrate prices on up to 100 base plans in one call.
requestsrequiredproductIdrequiredpackageNamerequiredUpsert up to 100 base plans.
requestsrequiredproductIdrequiredpackageNamerequiredActivate/deactivate up to 100 base plans.
requestsrequiredproductIdrequiredpackageNamerequiredList offers for a base plan. `basePlanId` supports '-' wildcard to list across all.
pageSizepageTokenproductIdrequiredbasePlanIdrequiredpackageNamerequiredGet a single offer.
offerIdrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredCreate an offer on a base plan (free trial, intro pricing, etc.).
offerrequiredofferIdrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredregionsVersionPatch-update an offer.
offerrequiredofferIdrequiredproductIdrequiredbasePlanIdrequiredupdateMaskpackageNamerequiredallowMissingregionsVersionlatencyToleranceDelete an offer.
offerIdrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredActivate an offer — starts making it available for purchase.
offerIdrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredDeactivate an offer.
offerIdrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredBatch-get up to 100 offers.
requestsrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredUpsert up to 100 offers.
requestsrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredActivate/deactivate up to 100 offers.
requestsrequiredproductIdrequiredbasePlanIdrequiredpackageNamerequiredUtility: convert a price in one region to comparable prices in every other region. Use before setting prices on a base plan.
pricerequiredpackageNamerequiredGet current state of a one-time product purchase. Supports multiple purchase options + offers (replaces legacy purchases.products).
tokenrequiredpackageNamerequiredAcknowledge a one-time product purchase. Unacknowledged purchases are refunded by Play after 3 days.
tokenrequiredproductIdrequiredpackageNamerequireddeveloperPayloadConsume a consumable one-time product so the user can buy it again. Consuming also acknowledges the purchase.
tokenrequiredproductIdrequiredpackageNamerequiredGet full state of a subscription purchase (SubscriptionPurchaseV2). Includes OfferPhase (2026), outOfAppPurchaseContext, latestSuccessfulOrderId, priceChangeState, priceStepUpConsentDetails.
tokenrequiredpackageNamerequiredRevoke a subscription (refund + terminate access). 2025-05 added `itemBasedRefund` option for per-item refunds.
tokenrequiredpackageNamerequiredrevocationContextCancel a subscription (2025-09+). `cancellationType`: USER_REQUESTED, DEVELOPER_REQUESTED, or SYSTEM_INITIATED.
tokenrequiredpackageNamerequiredcancellationTypecancelSurveyReasonDefer billing for a subscription (2026-01 supports subscriptions with add-ons too). Pass DeferralInfo with expectedExpiryTime + desiredExpiryTime.
tokenrequiredpackageNamerequireddeferralInforequiredAcknowledge a subscription purchase. 2025-11+ accepts optional `externalAccountId` for account-linking. (v1 endpoint retained for compatibility.)
tokenrequiredpackageNamerequiredsubscriptionIddeveloperPayloadexternalAccountIdList voided purchases (refunded/charged-back). Supports filtering by time range + voided source.
typetokenendTimestartTimemaxResultsstartIndexpackageNamerequiredincludeQuantityBasedPartialRefundsList orders within a time window. Returns OrderId, productId, purchase state, quantity, offerPhaseDetails.
endTimeorderIdspageTokenstartTimemaxResultspackageNamerequiredGet one order by order id.
orderIdrequiredpackageNamerequiredGet up to 100 orders in one call.
orderIdsrequiredpackageNamerequiredRefund an order. Pass `revoke=true` to also cancel the entitlement (subscription) or consumable.
revokeorderIdrequiredpackageNamerequiredRespond to a pending refund review (collaborative chargeback, 2026-07). Call within 24 hours of a PendingRefundReviewNotification. Supply `refundPreference` and optional usage evidence so Play can dispute the chargeback.
orderIdrequiredpackageNamerequiredrefundPreferencerequiredpendingRefundTokenrequiredsampleContentProvidedrequiredconsumptionUsageEventsconsumptionPercentageMilliunitsGet an external transaction (Alternative Billing).
parentrequiredexternalTransactionIdrequiredRegister a new external transaction (Alternative Billing).
parentrequiredtransactionrequiredexternalTransactionIdrequiredReport a refund on an external transaction.
parentrequiredrefundrequiredexternalTransactionIdrequiredList reviews from the last 7 days. Use token from the previous page for pagination. Optional filters: language, translationLanguage, device.
tokenmaxResultsstartIndexpackageNamerequiredtranslationLanguageGet a single review by id.
reviewIdrequiredpackageNamerequiredtranslationLanguagePost a public reply to a review. Replies can be edited by calling this again.
reviewIdrequiredreplyTextrequiredpackageNamerequiredList all users on a developer account. `parent` is the developer account id in the form `developers/{developerId}` (find it in the Play Console URL).
parentrequiredpageSizepageTokenAdd a new team member to the developer account. Pass the user resource with email + roles + optional expirationTime.
userrequiredparentrequiredPatch-update a team member (roles, access level).
namerequireduserrequiredupdateMaskRemove a user from the developer account.
namerequiredGrant a user access to one app. `parent` is developers/{dev}/users/{user}. Grant body contains packageName + appLevelPermissions.
grantrequiredparentrequiredPatch a grant (change appLevelPermissions).
namerequiredgrantrequiredupdateMaskRevoke a grant.
namerequiredList all device-tier configs for an app.
pageSizepageTokenpackageNamerequiredCreate a new device-tier config.
packageNamerequireddeviceTierConfigrequiredallowUnknownDevicesGet a device-tier config by id.
packageNamerequireddeviceTierConfigIdrequiredList app recovery actions for a versionCode.
packageNamerequiredversionCoderequiredCreate an app recovery action.
packageNamerequiredappRecoveryActionrequiredDeploy an app recovery action to users.
packageNamerequiredappRecoveryIdrequiredCancel an in-flight app recovery action.
packageNamerequiredappRecoveryIdrequiredAdd targeting (country/locale/version) to an in-progress recovery action.
packageNamerequiredappRecoveryIdrequiredtargetingUpdaterequiredList generated (split + standalone) APKs for a given bundle versionCode.
packageNamerequiredversionCoderequiredDownload a specific generated APK. `downloadId` is the id from `generated_apks_list`. Returns the binary as a base64 string.
downloadIdrequiredpackageNamerequiredversionCoderequiredList system APK variants created for a given versionCode.
packageNamerequiredversionCoderequiredCreate a new system APK variant for a versionCode.
variantrequiredpackageNamerequiredversionCoderequiredGet a system APK variant.
variantIdrequiredpackageNamerequiredversionCoderequiredDownload a built system APK variant. Returns base64.
variantIdrequiredpackageNamerequiredversionCoderequiredUpload an APK for internal app sharing. Returns a link you can distribute internally.
filerequiredpackageNamerequiredUpload an AAB for internal app sharing.
filerequiredpackageNamerequiredList every app the service account can access.
pageSizepageTokenList the release-filter dimensions available for an app (version codes, track, staged rollout).
namerequiredList detected anomalies across metric sets for an app.
filterparentrequiredpageSizepageTokenGet crash-rate metric-set metadata (available dimensions, metrics, freshness).
namerequiredQuery crash-rate timeline with dimensions, metrics, filter.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet ANR-rate metric-set metadata.
namerequiredQuery ANR-rate timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet anonymous RSS + swap memory usage metric-set metadata. Format: apps/{packageName}/anonRssAndSwapMemoryUsageMetricSet
namerequiredQuery anonymous RSS + swap memory usage timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet bitmap memory usage metric-set metadata. Format: apps/{packageName}/bitmapMemoryUsageMetricSet
namerequiredQuery bitmap memory usage timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet slow-start-rate metadata.
namerequiredQuery slow-start-rate timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet slow-rendering-rate metadata.
namerequiredQuery slow-rendering-rate timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet excessive-wake-up-rate metadata.
namerequiredQuery excessive-wake-up-rate timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet stuck-background-wake-lock-rate metadata.
namerequiredQuery stuck-background-wake-lock-rate timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet Low-Memory-Killer (LMK) rate metadata.
namerequiredQuery LMK-rate timeline.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecGet error-counts metric-set metadata.
namerequiredQuery aggregated error-count timelines.
namerequiredfiltermetricspageSizepageTokendimensionsuserCohorttimelineSpecSearch grouped error issues (ErrorIssue).
filterparentrequiredintervalpageSizepageTokenSearch raw error reports (ErrorReport) within an issue or time window.
filterparentrequiredintervalpageSizepageToken90% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
npm install -g google-play-developer-mcp{ "mcpServers": { "google-play-developer": { "command": "google-play-developer-mcp" } }}accounts_add --name my-app \ --keyFile /Users/you/.config/google-play-developer-mcp/service-account.json \ --description "My company's Play Console"auth_statusapps_list{ "mcpServers": { "google-play-developer": { "command": "google-play-developer-mcp" } }}claude mcp add google-play-developer google-play-developer-mcp{ "mcpServers": { "google-play-developer": { "command": "google-play-developer-mcp" } }}{ "google-play-developer": { "command": "google-play-developer-mcp" }}{ "servers": { "google-play-developer": { "type": "stdio", "command": "google-play-developer-mcp" } }}git clone https://github.com/devinwang/google-play-developer-mcp.gitcd google-play-developer-mcpnpm installnpm run build{ "mcpServers": { "google-play-developer": { "command": "node", "args": ["/absolute/path/to/google-play-developer-mcp/dist/index.js"] } }}accounts_switch --name my-app
# Open an edit, upload bundle, route it to the internal track, commit.edits_insert --packageName com.example.app# → { id: "EDIT_ID", expiryTimeSeconds: "..." }
bundles_upload --packageName com.example.app --editId EDIT_ID \ --file /path/to/app-release.aab# → { versionCode: 47, sha256: "..." }
tracks_update --packageName com.example.app --editId EDIT_ID \ --track internal \ --releases '[{"versionCodes":["47"],"status":"completed","releaseNotes":[{"language":"en-US","text":"Fixes a crash on startup."}]}]'
edits_commit --packageName com.example.app --editId EDIT_IDedits_insert --packageName com.example.app# → EDIT_ID
# Promote the beta versionCodes to production with 10% staged rollout.tracks_update --packageName com.example.app --editId EDIT_ID \ --track production \ --releases '[{"versionCodes":["47"],"status":"inProgress","userFraction":0.1}]'
edits_commit --packageName com.example.app --editId EDIT_IDreviews_list --packageName com.example.app --maxResults 50# → { reviews: [{ reviewId, authorName, comments, ... }] }
reviews_reply --packageName com.example.app --reviewId REVIEW_ID \ --replyText "Thanks for the feedback! The crash is fixed in v1.2 — please update."# 1. Create the subscription (product)subscriptions_create --packageName com.example.app --productId plus_monthly \ --subscription '{"listings":[{"languageCode":"en-US","title":"Plus","benefits":["All premium features"]}],"taxAndComplianceSettings":{"taxTier":"TAX_TIER_UNSPECIFIED"}}'
# 2. Create a base plansubscription_base_plans_batch_update --packageName com.example.app --productId plus_monthly \ --requests '[{"basePlan":{"basePlanId":"monthly","autoRenewingBasePlanType":{"billingPeriodDuration":"P1M","accountHoldDuration":"P30D"},"state":"DRAFT","regionalConfigs":[{"regionCode":"US","price":{"currencyCode":"USD","units":"9","nanos":990000000}}]},"updateMask":"autoRenewingBasePlanType,regionalConfigs"}]'
# 3. Activate the base plansubscription_base_plans_activate --packageName com.example.app \ --productId plus_monthly --basePlanId monthly
# 4. Create a 7-day free-trial offersubscription_offers_create --packageName com.example.app --productId plus_monthly \ --basePlanId monthly --offerId new-user-trial \ --offer '{"phases":[{"duration":"P7D","regionalConfigs":[{"regionCode":"US","free":true}]}],"state":"DRAFT"}'
subscription_offers_activate --packageName com.example.app \ --productId plus_monthly --basePlanId monthly --offerId new-user-trial# For a one-time product (consumable or non-consumable)purchases_products_v2_get --packageName com.example.app --token PURCHASE_TOKEN
# For a subscription — includes 2026 OfferPhase, priceChangeState, etc.purchases_subscriptions_v2_get --packageName com.example.app --token PURCHASE_TOKENreports_crash_rate_query \ --name "apps/com.example.app/crashRateMetricSet" \ --dimensions '["versionCode","countryCode"]' \ --metrics '["crashRate","distinctUsers"]' \ --timelineSpec '{"aggregationPeriod":"DAILY","startTime":{"year":2026,"month":4,"day":1},"endTime":{"year":2026,"month":4,"day":8}}'
reports_errors_issues_search --parent "apps/com.example.app" \ --filter "errorIssueType = \"CRASH\""