gplay-subscription-localization
Google Play Subscription Localization
Use this skill to bulk-create or bulk-update localized display names, descriptions, and benefits for subscriptions across all Google Play supported locales. This eliminates the tedious manual process of editing each language in Play Console.
Preconditions
- Auth configured (
gplay auth loginorGPLAY_SERVICE_ACCOUNTenv var). - Package name known (
--packageorGPLAY_PACKAGE). - Subscription products already created (use
gplay subscriptions createfirst). - Service account has "Edit and manage your app" permission.
Supported Google Play Locales
These are the locales supported by Google Play for subscription listings:
af, am, ar, hy-AM, az-AZ, eu-ES, be, bn-BD, bg, my-MM, ca,
zh-HK, zh-CN, zh-TW, hr, cs-CZ, da-DK, nl-NL, en-AU, en-CA,
en-GB, en-IN, en-SG, en-US, en-ZA, et, fil, fi-FI, fr-CA,
fr-FR, gl-ES, ka-GE, de-DE, el-GR, gu, he-IL, hi-IN, hu-HU,
is-IS, id, it-IT, ja-JP, kn-IN, kk, km-KH, ko-KR, ky-KG,
lo-LA, lv, lt, mk-MK, ms, ms-MY, ml-IN, mr-IN, mn-MN, ne-NP,
no-NO, fa, pl-PL, pt-BR, pt-PT, pa, ro, rm, ru-RU, sr, si-LK,
sk, sl, es-419, es-ES, es-US, sw, sv-SE, ta-IN, te-IN, th,
tr-TR, uk, ur, vi, zu
Verify which locales your app already supports:
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay listings list --package com.example.app --edit $EDIT_ID --output table
Subscription Structure in Google Play
Google Play subscriptions have a hierarchical structure:
- Subscription: The product itself (e.g., "Premium")
- Listings: Localized display name, description, benefits per locale
- Base Plan: A pricing tier (e.g., "Monthly", "Yearly")
- Offer: Promotional pricing on a base plan (trials, intro prices)
Listings are set at the subscription level and apply to all base plans under it.
Workflow: Bulk-Localize a Subscription
1. List Existing Subscriptions
gplay subscriptions list --package com.example.app --paginate --output table
2. Get Current Subscription Details
gplay subscriptions get \
--package com.example.app \
--product-id premium_monthly \
--output json --pretty
The response includes a listings object keyed by locale:
{
"productId": "premium_monthly",
"listings": {
"en-US": {
"title": "Premium Monthly",
"benefits": ["Unlimited access", "No ads"],
"description": "Get premium access to all features"
}
}
}
3. Prepare Multi-locale Listings JSON
Create a JSON file with listings for all target locales:
subscription-listings.json:
{
"listings": {
"en-US": {
"title": "Premium Monthly",
"benefits": ["Unlimited access", "No ads", "Priority support"],
"description": "Get premium access to all features every month."
},
"de-DE": {
"title": "Premium Monatlich",
"benefits": ["Unbegrenzter Zugang", "Keine Werbung", "Prioritäts-Support"],
"description": "Erhalten Sie jeden Monat Premium-Zugang zu allen Funktionen."
},
"fr-FR": {
"title": "Premium Mensuel",
"benefits": ["Accès illimité", "Sans publicité", "Support prioritaire"],
"description": "Accédez à toutes les fonctionnalités premium chaque mois."
},
"es-ES": {
"title": "Premium Mensual",
"benefits": ["Acceso ilimitado", "Sin anuncios", "Soporte prioritario"],
"description": "Obtén acceso premium a todas las funciones cada mes."
},
"ja-JP": {
"title": "プレミアム月額",
"benefits": ["無制限アクセス", "広告なし", "優先サポート"],
"description": "毎月すべての機能にプレミアムアクセスできます。"
},
"ko-KR": {
"title": "프리미엄 월간",
"benefits": ["무제한 액세스", "광고 없음", "우선 지원"],
"description": "매달 모든 기능에 프리미엄 액세스를 받으세요."
},
"pt-BR": {
"title": "Premium Mensal",
"benefits": ["Acesso ilimitado", "Sem anúncios", "Suporte prioritário"],
"description": "Tenha acesso premium a todos os recursos todos os meses."
},
"zh-CN": {
"title": "高级月度订阅",
"benefits": ["无限访问", "无广告", "优先支持"],
"description": "每月获得所有功能的高级访问权限。"
}
}
}
4. Update Subscription with All Listings
gplay subscriptions update \
--package com.example.app \
--product-id premium_monthly \
--json @subscription-listings.json \
--update-mask listings
The --update-mask listings ensures only the listings field is modified, leaving base plans and other configuration untouched.
5. Verify
gplay subscriptions get \
--package com.example.app \
--product-id premium_monthly \
--output json --pretty
Check that all locales appear in the listings object.
Workflow: Export, Translate, Import
1. Export current subscription data
gplay subscriptions get \
--package com.example.app \
--product-id premium_monthly \
--output json --pretty > subscription-export.json
2. Extract listings for translation
Use jq to isolate the listings:
jq '.listings' subscription-export.json > listings-to-translate.json
3. Send for translation
Send listings-to-translate.json to your translation service or team. The structure is simple key-value pairs per locale.
4. Merge translated listings back
After receiving translations, build the update JSON:
jq -n --slurpfile translations translated-listings.json \
'{ listings: $translations[0] }' > subscription-update.json
5. Import translated listings
gplay subscriptions update \
--package com.example.app \
--product-id premium_monthly \
--json @subscription-update.json \
--update-mask listings
Workflow: Bulk-Localize All Subscriptions in an App
#!/bin/bash
# bulk-localize-subscriptions.sh
PACKAGE="com.example.app"
LISTINGS_FILE="subscription-listings.json"
# Get all subscription product IDs
PRODUCT_IDS=$(gplay subscriptions list \
--package "$PACKAGE" \
--paginate | jq -r '.[].productId')
for PRODUCT_ID in $PRODUCT_IDS; do
echo "Updating listings for: $PRODUCT_ID"
gplay subscriptions update \
--package "$PACKAGE" \
--product-id "$PRODUCT_ID" \
--json "@$LISTINGS_FILE" \
--update-mask listings
echo "Done: $PRODUCT_ID"
done
echo "All subscriptions updated."
For subscriptions with different display names, use per-product JSON files:
for PRODUCT_ID in $PRODUCT_IDS; do
LISTINGS_FILE="listings/${PRODUCT_ID}.json"
if [ -f "$LISTINGS_FILE" ]; then
gplay subscriptions update \
--package "$PACKAGE" \
--product-id "$PRODUCT_ID" \
--json "@$LISTINGS_FILE" \
--update-mask listings
else
echo "Warning: No listings file for $PRODUCT_ID, skipping."
fi
done
Workflow: Localize Subscription with Base Plans and Offers
When creating a new subscription with localized listings and base plans in one call:
gplay subscriptions create \
--package com.example.app \
--product-id premium_yearly \
--json @full-subscription.json
full-subscription.json:
{
"productId": "premium_yearly",
"listings": {
"en-US": {
"title": "Premium Yearly",
"benefits": ["Unlimited access", "No ads", "2 months free"],
"description": "Save with annual premium access."
},
"de-DE": {
"title": "Premium Jährlich",
"benefits": ["Unbegrenzter Zugang", "Keine Werbung", "2 Monate gratis"],
"description": "Sparen Sie mit jährlichem Premium-Zugang."
},
"fr-FR": {
"title": "Premium Annuel",
"benefits": ["Accès illimité", "Sans publicité", "2 mois offerts"],
"description": "Économisez avec l'accès premium annuel."
},
"ja-JP": {
"title": "プレミアム年間",
"benefits": ["無制限アクセス", "広告なし", "2ヶ月無料"],
"description": "年間プレミアムアクセスでお得に。"
}
},
"basePlans": [
{
"basePlanId": "yearly",
"state": "ACTIVE",
"autoRenewingBasePlanType": {
"billingPeriodDuration": "P1Y",
"gracePeriodDuration": "P7D",
"resubscribeState": "RESUBSCRIBE_STATE_ACTIVE",
"prorationMode": "CHARGE_ON_NEXT_BILLING_DATE"
},
"regionalConfigs": [
{
"regionCode": "US",
"price": {
"currencyCode": "USD",
"units": "49",
"nanos": 990000000
}
}
]
}
]
}
Workflow: Localize Offer Tags
Offers support localized offerTags which can be used for display in your app:
gplay offers update \
--package com.example.app \
--product-id premium_monthly \
--base-plan-id monthly \
--offer-id free_trial_7d \
--json @offer-update.json
offer-update.json:
{
"offerTags": [
{"tag": "free-trial"},
{"tag": "7-days"}
]
}
Note: Offer tags are not locale-specific in the Google Play API. They are developer-defined identifiers used for filtering in your app. Localize the user-facing text for offer tags in your app code, not in Play Console.
Validate Locale Codes
Check which locales your app already has store listings for:
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay listings list --package com.example.app --edit $EDIT_ID --output table
This lists all locales with store listings. Your subscription listings should cover at least these same locales.
To see the full list of locales a specific listing supports:
gplay listings list --package com.example.app --edit $EDIT_ID \
| jq -r '.[].language'
JSON Template: Minimal Multi-locale Subscription
Copy and customize this template for quick localization:
{
"listings": {
"en-US": { "title": "TITLE_EN", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_EN" },
"de-DE": { "title": "TITLE_DE", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_DE" },
"fr-FR": { "title": "TITLE_FR", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_FR" },
"es-ES": { "title": "TITLE_ES", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_ES" },
"it-IT": { "title": "TITLE_IT", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_IT" },
"ja-JP": { "title": "TITLE_JA", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_JA" },
"ko-KR": { "title": "TITLE_KO", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_KO" },
"pt-BR": { "title": "TITLE_PT_BR", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_PT_BR" },
"ru-RU": { "title": "TITLE_RU", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_RU" },
"zh-CN": { "title": "TITLE_ZH_CN", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_ZH_CN" },
"zh-TW": { "title": "TITLE_ZH_TW", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_ZH_TW" },
"ar": { "title": "TITLE_AR", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_AR" },
"hi-IN": { "title": "TITLE_HI", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_HI" },
"tr-TR": { "title": "TITLE_TR", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_TR" },
"pl-PL": { "title": "TITLE_PL", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_PL" },
"nl-NL": { "title": "TITLE_NL", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_NL" },
"sv-SE": { "title": "TITLE_SV", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_SV" },
"th": { "title": "TITLE_TH", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_TH" },
"vi": { "title": "TITLE_VI", "benefits": ["BENEFIT_1", "BENEFIT_2"], "description": "DESC_VI" }
}
}
Agent Behavior
- Always list existing subscriptions and their current listings before making changes.
- Use
--update-mask listingswhen updating only localized metadata to avoid overwriting base plans or pricing. - When the user provides a single display name, use it for all locales (same name everywhere).
- When the user provides translated names per locale, use the locale-specific name for each.
- If benefits or description are provided, include them. Otherwise omit them from the JSON.
- Use
--output tablefor verification steps so the user can visually confirm. - Use default JSON output for intermediate automation steps.
- After bulk updates, always get the subscription to verify completeness.
- If an update fails, log the product ID and error, then continue with remaining subscriptions. Report all failures together at the end.
- Always confirm exact flags with
--helpbefore running commands.
Notes
- Subscription listings are updated atomically per subscription: one
updatecall sets all locales at once. - Unlike App Store Connect, Google Play does not require separate create calls per locale. The listings object is a single JSON field.
- The
--update-maskflag is critical: without it, an update call may overwrite base plans and pricing. - Title max length: 55 characters. Benefits max: 4 items. Description max: 80 characters.
- Use
--paginateon list commands to ensure all subscriptions are returned. - Use
--prettywhen inspecting JSON output for human readability. - Always use
--helpto verify flags for the exact command.
More from tamtom/gplay-cli-skills
gplay-cli-usage
Guidance for using the Google Play Console CLI in this repo (flags, output formats, pagination, auth, and discovery). Use when asked to run or design gplay commands or interact with Google Play Console via the CLI.
108gplay-gradle-build
Build, sign, and package Android apps with Gradle before uploading to Google Play. Use when asked to create an APK or AAB, configure signing, or set up build pipelines.
95gplay-submission-checks
Pre-submission validation for Google Play releases covering metadata, screenshots, bundle integrity, data safety, and policy compliance. Use when preparing a release to avoid rejections and catch issues before submitting.
93gplay-metadata-sync
Metadata and localization sync (including Fastlane format) for Google Play Store listings. Use when updating app descriptions, screenshots, or managing multi-locale metadata.
93gplay-signing-setup
Android app signing, keystores, and Play App Signing setup. Use when configuring signing for new apps or migrating to Play App Signing.
91gplay-iap-setup
In-app products, subscriptions, base plans, and offers setup for Google Play monetization. Use when configuring in-app purchases or subscription products.
89