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

> ## Agent Instructions
> Unkey is two separate products. Compute builds, deploys, and runs apps behind a gateway. API Management issues API keys, enforces rate limits, manages identities and permissions, and reports usage. Say which product a page belongs to; a reader can use either without the other.
> Every Unkey API endpoint is an HTTP POST to https://api.unkey.com/v2/{service}.{procedure} with a root key in the Authorization: Bearer header. Root keys are workspace scoped.
> Error codes have the form err:{system}:{category}:{specific} and each has a page at /errors/{system}/{category}/{specific}.
> The word environment means production or preview in Compute. Rate limiting has four meanings on this site; the glossary lists them.

# unkey api environments set-environment-variables

> Create or update the variables of an environment in one atomic call.

<Note>
  You need a root key with the permissions listed on this page. Create one in the dashboard under **Settings > Root Keys**. See [Permission reference](/docs/platform/root-keys/permissions-legacy) for every permission.
</Note>

Create or update variables of an <Tooltip tip="A production or preview environment of a Compute app, not the dashboard label on a key.">environment</Tooltip> in one atomic request.

By default, each variable you send is created or overwritten, and variables you don't mention stay as they are. So you can change one secret without resending the others.

* `--prune` deletes every variable you didn't send. `--prune --variables='[]'` removes them all.
* `kind` defaults to `writeonly`, which can never be read back. Set `"kind":"recoverable"` so `list-environment-variables` can return the value.

Values are encrypted at rest.

## Usage

```bash theme={"system"}
unkey api environments set-environment-variables --project=<project> --app=<app> --environment=<environment> --variables=<json> [--prune]
```

## Flags

<ParamField body="--app" type="string" required>
  App ID or slug.
</ParamField>

<ParamField body="--environment" type="string" required>
  Environment ID or slug.
</ParamField>

<ParamField body="--project" type="string" required>
  Project ID or slug. Both forms resolve to the same project.
</ParamField>

<ParamField body="--prune" type="boolean" default="false">
  Delete every variable not present in `--variables` after the upsert.
</ParamField>

<ParamField body="--variables" type="string" required>
  JSON array of at most 50 variables, each with `key` and `value` and optionally `kind` and `description`, for example `[{"key":"TOKEN","value":"secret"}]`. A key must be a POSIX shell name of at most 256 characters and may appear only once. A value is capped at 16384 UTF-8 bytes, and a description at 255 characters.
</ParamField>

### Shared flags

Every `unkey api` command accepts these; [CLI output and shared flags](/docs/platform/cli/output-and-flags) describes them in full.

<ParamField body="--body" type="string">
  A JSON document sent as the request body instead of building it from the flags above. It is mutually exclusive with the request-building flags, and unknown fields are rejected locally. See [Send a raw body](/docs/platform/cli/output-and-flags#send-a-raw-body).
</ParamField>

<ParamField body="--root-key" type="string">
  Root key for the request. Falls back to `UNKEY_ROOT_KEY`, then to the config file written by `unkey auth login`. See [CLI authentication](/docs/platform/cli/authentication).
</ParamField>

<ParamField body="--api-url" type="string" default="https://api.unkey.com">
  Base URL of the API. Falls back to `UNKEY_API_BASE_URL`. You don't normally need to set it.
</ParamField>

<ParamField body="--config" type="string" default="~/.unkey/config.toml">
  Path of the TOML file that `unkey auth login` writes. Falls back to `UNKEY_CONFIG`.
</ParamField>

<ParamField body="--output" type="string">
  Output format. Falls back to `UNKEY_OUTPUT`. Set `json` to print the full response envelope (`meta` and `data`) for piping; any other value prints the request ID followed by `data`.
</ParamField>

## Required permissions

Your root key needs one of:

* `environment.*.set_environment_variables` (any environment)
* `environment.<environment_id>.set_environment_variables` (a specific environment)

Without a matching permission the API answers 403 and the CLI prints `Permission denied:` followed by the detail. See [Root key permissions](/docs/platform/root-keys/permissions) for the full catalog.

## Examples

Set one variable:

```bash theme={"system"}
unkey api environments set-environment-variables --project=payments --app=payments-api --environment=production --variables='[{"key":"TOKEN","value":"secret"}]'
```

Replace the whole set:

```bash theme={"system"}
unkey api environments set-environment-variables --project=payments --app=payments-api --environment=production --prune --variables='[{"key":"DATABASE_URL","value":"mysql://...","kind":"recoverable"}]'
```

Send the request body as JSON:

```bash theme={"system"}
unkey api environments set-environment-variables --body='{"project":"payments","app":"payments-api","environment":"production","variables":[{"key":"TOKEN","value":"secret"}]}'
```

## API endpoint

The command calls [`POST /v2/environments.setEnvironmentVariables`](/docs/compute/api-reference/environments/set-environment-variables) and prints its response. The request fields carry the same names as the flags in camelCase, which is the shape `--body` expects.

## Related

<Columns cols={1}>
  <Card title="Environment variables" href="/docs/compute/configure/environment-variables">
    Kinds, encryption, and how variables reach a deployment.
  </Card>
</Columns>
