Skip to content
Coritan Docs

Set environment variables

Give an app settings and secrets as environment variables for its build, its replicas or both, and apply them with a deployment.

View as Markdown

Environment variables give an app its settings and secrets, such as a database address or a key for another service. Each variable reaches the build, the running app or both. You set them on the app's Environment tab or through the API. Once you save a value, neither the dashboard nor the API shows it again.

  • For an organization's app, you need the owner or admin role in the organization to change variables. Every member can see their names.
  • A change reaches the app with its next deployment (Apply a change).
  1. Open the app from Apps in the dashboard and select the Environment tab.
  2. Select Add variable….
  3. In Name, type the name, such as DATABASE_URL. In Value, type or paste the value.
  4. Leave Secret ticked to hide the value in build logs, or untick it for a plain value (Secret and plain values).
  5. In Available at, choose Build and runtime, Runtime only or Build only (Where a variable reaches). For an image app, it starts at Runtime only.
  6. Select Add variable.

A message confirms DATABASE_URL added., and a note under the app's header says which kind of deployment applies it.

To give a variable a new value, open the menu at the end of its row and select Replace value…. Type the new value, change Secret or Available at if you need to, and select Save variable. Leave Value empty to keep the saved value while you change the other two. A message confirms DATABASE_URL saved.

A name cannot change. To rename a variable, delete it and add it again.

To delete a variable, select Delete variable… in its menu, then Delete variable to confirm. A message confirms DATABASE_URL deleted. Running replicas keep the variable until the next deployment, and the value cannot be recovered.

Name
The variable's name, and Secret, hidden in build logs or Plain.
Value
•••• shop for a value of eight characters or more, where shop is its last four characters, or Sealed for a shorter one.
Available at
Build and runtime, Runtime only or Build only.
Updated
When the variable last changed.

The card says how many variables the app has out of its limit, such as 12 of 200 variables. Values are sealed and never shown again. With more than six, Search variables finds them by name.

A name has upper-case letters, digits and underscores, does not start with a digit, and has at most 128 characters, such as DATABASE_URL. These names are set by the platform, so you cannot use them:

  • PORT, TZ, STARTUP, SERVER_MEMORY, SERVER_IP and SERVER_PORT
  • any name that starts with CORITAN_ or P_SERVER_

A value can be empty, and holds up to 32 KiB. The dashboard does not save an empty value, so set one through the API. An app has up to 200 variables, and their names and values together hold up to 256 KiB.

Each variable has a target:

Build and runtime
The build and every replica get it. New variables have this target unless you choose another.
Runtime only
Only the replicas get it.
Build only
Only the build gets it. Builds explains how a Railpack build and a Dockerfile build read it.

An image app is not built, so only the variables its replicas get reach it. Every replica also gets PORT and the CORITAN_ variables (What your app must do).

A variable is secret unless you say otherwise. A secret value of six characters or more appears as [redacted] in the build log, and a Dockerfile build gets it as a build secret instead of a build argument. A plain value can appear in the build log as it is.

Both kinds are stored encrypted, and neither is ever shown again after you save it. For a value of eight characters or more, the variable shows its last four characters, so you can tell which value is saved. To change a value, replace it.

Replicas keep the variables they started with. After you change a variable:

  • For one that the running app reads, redeploy the app.
  • For one that the build reads, redeploy with a rebuild, so the build runs again.

Redeploy shows both. In the dashboard, a note under the app's header says which one: A redeploy applies the saved changes, or A new build applies the saved changes for a variable the build reads. Its Redeploy… button starts it. Through the API, the answer to each change says redeploy_required when a redeploy is needed.

Rarely, a saved value can no longer be opened on the platform, and the variable is marked as not readable. The running app starts without it, and a build that needs it fails with The build variable API_KEY cannot be read on this platform. Save it again. Set the variable again with its value.

In the dashboard, the Environment tab says One variable cannot be read, and the variable's value reads Unreadable, set it again. Select Set again… in its menu, type the value, and select Save variable.

The Environment tab lists each name with where it is available, whether it is secret, and the hint of its value. The next deployment uses them.

Use upper-case letters, digits and underscores, not starting with a digit, such as DATABASE_URL. or 'database_url' is not a variable name: upper-case letters, digits and underscores, not starting with a digit, at most 128 characters
Change the name, for example to DATABASE_URL.
PORT is set by the platform. Choose another name. or PORT is set by the platform and cannot be changed
The platform sets that name on every replica. Use another name, and read PORT to know where to listen.
API_KEY needs a value
A new variable was saved without a value. Give it one.
The environment is larger than 256 KiB in total
Shorten or delete some values. A large file is better kept in Object Storage and fetched when the app starts.
A variable does not change in the running app
Replicas keep the variables they started with. Redeploy the app, with a rebuild for a variable the build reads.

