Secrets API
List, set and remove a project's environment values, and choose whether each reaches the running process, the build, or both.
On this page
Secrets are environment values for a project, encrypted at rest. Values are never returned by the API — only names, scopes and dates. A project reads its environment when it starts, so setting or removing a secret restarts it. For how your code reads them, see Environment and secrets.
/ projects/ {name}/ secretsNames, scopes and dates — never values/ projects/ {name}/ secretsSet a secret, replacing one of the same name/ projects/ {name}/ secrets/ {key}Remove a secretScopes
Each secret has a scope that says where its value is given:
scope | The running process | The build |
|---|---|---|
runtime (default) | Yes | No |
build | No | Yes |
both | Yes | Yes |
Use build for values a framework bakes into its output at build time, such as a public API address. Keys your server uses at run time belong in runtime, so a build script never sees them.
List secrets
/ projects/ {name}/ secretsNames, scopes and dates — never valuesThe project's secrets, sorted by name.
namestringRequiredname.curl https://api.fortly.com/projects/my-app-ada/secrets \
-H "Authorization: Bearer $FORTLY_TOKEN"const res = await fetch("https://api.fortly.com/projects/my-app-ada/secrets", {
headers: { Authorization: `Bearer ${process.env.FORTLY_TOKEN}` },
});
const { secrets, storable } = await res.json();{
"secrets": [
{ "name": "PUBLIC_API_URL", "created_at": 1791820800, "scope": "build" },
{ "name": "STRIPE_SECRET_KEY", "created_at": 1791734400, "scope": "runtime" }
],
"storable": true
}storable is false when the platform has no encryption key configured; setting a secret then fails with 501 rather than storing the value unencrypted.
Set a secret
/ projects/ {name}/ secretsSet a secret, replacing one of the same nameStores a value, replacing any secret of the same name — its scope included — and restarts the project so the next request sees it.
In the path, {name} is the project's name. The JSON body takes:
namestringRequiredSTRIPE_SECRET_KEY.valuestringRequiredscopestringruntime, build or both. Default runtime. Any other value is refused rather than defaulted.Fortly sets some variables itself, and these names are refused: PORT, HOST, PATH, FORTLY_API, FORTLY_TOKEN, DATABASE_URL, DATABASE_TRANSACTION_URL, PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD and PGSSLMODE.
curl -X POST https://api.fortly.com/projects/my-app-ada/secrets \
-H "Authorization: Bearer $FORTLY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"STRIPE_SECRET_KEY","value":"sk_live_...","scope":"runtime"}'const res = await fetch("https://api.fortly.com/projects/my-app-ada/secrets", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FORTLY_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "STRIPE_SECRET_KEY", value: process.env.STRIPE_SECRET_KEY, scope: "runtime" }),
});Answers 201:
{ "name": "STRIPE_SECRET_KEY", "scope": "runtime" }| Status | When |
|---|---|
400 | The name breaks the rules above or is reserved, the value is empty or too long, or the scope is not one of the three. |
501 | The platform cannot encrypt secrets right now, so nothing was stored. |
A build reads its secrets when it runs. A build or both secret you change takes effect on the next release, not on the one already live.
Remove a secret
/ projects/ {name}/ secrets/ {key}Remove a secretRemoves the secret and restarts the project.
namestringRequiredname.keystringRequiredcurl -X DELETE https://api.fortly.com/projects/my-app-ada/secrets/STRIPE_SECRET_KEY \
-H "Authorization: Bearer $FORTLY_TOKEN"await fetch("https://api.fortly.com/projects/my-app-ada/secrets/STRIPE_SECRET_KEY", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.FORTLY_TOKEN}` },
});Answers 204 No Content, or 404 with no secret by that name.