# Environment variables

> What we set for you, what you can set, and what happens when you change one.

Your app's settings — API keys for other services, feature switches, anything you would otherwise hard-code — live on the app's **Environment** tab. They reach your app as ordinary environment variables, so a framework that reads its configuration from the environment picks them up with no code from you.

## What we set for you

These arrive on every deploy without you doing anything.

| Variable | What it is |
| --- | --- |
| `ROAR_API_KEY` | An AI key of the app's own. Calls it makes bill to your workspace and are attributed to that app, so you can see what each one costs. |
| `ROAR_BASE_URL` | The gateway address to send those calls to. |
| `DATABASE_URL` | Connection string for the app's managed Postgres, if you turned one on. See [Databases](/docs/databases). |
| `APP_NAME`, `APP_URL` | The app's own name and public web address. |

<Note>
**Your app already has a gateway key — don't add one.** This is the single most common thing people try to set by hand. `ROAR_API_KEY` is there from the first deploy; read it from the environment and start making calls. See [Authentication](/docs/authentication).
</Note>

## What you can set

Anything else. The usual case is a credential for a service your app talks to — a payment provider, an email provider, a third-party API.

`APP_NAME` and `APP_URL` are yours to override if you want different values; setting them replaces ours. `DATABASE_URL` is the same, if you would rather point the app at a database of your own than the one we provision.

## Names you cannot use

A few names are reserved, because we set them and an edited copy would put your app into a state that disagrees with itself:

- `ROAR_API_KEY` and `ROAR_BASE_URL` — your app already has both.
- `ROAR_CRON_SECRET` — filled in for you when you set up a scheduled run on the **Jobs** tab.
- The port your app listens on, and a small number of names the hosting layer uses internally.

Try to set one and the console says so, and tells you what the app already has rather than only refusing.

## Changing one

**Every change redeploys the app.** There is no separate "restart" — a new version is built and takes over, and the previous one keeps serving until it does. That means:

- A change is live within a deploy's time, not instantly.
- A batch of changes is better made together than one at a time, since each one costs a deploy.
- If the new version fails to build, **the old one stays up** with the old values. See [When a deploy fails](/docs/troubleshooting).

## Two things worth knowing

**Some frameworks need a variable at BUILD time, not just at run time.** Anything baked into a compiled front-end is read while the app is being built, so a variable added after a build is not in it until the next one. If a setting looks correct on the Environment tab and your app still cannot see it, this is usually why — redeploy.

**Secrets belong here, not in your repository.** A key committed to GitHub is a key you have to rotate, whatever the repository's visibility. Putting it on this tab keeps it out of your history and out of anything your team clones.
