Skip to content

Environment variables and secrets

Each value belongs to a project, and either to one environment or to all of them (environment: null). A value set for an environment overrides the project-wide one with the same name.

Changes take effect on the next deploy; every write says so with "appliesOn": "next_deploy".

Environment variables

Request Who What it does
GET /v1/projects/{projectId}/env Owners, admins, developers, tokens with env:read Lists variables with their values. ?environment=production returns what that environment sees, overrides applied.
PUT /v1/projects/{projectId}/env/{key} Owners, admins, developers, tokens with env:write { "value", "environment"? }. Creates or replaces.
DELETE /v1/projects/{projectId}/env/{key} Same as PUT { "environment"? }, or no body for the project-wide value. Removes it, or 404 if there’s nothing to remove.
{ "variables": [{ "key": "PUBLIC_SITE_NAME", "value": "Cookbook", "environment": null, "updatedAt": "2026-10-27T12:00:00.000Z" }] }

Without ?environment=, the list has one entry per value, sorted by key, so a key set both project-wide and for production appears twice.

Secrets

No route ever returns a secret’s value. Values are encrypted with the project’s own key before they’re stored, and are decrypted only to hand them to your app at deploy.

Request Who What it does
GET /v1/projects/{projectId}/secrets Owners, admins, developers, tokens with env:read Lists secret names, never values. Same ?environment= as above.
PUT /v1/projects/{projectId}/secrets/{key} Owners, admins, developers, tokens with env:write { "value", "environment"? }. Creates or replaces.
DELETE /v1/projects/{projectId}/secrets/{key} Same as PUT { "environment"? }. Removes it.
{ "secrets": [{ "key": "STRIPE_SECRET_KEY", "environment": null, "updatedAt": "2026-10-23T12:00:00.000Z" }] }

Rules for both

  • Names: upper-case letters, digits and underscores, starting with a letter, at most 64 characters. Names starting FS_ are reserved. Anything else is 400 validation_failed.
  • Values: at most 5 KB.
  • An environment that doesn’t exist in the project is 404 not_found.
  • Every PUT and DELETE is in the audit log (env_var.set, env_var.deleted, secret.set, secret.deleted) with the name and environment, never the value.
  • Viewers can’t read either list.
  • A deploy token reaches only its own project. One made for a single environment can read only that environment (?environment= is required).

As Markdown: api/environment.md