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

# SDK keys, management API keys, and service account tokens

> Which shipd credential to use where: server SDK key vs client SDK key, CLI keys, and CI tokens.

## Overview

shipd has three kinds of credentials. **SDK keys** read flags from the edge (data plane). **Management API keys** and **service account tokens** change flags through the control plane. A credential for one plane never works on the other.

## At a glance

| Credential | Prefix | Plane | Where you create it | Bound to | Safe in a browser? | Used by |
| - | - | - | - | - | - | - |
| Server SDK key | `shipd_sdk_server_` | Data plane (`edge.useshipd.com`) | Project → **SDK keys** → **Create SDK key**, **Key type** `server` | One environment | No | `shipdit` on Node.js, Workers, server-side Next.js, [Convex](/sdks/convex) |
| Client SDK key | `shipd_sdk_client_` | Data plane (`edge.useshipd.com`) | Project → **SDK keys** → **Create SDK key**, **Key type** `client` | One environment | Yes | `shipdit/client`, `shipdit/client/react` |
| Management API key | `shipd_mgmt_` | Control plane (`api.useshipd.com`) | `shipd login`, or **Settings → API keys** → **Create key** | One organization, project, and environment | No | The `shipd` CLI on your machine |
| Service account token | `shipd_sa_` | Control plane (`api.useshipd.com`) | **Settings → Service accounts** → **Create service account** → **Create token** | Explicit scopes, optional project or environment binding, optional expiry | No | CI and other automation |

SDK keys are created for the environment that is active in the dashboard when you click **Create SDK key**. Every key is shown once; copy it before you close the dialog.

## Server SDK key vs client SDK key

Use a **server SDK key** when the code runs on infrastructure you control. Use a **client SDK key** when the code ships to a user's device.

| | Server SDK key | Client SDK key |
| - | - | - |
| Runs in | Your servers, Workers, route handlers, server components, Convex | Browser bundles, React client components, mobile apps |
| Can be public | No. Keep it in a server-only secret. | Yes. It is expected to be visible in the bundle. |
| Snapshot contents | Full snapshot, including targeting rules | Currently the same as server keys. Reduced client snapshots are planned. |
| Identity trait overlay (`GET /sdk/v1/identity`) | Yes | No |
| Automatic location traits | No. Pass traits yourself. | Yes. `country`, `region`, `city`, and `timezone` from the edge. |

Because client keys currently receive the full snapshot, anyone with the client key can read your targeting rules and flag values. Do not put secrets in flag values or rule conditions.

## Which credential should I use?

| You want to | Use |
| - | - |
| Evaluate flags in a Node.js server, Worker, or Convex function | Server SDK key |
| Evaluate flags in the browser or in React client components | Client SDK key |
| Run `shipd push`, `pull`, or `diff` from your laptop | Management API key, created by `shipd login` |
| Run `shipd push` or `diff` in GitHub Actions or another CI system | Service account token in `SHIPD_API_KEY` |
| Call the [control-plane API](/reference/control-plane-api) from a script | Service account token |

The CLI reads `SHIPD_API_KEY` for both management API keys and service account tokens. See [Sync flags in CI](/config-as-code/ci) and [Create a service account](/enterprise/service-accounts).

## Rotate or revoke a credential

| Credential | How to rotate |
| - | - |
| SDK key | Create a new key for the same environment, deploy it, then click **Revoke** on the old key. Apps still using the old key keep their last good snapshot and report a `401` to `onError`. |
| Management API key | Revoke it on **Settings → API keys** (admin or owner), then run `shipd login` again. |
| Service account token | Create a new token, update your CI secret, then revoke the old token. Disable the service account to invalidate all of its tokens at once. See [Service account tokens](/reference/service-account-tokens). |

Revocation fails closed on the edge as soon as it propagates; open WebSocket connections are revalidated at least every 60 seconds. See [Edge API](/reference/edge-api).

A management API key is checked against its creator's current role and project access on every use. If the creator loses access, the key stops working.

## Common mistakes

> **A server SDK key in the browser bundle**
>
> Any key in client code is public. If you put a `shipd_sdk_server_` key in a browser bundle (for example, in a `NEXT_PUBLIC_` environment variable), revoke it and create a client key for the browser. Keep the server key in a server-only secret.

> **A management API key as the SDK key**
>
> `createClient({ sdkKey: "shipd_mgmt_…" })` fails: the edge returns `401` for any credential that is not an SDK key. Create an SDK key on the project's **SDK keys** page.

> **An SDK key for the CLI**
>
> `SHIPD_API_KEY=shipd_sdk_…` fails with `401 unauthenticated`: SDK keys only work on the edge. Run `shipd login` locally, or use a service account token in CI.

> **An SDK key from a different environment**
>
> Each SDK key reads exactly one environment. If flags show staging values in production, check that the key was created with the production environment active.

## Related

* [Organizations, projects, environments](/concepts/environments)
* [Organizations and access control](/enterprise/access-control)
* [Edge API](/reference/edge-api)
* [Troubleshooting](/resources/troubleshooting)


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