> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Get your Chrome Web Store credentials

> Register the $5 Chrome Web Store developer account, create the first listing by hand, and mint the OAuth or service-account credentials that automated submissions need.

This page is part of the Extension.js documentation. Extension.js builds and runs browser extensions from one `manifest.json` for Chrome, Edge, Firefox, and Safari, and stops at the package that `extension build --zip` produces, so the values below feed your own submission tooling.

Automated Chrome Web Store submissions need two identifiers and one credential set:

| Value | What it looks like | Where it comes from |
| - | - | - |
| Extension ID | 32 lowercase letters, for example `abcdefghijklmnopabcdefghijklmnop` | The Developer Dashboard item URL, after the first manual upload |
| Publisher ID | A UUID, for example `f1e2d3c4-0000-4000-8000-a1b2c3d4e5f6` | Your dev console URL: `chrome.google.com/webstore/devconsole/<UUID>` |
| OAuth client ID | Ends in `.apps.googleusercontent.com` | Google Cloud Console credentials page |
| OAuth client secret | Starts with `GOCSPX-` | Generated with the client ID |
| OAuth refresh token | Starts with `1//` | Minted against the client ID, see below |
| Service account JSON | A JSON key file | Google Cloud Console, alternative to the OAuth trio |

You need either the OAuth trio or the service account, not both. When both are configured, the service account wins.

## Prerequisites

<Warning>
  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.
</Warning>

1. Register a developer account at the
   [Chrome Web Store Developer Dashboard](https://chrome.google.com/webstore/devconsole).
   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>`.

Extension.js does not submit to a store, so it never asks you for these
values. This page is the manual path: create the OAuth client yourself and
mint the refresh token yourself.

<Note>
  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`.
</Note>

## Create the OAuth client

1. Create or choose a project in the
   [Google Cloud Console](https://console.cloud.google.com).
2. Enable the
   [Chrome Web Store API](https://console.cloud.google.com/apis/library/chromewebstore.googleapis.com)
   for that project.
3. On the [credentials page](https://console.cloud.google.com/apis/credentials),
   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.

<Warning>
  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.
</Warning>

## 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

<Warning>
  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.
</Warning>

To rotate, mint a new refresh token, or a new service account key, and re-enter
it wherever it is stored.

## Name map

The environment variable each value answers to:

| Value | Env var |
| - | - |
| OAuth client ID | `CHROME_CLIENT_ID` |
| OAuth client secret | `CHROME_CLIENT_SECRET` |
| Refresh token | `CHROME_REFRESH_TOKEN` |
| Service account JSON | `CHROME_SERVICE_ACCOUNT_JSON` |
| Extension ID | `CHROME_EXTENSION_ID` |
| Publisher ID | `CHROME_PUBLISHER_ID` |

## 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](/docs/workflows/store-metadata) so every resubmission copies from
one tracked source.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.