Docs

Environment and secrets

Set environment values for your build and your running app, choose where each one goes, and know when a change takes effect.

Updated October 12, 2026
On this page
  1. Set a value
  2. Choose where a value goes
  3. When a change takes effect
  4. List and remove values
  5. Names Fortly reserves
  6. How values are protected
  7. Related

Environment values are the API keys, passwords and configuration your project needs without writing them into its code. Fortly encrypts each value before storing it and never hands it back: the API and the console show names, scopes and dates, never values. You choose, per value, whether it goes to your build, your running app, or both.

Set a value

Open the environment

Open your project, go to Deployments, and choose the Environment tab.

Add a value

Under Add a value, enter the Name and the Value, and choose Where it may be used: Runs only, Builds only, or Builds and runs.

Save it

The value is stored encrypted and cannot be shown again. It appears under Set on this project with its scope and the date it was set.

Choose where a value goes

ScopeConsole labelGiven toUse it for
runtimeRuns onlyYour running appDatabase passwords, payment keys, anything only your server reads
buildBuilds onlyYour build, not your running appValues a framework bakes into its output at build time
bothBuilds and runsBothA value the build embeds and the server also reads

runtime is the default because it hands a value to the fewest places. A build runs your project's own install scripts, so keep a value out of it unless the build needs it.

Public configuration for a frontend

Frameworks like Next.js read variables such as NEXT_PUBLIC_API_URL while they build and write them into the files they produce. Give those values the build or both scope. A value the build cannot see ends up missing from the site, which then fails in the visitor's browser rather than at deploy time.

A scope you spell wrong is refused rather than read as runtime: "runtme" is not a secret scope; use one of runtime, build, both.

When a change takes effect

Setting or removing a value takes effect without a deploy for values your running app already reads: Fortly clears the project's cached responses, and the next request runs with the new set of values.

Two cases need a new deploy:

  • A value with the build or both scope. It is read while the build runs, so output that is already built keeps the value it was built with. Deploy again to rebuild with the new one.
  • A new name for a server-rendered app or Node server. A release built into a Worker receives the runtime and both values whose names existed when it was built. After adding a new name, deploy again so the new release picks it up. Changing or removing a value for an existing name does not need this.

A static site has no running server, so only its build-time values matter to it.

List and remove values

Terminal
curl https://api.fortly.com/projects/my-app-ada/secrets \
  -H "Authorization: Bearer $FORTLY_TOKEN"

Each entry in secrets has name, created_at and scope. There is no route that returns a value: if you lose one, set a new one.

Terminal
curl -X DELETE https://api.fortly.com/projects/my-app-ada/secrets/STRIPE_SECRET_KEY \
  -H "Authorization: Bearer $FORTLY_TOKEN"

Removing answers 204, or 404 with no secret by that name.

GET/projects/{name}/secretsNames, scopes and dates — never the values
POST/projects/{name}/secretsSet one, or replace it
DELETE/projects/{name}/secrets/{key}Remove one

Names Fortly reserves

These names are reserved for the platform, and setting one is refused with PORT is set by Fortly and cannot be replaced (naming the one you tried):

GroupNames
ProcessPORT, HOST, PATH
FortlyFORTLY_API, FORTLY_TOKEN
DatabaseDATABASE_URL, DATABASE_TRANSACTION_URL, PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE

The database names are reserved so that no value of yours can stand in for the connection details the platform manages for your project's database. A name that only contains one of these, such as MY_DATABASE_URL, is yours to use.

Other names are refused when they break the naming rule: a name cannot start with a digit, or a name can use capital letters, digits and underscores — for example DATABASE_URL.

How values are protected

  • Encrypted at rest with AES-256-GCM. The key is held outside the database, so a copy of the database does not carry readable values.
  • Never returned. No API route and no console page shows a value after it is set.
  • Given only where their scope says. A build receives build and both values; a running app receives runtime and both values.
  • Masked in logs. A value 8 characters or longer that appears in your project's log is replaced with [redacted]. Shorter values are not masked, because they cannot be told apart from ordinary words.
Something missing or unclear? Tell us and we will fix the page.© 2026 Fortly