For an organization's app, send the same requests under /api/v1/orgs/{org_slug}/apps (organization apps reference). In each request, target is both, runtime or build.

GET /api/v1/client/apps/{app_uuid}/env lists the variables by name, without their values:

Shell
curl https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21/env \
  -H "Authorization: Bearer $CORITAN_TOKEN"
JSON
{
  "vars": [
    {
      "key": "DATABASE_URL",
      "secret": true,
      "target": "runtime",
      "value": null,
      "hint": "shop",
      "readable": true,
      "created_at": "2026-09-20T09:12:00Z",
      "updated_at": "2026-09-24T16:40:00Z"
    },
    {
      "key": "NODE_ENV",
      "secret": false,
      "target": "both",
      "value": null,
      "hint": null,
      "readable": true,
      "created_at": "2026-09-20T09:12:00Z",
      "updated_at": "2026-09-20T09:12:00Z"
    }
  ]
}

value is always null. hint is the last four characters of a value of eight characters or more, and null otherwise. readable is false when the saved value can no longer be opened.

PUT /api/v1/client/apps/{app_uuid}/env/{key} creates the variable or changes it. The body takes value, secret and target. A new variable needs value. For one that exists, leave value out to keep the saved value while you change secret or target.

Shell
curl -X PUT https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21/env/STRIPE_KEY \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value": "sk_live_EXAMPLE0000", "target": "runtime"}'
JSON
{
  "var": {"key": "STRIPE_KEY", "secret": true, "target": "runtime", "value": null, "hint": "0000", "readable": true},
  "created": true,
  "redeploy_required": true
}

created is true for a new variable. The example shortens var.

PUT /api/v1/client/apps/{app_uuid}/env sets up to 200 variables in one request. Each item in vars has a key and the same value, secret and target as above. With "replace": true, every variable not in the list is deleted.

Shell
curl -X PUT https://api.coritan.com/api/v1/client/apps/3c9e2f4a-8b1d-4f6e-a2c7-5d8b9e0f1a21/env \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"vars": [{"key": "NODE_ENV", "value": "production", "secret": false}, {"key": "DATABASE_URL"}], "replace": true}'
JSON
{
  "created": [],
  "updated": ["NODE_ENV"],
  "deleted": ["STRIPE_KEY"],
  "redeploy_required": true
}

created, updated and deleted name the variables the request touched. DATABASE_URL kept its value because the request left value out. The answer also holds vars, every variable after the change, as in the list above.

DELETE /api/v1/client/apps/{app_uuid}/env/{key} deletes one variable and answers {"deleted": "STRIPE_KEY", "redeploy_required": true}. Running replicas keep it until the next deployment.

Status detail Cause
404 Variable not found The app has no variable with that name.
422 {"message": "PORT is set by the platform and cannot be changed", "field": "key"} The name is one the platform sets.
422 {"message": "API_KEY needs a value", "field": "value"} A new variable came without value.
422 {"message": "The value of API_KEY is larger than 32 KiB", "field": "value"} The value is too long.
422 {"message": "API_KEY appears twice", "field": "key"} vars names one variable twice.
422 An app can have at most 200 variables The change would leave the app with more than 200.
422 The environment is larger than 256 KiB in total The names and values would hold more than 256 KiB.

API operations on this page

MethodPathWhat it does
GET/api/v1/client/apps/{app_uuid}/envList an app's environment variables without their values
PUT/api/v1/client/apps/{app_uuid}/envSet many variables; a variable given without value keeps its saved one
PUT/api/v1/client/apps/{app_uuid}/env/{key}Set one environment variable, creating it when it is new
DELETE/api/v1/client/apps/{app_uuid}/env/{key}Delete one environment variable
GET/api/v1/orgs/{org_slug}/apps/{app_uuid}/envList an app's environment variables without their values
PUT/api/v1/orgs/{org_slug}/apps/{app_uuid}/envSet many variables; a variable given without value keeps its saved one
PUT/api/v1/orgs/{org_slug}/apps/{app_uuid}/env/{key}Set one environment variable, creating it when it is new
DELETE/api/v1/orgs/{org_slug}/apps/{app_uuid}/env/{key}Delete one environment variable