---
title: Environment variables | Runware Docs
url: https://runware.ai/docs/serverless/api-environment-variables
description: Read and write the environment an application's workers run with.
relatedDocuments:
  - https://runware.ai/docs/serverless/api
  - https://runware.ai/docs/serverless/environment-variables
  - https://runware.ai/docs/serverless/secrets
---
## Introduction

An app's environment is **part of the version snapshot its workers are rendered from**, so writing a variable is not an in-place edit. A write that changes the stored value records a new version carrying the same image and **rolls the app**, and a write that leaves the value unchanged records nothing at all.

> [!WARNING]
> A write while a rollout is **still in flight returns `409` and is discarded**, so setting several variables one at a time is that many sequential rollouts. Replace the whole set in one request with `PATCH /v1/apps/{appId}` instead. See [Environment variables](https://runware.ai/docs/serverless/environment-variables).

## List environment variables

GETapi.serverless.runware.ai/v1/apps/{appId}/environment-variables

### [Request](#list-app-environment-variables-request)

Path

### [appId](#list-app-environment-variables-path-appid)

- **Type**: `string`
- **Required**: true
- **Min**: `6`
- **Max**: `30`

Immutable app identifier, unique among the authenticated organization's live apps.

Query

### [limit](#list-app-environment-variables-query-limit)

- **Type**: `integer`
- **Format**: `int32`
- **Min**: `1`
- **Max**: `100`
- **Default**: `20`

Maximum number of items to return.

### [cursor](#list-app-environment-variables-query-cursor)

- **Type**: `string`

Opaque pagination cursor returned by a previous call, as `nextCursor` or, on the operations that offer one, `prevCursor`.

### [Response](#list-app-environment-variables-response)

### [nextCursor](#list-app-environment-variables-response-nextcursor)

- **Type**: `string (nullable)`

Cursor for the next page. Null when there are no more items.

### [data](#list-app-environment-variables-response-data)

- **Type**: `object[] (6 properties)`

#### [id](#list-app-environment-variables-response-data-id)

- **Type**: `string (uuid)`
- **Format**: `UUID v4`

#### [appId](#list-app-environment-variables-response-data-appid)

- **Type**: `string`
- **Min**: `6`
- **Max**: `30`

Immutable app identifier. Unique among the authenticated organization's live apps: it cannot be changed after creation, and it becomes available again once the app it named reaches `deleted`.

#### [key](#list-app-environment-variables-response-data-key)

- **Type**: `string`
- **Required**: true
- **Min**: `1`
- **Max**: `128`

POSIX-style environment variable name. Letters, digits, and underscore. Must start with a letter or underscore. Matched by the `deployment_configs` column CHECK so a valid-by-contract request cannot 500 at INSERT.

#### [value](#list-app-environment-variables-response-data-value)

- **Type**: `string`
- **Required**: true

#### [createdAt](#list-app-environment-variables-response-data-createdat)

- **Type**: `string (date-time)`
- **Format**: `date-time`

#### [updatedAt](#list-app-environment-variables-response-data-updatedat)

- **Type**: `string (date-time)`
- **Format**: `date-time`

### [Errors](#list-app-environment-variables-errors)

<table><tbody><tr><td data-rw-cid-pz7tphoj="true">Status</td><td data-rw-cid-pz7tphoj="true">When</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">400</code></td><td data-rw-cid-pz7tphoj="true">The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns <code class="component-Code">422</code> instead.</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">401</code></td><td data-rw-cid-pz7tphoj="true">Missing or invalid credentials</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">404</code></td><td data-rw-cid-pz7tphoj="true">Resource not found</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">422</code></td><td data-rw-cid-pz7tphoj="true">The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns <code class="component-Code">400</code>. The <code class="component-Code">errors</code> array carries one entry per offending field.</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">500</code></td><td data-rw-cid-pz7tphoj="true">Unexpected server error</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">503</code></td><td data-rw-cid-pz7tphoj="true">A required service is temporarily unavailable</td></tr></tbody></table>

## Update an environment variable

PUTapi.serverless.runware.ai/v1/apps/{appId}/environment-variables/{variableName}

Sets one environment variable, creating it if absent. Names the platform sets on the serving container itself are rejected with `422`, as they are on create. A write that changes the stored value records a new version carrying the live environment set and the same image. If that image is deployable, the write pins it as `activeVersionId` and rolls the workload when the app can take one (`active`, `initializing`, or `failed` which becomes `initializing`). A `stopped` or `stopping` app pins the version and rolls it on `resume`. A write that leaves the stored value unchanged records no version and does not roll. A write while a rollout of this app is still in flight, or to a `failed` app while the workers of its failed rollout are still stopping, returns `409 Conflict` and does not store the value. Each changing write is serialised behind that rollout, so setting several variables one at a time is that many sequential rolls with `409`s between them. Replace the whole set in one request with `PATCH /v1/apps/{appId}` `environmentVariables`. An app holds at most 100 environment bindings in total, plain variables plus attached secrets, the same combined ceiling `AppCreate.environmentVariables` declares (create rejects secrets in-request, attach grows the set later). Overwriting an existing variable is always allowed. Adding one past the ceiling returns `422`. The name must not collide with a secret already attached to this app (the secret's injected env var name). Secrets and plain env vars share the pod environment. A duplicate would be resolved last-wins by kubelet with no error, so the server rejects it with `422`. The reverse check applies on attach.

### [Request](#update-app-environment-variable-request)

Path

### [appId](#update-app-environment-variable-path-appid)

- **Type**: `string`
- **Required**: true
- **Min**: `6`
- **Max**: `30`

Immutable app identifier, unique among the authenticated organization's live apps.

### [variableName](#update-app-environment-variable-path-variablename)

- **Type**: `string`
- **Required**: true
- **Min**: `1`
- **Max**: `128`

POSIX-style environment variable name. Letters, digits, and underscore. Must start with a letter or underscore. Matched by the `deployment_configs` column CHECK so a valid-by-contract request cannot 500 at INSERT.

Body

### [value](#update-app-environment-variable-body-value)

- **Type**: `string`
- **Required**: true
- **Max**: `4096`

Value delivered to the workload as this variable's value. Bounded because every variable ends up in the pod template, which as a whole has to fit what the Kubernetes API server accepts. The same `maxLength` create applies, so one path cannot be used to exceed the other.

### [Response](#update-app-environment-variable-response)

### [id](#update-app-environment-variable-response-id)

- **Type**: `string (uuid)`
- **Format**: `UUID v4`

### [appId](#update-app-environment-variable-response-appid)

- **Type**: `string`
- **Min**: `6`
- **Max**: `30`

Immutable app identifier. Unique among the authenticated organization's live apps: it cannot be changed after creation, and it becomes available again once the app it named reaches `deleted`.

### [key](#update-app-environment-variable-response-key)

- **Type**: `string`
- **Required**: true
- **Min**: `1`
- **Max**: `128`

POSIX-style environment variable name. Letters, digits, and underscore. Must start with a letter or underscore. Matched by the `deployment_configs` column CHECK so a valid-by-contract request cannot 500 at INSERT.

### [value](#update-app-environment-variable-response-value)

- **Type**: `string`
- **Required**: true

### [createdAt](#update-app-environment-variable-response-createdat)

- **Type**: `string (date-time)`
- **Format**: `date-time`

### [updatedAt](#update-app-environment-variable-response-updatedat)

- **Type**: `string (date-time)`
- **Format**: `date-time`

### [Errors](#update-app-environment-variable-errors)

<table><tbody><tr><td data-rw-cid-pz7tphoj="true">Status</td><td data-rw-cid-pz7tphoj="true">When</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">400</code></td><td data-rw-cid-pz7tphoj="true">The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns <code class="component-Code">422</code> instead.</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">401</code></td><td data-rw-cid-pz7tphoj="true">Missing or invalid credentials</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">403</code></td><td data-rw-cid-pz7tphoj="true">Authenticated but not permitted to access this resource</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">404</code></td><td data-rw-cid-pz7tphoj="true">Resource not found</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">409</code></td><td data-rw-cid-pz7tphoj="true">Resource already exists or the request conflicts with its current state</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">413</code></td><td data-rw-cid-pz7tphoj="true">The request body exceeds its size limit: 10 MiB on <code class="component-Code">invoke-sync</code> and <code class="component-Code">invoke-async</code>, whose body carries the endpoint's payload, and 1 MiB on the other operations that answer with this response. <code class="component-Code">detail</code> names the limit in bytes.</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">415</code></td><td data-rw-cid-pz7tphoj="true">The request body arrived with a Content-Type this operation does not accept. The body was not decoded, so this is not a schema failure. A body of <code class="component-Code">application/json</code> that cannot be parsed returns <code class="component-Code">400</code>. One that parses and breaks the schema returns <code class="component-Code">422</code>. A body sent with no Content-Type is the same refusal.</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">422</code></td><td data-rw-cid-pz7tphoj="true">The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns <code class="component-Code">400</code>. The <code class="component-Code">errors</code> array carries one entry per offending field.</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">500</code></td><td data-rw-cid-pz7tphoj="true">Unexpected server error</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">503</code></td><td data-rw-cid-pz7tphoj="true">A required service is temporarily unavailable</td></tr></tbody></table>

## Delete an environment variable

DELETEapi.serverless.runware.ai/v1/apps/{appId}/environment-variables/{variableName}

Removes one environment variable. A successful delete records a new version carrying the remaining environment set and the same image. If that image is deployable, the delete pins it as `activeVersionId` and rolls the workload when the app can take one (`active`, `initializing`, or `failed` which becomes `initializing`). A `stopped` or `stopping` app pins the version and rolls it on `resume`. A delete of a key that is present while a rollout of this app is still in flight, or while the workers of a `failed` app's failed rollout are still stopping, returns `409 Conflict` and does not remove the value. A name that is not present returns `404` even during that window.

### [Request](#delete-app-environment-variable-request)

Path

### [appId](#delete-app-environment-variable-path-appid)

- **Type**: `string`
- **Required**: true
- **Min**: `6`
- **Max**: `30`

Immutable app identifier, unique among the authenticated organization's live apps.

### [variableName](#delete-app-environment-variable-path-variablename)

- **Type**: `string`
- **Required**: true
- **Min**: `1`
- **Max**: `128`

POSIX-style environment variable name. Letters, digits, and underscore. Must start with a letter or underscore. Matched by the `deployment_configs` column CHECK so a valid-by-contract request cannot 500 at INSERT.

### [Errors](#delete-app-environment-variable-errors)

<table><tbody><tr><td data-rw-cid-pz7tphoj="true">Status</td><td data-rw-cid-pz7tphoj="true">When</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">401</code></td><td data-rw-cid-pz7tphoj="true">Missing or invalid credentials</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">403</code></td><td data-rw-cid-pz7tphoj="true">Authenticated but not permitted to access this resource</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">404</code></td><td data-rw-cid-pz7tphoj="true">Resource not found</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">409</code></td><td data-rw-cid-pz7tphoj="true">Resource already exists or the request conflicts with its current state</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">422</code></td><td data-rw-cid-pz7tphoj="true">The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns <code class="component-Code">400</code>. The <code class="component-Code">errors</code> array carries one entry per offending field.</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">500</code></td><td data-rw-cid-pz7tphoj="true">Unexpected server error</td></tr><tr><td data-rw-cid-pz7tphoj="true"><code data-rw-cid-pz7tphoj="">503</code></td><td data-rw-cid-pz7tphoj="true">A required service is temporarily unavailable</td></tr></tbody></table>