Google Play API 401 and 403: IAM is not Play Console permissions

A 401 from the Play Developer API means Google would not accept your credentials at all. A 403 means it accepted them and then refused the action.

The single most common cause of a 403 is granting your service account roles in Google Cloud IAM and expecting Play Console to care. It does not. They are two separate permission systems, and only one of them decides what your service account can do to your apps.

Two systems, one email address

Your service account has one email, something like releases@my-project.iam.gserviceaccount.com, and it appears in two different places:

Google Cloud IAM controls the service account as a resource: who can create keys for it, who can impersonate it, which APIs the project may call. Roles here are things like Owner, Editor, Service Account User.

Play Console, under Users and permissions controls what that email may do to your developer account and your apps. Permissions here are checkboxes with names like "Manage store presence".

Giving the service account Owner in IAM grants it nothing on Google Play. Owner is about the Cloud project. Play Console has never heard of it.

This is why the classic report reads "I gave the service account full admin and I still get The caller does not have permission". Full admin where? If the answer is IAM, the 403 is expected.

Getting a 401 sorted first

A 401 rarely has anything to do with permissions. Work through these in order:

  1. The API is not enabled. Enable the Google Play Android Developer API in the Cloud Console for the project that owns the service account. A disabled API refuses the token before any permission check happens.
  2. Wrong scope. The token must be minted for https://www.googleapis.com/auth/androidpublisher. Any other scope, or none, fails at the door.
  3. The key was revoked or the service account deleted. Keys can be deleted from under a running system without anything telling the system.
  4. Server clock skew. Service account auth signs a JWT with iat and exp timestamps. A host whose clock has drifted by more than a few minutes produces tokens Google will not accept. This one is easy to miss because everything else looks fine.
  5. The wrong JSON key file. Two projects, two credentials.json files, one of them for a service account that was never invited to Play Console.

You no longer need to link your developer account to a Google Cloud project to use the API, so that step being missing is not the problem it used to be.

The permissions a 403 is actually asking for

Once authentication works, the 403 is about the checkboxes. In Play Console: Users and permissions, find the service account email, open its permissions.

The three that matter for publishing:

  • "Manage store presence" covers editing store listings, pricing, in-app products and promotional content. Every listing write and every screenshot upload needs it.
  • "Release apps to testing tracks" lets the account upload drafts and create releases on test tracks. Google's own description is blunt about the limit: "This permission doesn't allow users to publish apps to production on Google Play."
  • "Release to production, exclude devices, and use Play App Signing" allows creating, editing and rolling out production releases, plus unpublishing and republishing apps.

Those last two being separate is the source of a specific and confusing failure: internal deliveries succeed and production promotion is refused. Your pipeline works for weeks against the internal track, you promote to production for the first time, and Google 403s. Nothing changed. The second checkbox was never ticked.

If your tooling only ever writes to test tracks, you will never discover the gap until the release that matters.

Account level versus app level

Play Console permissions can be granted account-wide or per app, and Google is explicit that some permissions only exist at one level. A user cannot hold the same permission at both levels; you pick the scope.

The practical consequence: a service account granted permissions on App A returns 403 for App B, with an error that names the operation rather than the app. If you have several apps under one developer account, check the grant is where you think it is. App-level grants are the safer default and the easier one to get wrong.

Propagation delay

Permission changes are not always instant. After ticking a box and saving, an API call can keep failing for a while.

Google does not document how long. Anyone quoting you a specific number is guessing, and the numbers people quote range from seconds to 24 hours.

What to do about it: after changing permissions, wait a few minutes and retry once before you start changing anything else. The failure mode you want to avoid is editing four settings in five minutes and then having no idea which one fixed it.

Diagnosing in order

  1. Read the status code. 401 is credentials, 403 is permissions. They have almost no overlap in cause, and treating them as one thing wastes an afternoon.
  2. Read the message body, not just the code. Google's 403 bodies often name the operation or say The caller does not have permission. Some 403s are not permission problems at all: a commit refused because changes cannot be auto-sent for review comes back as a 403 or 400 mentioning changesNotSentForReview, and the fix is a query parameter, not a checkbox.
  3. Confirm the email. Copy the service account email out of your JSON key file and confirm that exact string appears in Play Console's user list. Two similar service accounts in one project is a common trap.
  4. Confirm the app. Account-level or app-level, and if app-level, this app.
  5. Confirm the specific checkbox for the operation that failed. Listing push wants store presence. Test track delivery wants testing tracks. Production promotion wants the production line.
  6. Wait, then retry once. Only then start changing things.

What a good error should tell you

A raw Play API 403 on /applications/com.example.app/edits/11778524653622734947/tracks/production tells a stranded user nothing they can act on. The same failure said properly names the missing checkbox, the console page it lives on, and the fact that testing and production are separate grants.

AppSubmit maps this error onto that guide and shows the Play Console screen with the right box circled, because the difference between the two release permissions is not guessable from Google's error text. The permission names above are the same ones you would tick by hand.

Read next

Last reviewed 2026-08-17. Apple and Google change their rules without notice, so check anything decision-critical against their live documentation.