---
title: Google Play Linking
description: How to link your Apptonomy project to Google Play Console.
---

Follow this guide to link your Google Play account to Apptonomy.

## Overview

Apptonomy needs permission to read your app's store listing, publish the
localized descriptions and screenshots you approve, and download the daily
reporting CSVs that power your analytics.

There are two ways to grant that permission, and both are fully supported:

- **Keyless linking (recommended)** — you invite an Apptonomy service
  account into your Play Console and grant it a few roles. Nothing is
  downloaded, no key file leaves your machine, and it works even when your
  organization blocks service-account key creation. It takes a couple of
  minutes and needs nothing outside of Play Console, so it's the path we
  recommend for most people.
- **Bring your own key** — you create your own service account in Google
  Cloud, download its JSON key, and upload that key to Apptonomy. This is a
  valid choice when your policies require you to own the credential. It
  needs Google Cloud access, and it isn't available when your organization
  enforces the `iam.disableServiceAccountKeyCreation` policy.

Both flows grant the same roles inside Play Console and give Apptonomy the
same access. Pick whichever fits how your organization manages credentials.

## Keyless linking (recommended)

You grant access to the Apptonomy service account. You never download or
handle a key — you simply invite the account's email into your Play Console
and assign it roles, exactly the way you'd grant a teammate access.

### Prerequisites

- You need the **Owner** or **Manager** role in your Apptonomy organization. See [Members & roles](/docs/team/members-and-roles).
- Access to Google Play Console with an account that has **Admin (all
  permissions)** — you need this to invite a new user and to grant the
  account-level permission that unlocks reporting-bucket access.

You do **not** need Google Cloud (GCP) access for keyless linking.

### I. Copy the Apptonomy service account email

1.  In Apptonomy, start linking your Google Play account. Apptonomy shows
    you the service account email to invite — it ends with
    `iam.gserviceaccount.com`.
2.  Click **Copy** next to the email. Keep it handy; you'll paste it into
    Play Console in the next step.

:::note[The service account has no standing access]
The Apptonomy service account starts with no access to anything. It can
only do what you explicitly grant it inside your Play Console, and you can
revoke that access at any time by removing the user.
:::

### II. Invite the service account into Play Console

This is the only place you grant permissions. Everything Apptonomy
does — reading and writing app metadata, and downloading the reporting
CSVs used for analytics — flows from the roles you set here. You'll set
permissions on **two tabs**.

