# Environment variables

Source: /docs/concepts/environment-variables

Environment variables are the key-value config your app reads at runtime — API keys, feature flags, external URLs. Set them in the app's **Environment** section.

## Adding a variable [#adding-a-variable]

### Open Environment [#open-environment]

From the app, open **Environment**.

### Add a key and value [#add-a-key-and-value]

Enter a **Key** and **Value** and **Add variable**. Keys must start with an uppercase letter or underscore and contain only uppercase letters, numbers and underscores — for example `OPENAI_API_KEY`.

## Values are write-only [#values-are-write-only]

After you save, the platform **never shows a value again** — the table shows keys only. To change one, use **Overwrite variable**; the new value replaces the old one permanently, and the old value cannot be shown or recovered. **Remove variable** deletes it for good.

## When changes apply [#when-changes-apply]

Saving a variable applies **automatically**: the app restarts within about **10 seconds**, with no downtime and no rebuild. Anything else you save before the restart goes in with the same restart. An app you have not deployed yet picks up its variables on its first deploy.

## Reserved and injected keys [#reserved-and-injected-keys]

Some keys belong to the platform and are injected for you. You cannot set them by hand:

* **`PORT`** — always `8080`; the port your app must listen on.
* **`DATABASE_URL`** — the connection string for your [managed database](/docs/concepts/subdomains-and-domains), injected from your first deploy.
* **`META_*`** — reserved platform keys.

## A prompt for your coding agent [#a-prompt-for-your-coding-agent]

The **Environment** section offers a prompt listing the exact variable names to read — never the values — so your code picks them up on deploy. Copy it into the agent that builds your app.

## What can go wrong [#what-can-go-wrong]

* **"Key must start with A–Z or \_ and contain only uppercase letters, numbers, and underscores."** — Rename the key to match the format.
* **"This key is reserved by the platform (e.g. PORT, DATABASE*URL, META*\*)."** — Pick a different name; that key is injected for you.
* **"Value is required."** — Enter a value before saving.