Skip to main content
Automated Chrome Web Store submissions need two identifiers and one credential set: You need either the OAuth trio or the service account, not both. When both are configured, the service account wins.

Prerequisites

The Chrome Web Store API cannot create a new item. The first upload of a new extension must happen by hand in the Developer Dashboard. The 32-character extension ID only exists after that upload.
  1. Register a developer account at the Chrome Web Store Developer Dashboard. Registration has a one-time $5 fee.
  2. Build a store zip (npx extension build --browser chrome --zip).
  3. Upload that zip manually in the dashboard to create the item.
  4. Copy the extension ID from the item’s dashboard URL.
  5. Copy the publisher ID: it is the UUID in your dev console URL, chrome.google.com/webstore/devconsole/<UUID>.

The easy path: hold the credentials once, on the platform

Extension.js does not submit to a store, so it never asks you for these values. If you would rather not carry them yourself, hand them to extension.dev once per project and let the platform run the submission. It accepts a service account key instead of an OAuth client, which is the better default because a service account does not expire with a person’s session. See Chrome Web Store credentials. The rest of this page is the manual path: create the OAuth client yourself and mint the refresh token yourself.
Do not use the Google OAuth Playground to mint the refresh token. The Playground requires a Web application client with its redirect URI, and the Chrome Web Store flow requires a Desktop app client. Combining them fails with redirect_uri_mismatch.

Create the OAuth client

  1. Create or choose a project in the Google Cloud Console.
  2. Enable the Chrome Web Store API for that project.
  3. On the credentials page, create an OAuth client ID with application type Desktop app. A Web application client does not work here.
  4. Copy the client ID and the client secret.
  5. Mint a refresh token for that client with a loopback consent flow on 127.0.0.1, which is the redirect a Desktop app client accepts. The token must authorize the https://www.googleapis.com/auth/chromewebstore scope. A service account skips this step, and the next section covers it.
If your OAuth consent screen is in Testing status, Google revokes the refresh token after 7 days. Your first submission works and the credential dies a week later. Publish the consent screen (In production), or use a service account, which has no such expiry.

Alternative: a service account

A Google Cloud service account avoids OAuth consent entirely and is the most stable choice for CI:
  1. In the Google Cloud Console, create a service account in the same project that has the Chrome Web Store API enabled.
  2. Create a JSON key for it and download the file.
  3. In the Chrome Web Store dev console, open Account and add the service account’s email address to your publisher. One service account per publisher.
Provide the JSON key content (or a path to the file) as the credential. When a service account is configured, it is preferred over the OAuth trio.

Blast radius and rotation

Chrome credentials are publisher-wide, not per extension. A token that can publish one item can publish every item under the same publisher account. Treat the refresh token and the service account key accordingly, and prefer a separate publisher account per client if you manage extensions for others.
To rotate, mint a new refresh token, or a new service account key, and re-enter it wherever it is stored. Saved platform secrets are write-only, so rotation always means re-entering the value.

Name map

The same values wear different names on each surface:

Listing metadata stays manual

The Chrome Web Store API accepts no listing metadata. Store listing copy, screenshots, and permission justifications are entered in the Developer Dashboard by hand. Keep them in the Chrome section of STORE.md so every resubmission copies from one tracked source.