1.  Go to the [Google Play Console](https://play.google.com/console).
2.  Click **Users & permissions** in the left nav.
3.  Click **Invite new users**.
4.  Paste the Apptonomy service account email you copied in step I
    (it ends with `iam.gserviceaccount.com`).

#### App permissions

5.  Click **Add app** and choose **Select all** (or pick the specific apps
    you want to manage with Apptonomy).
6.  Grant the following roles. They're separate on purpose — Apptonomy
    reads app metadata through the first, uses the second to check write
    access when you link and to publish store-listing changes later, and
    uses the third only to post the review replies you approve:
    - <a id="view-app-information"></a>**View app information** —
      lets Apptonomy read your app's listing, details, and release
      history. This is the minimum role required to link at all.
    - <a id="manage-store-presence"></a>**Manage store presence** —
      lets Apptonomy run the write-access check when you link and, later,
      publish store-listing changes on your behalf.
    - **Reply to reviews** — lets Apptonomy post and edit the replies you
      approve on the User Reviews page. Without it, reviews still load and
      replying stays off. See [Reply to reviews](#reply-to-reviews).
7.  Click **Apply**.

#### Account permissions

<a id="storage-object-viewer"></a>

8.  Switch to the **Account permissions** tab (next to App permissions in
    the same dialog).
9.  Check **View app information and download bulk reports
    (read-only)**. This is the permission that grants the service account
    access to your `pubsite_prod_*` reporting bucket — without it,
    Apptonomy can't sync installs, crashes, ratings, or any of the daily
    CSV-based analytics.
10. Click **Apply**.
11. Click **Invite user**.

:::caution[Why "Account permissions" and not GCS IAM?]
The `pubsite_prod_*` reporting bucket is **owned by Google Play Console
infrastructure**, not by your GCP project. You cannot grant
`Storage Object Viewer` on it from the Cloud Storage browser — the
Permissions tab on the bucket will typically show "Unable to load roles"
because the bucket isn't in any project you administer. Reporting access
is configured exclusively through this Play Console account-level
permission.
:::

:::note[Propagation delay]
Google may take up to **24 hours** to apply new Play Console permissions
to the reporting bucket. If Apptonomy reports a 403 on the bucket
immediately after linking, that's almost always propagation —
re-verify the next day before troubleshooting further.
:::

### III. Tell Apptonomy where to find your reporting bucket

Apptonomy needs the bucket name to know which CSVs to read.

1.  In [Google Play Console](https://play.google.com/console), go to the
    left nav → **Download reports** → **Statistics**.
2.  Click **Copy Cloud Storage URI**.

The URI looks like `gs://pubsite_prod_rev_<developer-id>`. Some older Play
accounts use `gs://pubsite_prod_<developer-id>` without the `rev_`
segment; Apptonomy accepts either form.

3.  Back in Apptonomy, paste this URI (or the bare bucket name) into the
    **Reporting bucket** field.

### IV. Verify access

1.  Back in Apptonomy, click **Verify access**.

Apptonomy uses the invited service account to check that it can read your
listing, that it has write access, that it can reach the reporting bucket,
and that it can reply to reviews. Click **Link** once the listing check
passes; any check that fails names the permission it needs, and the matching
feature stays off until you grant it.

:::note[Why keyless works when key creation is blocked]
Many Google Cloud organizations enforce the
`iam.disableServiceAccountKeyCreation` policy, which blocks the
bring-your-own-key flow below. Keyless linking doesn't create or download
any key — it grants access to an account Apptonomy already manages — so it
works regardless of that policy. This is the main reason we recommend it.
:::

## Reply to reviews {#reply-to-reviews}

The **User Reviews** page lists your app's written reviews from both stores with the reply that is live on each. On Google Play you can post a reply and edit it from Apptonomy. Replies go out through the service account you invited, so it needs the **Reply to reviews** permission on the app (App permissions, step [II](#ii-invite-the-service-account-into-play-console)).

- **Without Reply to reviews,** reviews still load and replying stays off. The Store Link capability check names the missing permission; grant it in Play Console, then click **Verify access** again.
- **Google doesn't let apps delete a reply.** You can edit it as often as you like; the reviewer is notified only of your first reply.
- **Replies are plain text, up to 350 characters.** HTML is removed before the limit is counted.
- **Google's reply API sees only reviews written or changed in the last 7 days.** Older reviews come from the public listing; a few of them may show replying as not available yet until Apptonomy matches them to Google's API at the next refresh or nightly sync.
- **Replies you make in Play Console show up too.** Apptonomy reads every reply on your reviews, wherever it was written.
- **Generate reply** writes a draft in the review's language when you ask for one. Nothing is posted until you press **Post reply**.
- **What visitors see first.** Above the reviews, the page shows the reviews Google Play puts first on your listing in each language and country, in Google's own **Most relevant** order, read from the store with each refresh of the page and each night. A 1- or 2-star review in the first three places is flagged, and you can reply to it right there. After you reply, the page shows if the review changes place or drops out of the reviews shown. Google does not let any developer choose, pin or reorder these reviews: replying in the slot, asking for ratings with the Google Play in-app review prompt, and flagging a review that breaks Google's rules as inappropriate are what an app team can do.
- Replying, editing and generating drafts need a **Pro** plan or above. Every plan can read reviews.

## Troubleshooting

### The service account hasn't been granted access yet

<a id="sa-not-invited"></a>

If Apptonomy reports that **the invited service account hasn't been granted
access yet**, the account either wasn't invited into your Play Console or
wasn't given the roles it needs. To fix it:

1.  Go to [Google Play Console](https://play.google.com/console) →
    **Users & permissions**.
2.  Look for the Apptonomy service account email (it ends with
    `iam.gserviceaccount.com`). If it isn't listed, it was never invited —
    click **Invite new users**, paste the email Apptonomy shows you, and
    follow step [II](#ii-invite-the-service-account-into-play-console)
    again.
3.  If it **is** listed, open it and confirm all three roles are granted:
    **View app information**, **Manage store presence** and **Reply to
    reviews** (App permissions), plus **View app information and download
    bulk reports (read-only)** (Account permissions). Add any that are missing and click
    **Apply** / **Save changes**.
4.  Return to Apptonomy and click **Verify access** again.

If you invited the account only moments ago, give it a minute — new
permissions can take a short while to take effect, and reporting-bucket
access in particular can take up to 24 hours (see the propagation-delay
note above).

## Bring your own key

:::note[When to use this flow]
Bring-your-own-key linking is a good fit when your policies require you to
own the credential. It needs Google Cloud access and involves downloading a
JSON key file. One thing to check first: it's blocked entirely when your
organization enforces the `iam.disableServiceAccountKeyCreation` policy, in
which case use [keyless linking](#keyless-linking-recommended) instead.
:::

With bring-your-own-key linking you create your own service account in
Google Cloud, download its JSON key, and upload that key to Apptonomy.

### Prerequisites

- You need the **Owner** or **Manager** role in your Apptonomy organization. See [Members & roles](/docs/team/members-and-roles).
- Access to the Google Cloud (GCP) console with an account that has
  elevated privileges.
- Access to Play Store Console with an account that has **Admin (all
  permissions)** — you'll need this to grant the account-level permission
  that unlocks reporting-bucket access.

### 1. Enable the Play Store API

This is how Apptonomy talks to the Play Store. It might already be enabled,
so let's check.

1.  Go to the Play Store API page on the Google Cloud Console: [Play Store API](https://console.cloud.google.com/apis/library/androidpublisher.googleapis.com)
2.  Ensure the right project is selected (drop-down, top left).
3.  If you see ![API Enabled in Google Cloud Console](/docs/img/psc/api-enabled.png) then you're good to go.
4.  Otherwise, click ![Enable API button in Google Cloud Console](/docs/img/psc/enable.png)

### 2. Create a service account

1.  Go to the Service Accounts area on the Google Cloud Console: [Service Accounts](https://console.cloud.google.com/iam-admin/serviceaccounts)
2.  Ensure you've selected the right project (the same project as above in _Enable the Play Store API_).
3.  Click ![Create Service Account in Google Cloud Console](/docs/img/psc/create-service-account.png)
4.  Service Account Name: **apptonomy-service-account** (or whatever you want).
5.  Copy the email address and put it somewhere for later — we'll use it
    soon: ![Copy Service Account Email Address](/docs/img/psc/copy-email-address.png)
6.  Click **Done**.

### 3. Create a service account key

1.  Go back to the Service Accounts list and note that you might need to refresh the page to see the newly created account.
2.  Click on the new service account (it has the email address we copied above).
3.  Click on the ![Keys tab in Service Account details](/docs/img/psc/keys.png) tab.
4.  Click **Add key** \> **Create new key**.
5.  Choose Key type **JSON** and click **Create**.
6.  The key file downloads immediately to your computer.

:::caution[Blocked from creating a key?]
If clicking **Create** shows an error like **"Service account key creation
is disabled"**, your Google Cloud organization enforces the
`iam.disableServiceAccountKeyCreation` policy, which prevents key creation
in projects under that organization.

The simplest fix is to use [keyless linking](#keyless-linking-recommended)
instead — it doesn't create a key at all and is unaffected by this policy.

If you specifically need a downloaded key, you have two options:

- **No admin access needed** — create the service account in a GCP project
  that is **not** under the locked-down organization. A personal Google
  account (with its own project outside any organization) works fine. It's
  the service account's **email identity** that you invite into Play
  Console in step [4](#4-add-the-service-account-to-play-store-console) —
  the project that hosts the account is independent of your organization's
  policy, so a key created there is perfectly valid.
- **Have org admin access?** — an **Organization Policy Administrator**
  (`roles/orgpolicy.policyAdmin`) can override the
  `iam.disableServiceAccountKeyCreation` constraint for the relevant
  project or organization, after which you can create the key normally. Ask
  whoever administers your Google Cloud organization.
:::

### 4. Add the service account to Play Store Console

This is where you grant the service account permissions. You'll set
permissions on **two tabs**, exactly as in keyless linking.

1.  Go to the [Google Play Console](https://play.google.com/console).
2.  Click **Users & permissions** in the left nav.
3.  Click **Invite new users**.
4.  Paste the email address you copied above for the service account
    (it ends with `iam.gserviceaccount.com`).
5.  Under **App permissions**, click **Add app**, choose your apps, and
    grant **View app information**, **Manage store presence** and **Reply
    to reviews**, then click **Apply**.
6.  Under **Account permissions**, check **View app information and
    download bulk reports (read-only)**, then click **Apply**.
7.  Click **Invite user**.

The roles here are identical to keyless linking — see the
[App permissions](#app-permissions) and
[Account permissions](#account-permissions) sections above for what each
role unlocks and why the reporting permission can't be set from GCS IAM.

### 5. Tell Apptonomy where to find your reporting bucket

Follow the same steps as keyless linking to copy your **Cloud Storage
URI**, then paste it (or the bare bucket name) into the **Reporting
bucket** field next to the JSON upload in Apptonomy. See
[step III above](#iii-tell-apptonomy-where-to-find-your-reporting-bucket).

### Finished!

Return to Apptonomy, click **Connect Play Store**, and upload the JSON
file.

:::note[Key File Security]
The JSON file contains a key that can be used to access your Play Store account and make changes (e.g. submit screenshots and app store descriptions, etc). Apptonomy treats the JSON key as highly sensitive information. The file is encrypted in the browser before uploading via SSL/TLS then it is re-encrypted and stored according to best practices.

[Read about how Apptonomy secures keys](/docs/store-setup/credential-security)
:::
