> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codenullapp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment Variables

> Store secrets and per-deployment settings for your application and read them from your hooks with process.env

Environment variables let you keep the values your application needs at runtime — API keys, tokens, endpoints of third-party services — **outside** of your hooks and features. Instead of hardcoding a key inside a hook (where it would end up in the configuration, in every migration and in every audit entry), you store it once as an environment variable and read it from code.

Each variable belongs to **one application** and holds a `name` and a `value`. The backend of that application exposes it to your code as `process.env.<NAME>`.

<Info>
  Environment variables are a **backend** concept. They are available to hooks,
  scheduled jobs and webhooks, which run on the application server. They are
  **not** shipped to the browser, so a feature's frontend code cannot read them.
</Info>

## Creating and updating variables

Variables are managed with GraphQL mutations against your application's `/graphql` endpoint (authenticated as a user of the application):

```graphql theme={null}
mutation {
  createEnvironmentVariable(
    environmentVariable: { name: "PAYMENTS_API_KEY", value: "sk_live_..." }
  ) {
    _id
    name
  }
}
```

To change a value, update it by `_id`:

```graphql theme={null}
mutation {
  updateEnvironmentVariable(
    _id: "6712ab..."
    environmentVariable: { name: "PAYMENTS_API_KEY", value: "sk_live_new..." }
  ) {
    _id
    name
  }
}
```

And `deleteEnvironmentVariable(_id: "...")` removes it.

You can list the variables of the application with the `environmentVariables` query.

<Tip>
  If you connect an AI agent through the [MCP Server](/configurations/mcp-server), the
  `set_environment_variable` tool creates or updates a variable **by name** in a single call (it
  requires the `env:write` scope, which only an admin can grant). The `list_environment_variables`
  tool returns **only the names** — values are never exposed through MCP, and never reach the MCP
  audit log.
</Tip>

## Reading a variable from a hook

Inside a hook, read the variable from `process.env` using its name:

```javascript theme={null}
const apiKey = process.env.PAYMENTS_API_KEY;

const response = await fetch("https://api.payments.example/v1/charges", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ amount: instance.Total }),
});
```

Because hooks run inside the application's backend process, they can read **any** variable of that deployment. Codenull's static hook scanner flags any hook whose code touches `process.env` so those hooks stay visible and auditable — the warning is informative, it does not block the hook. See [Hooks](/configurations/hooks) for the full hook lifecycle.

<Warning>
  Treat a variable's value as a secret. Never log it, never return it from a hook and never copy it
  into a feature's code: anything a feature renders travels to the browser.
</Warning>

## Naming conventions

* Use `UPPER_SNAKE_CASE` — that is how the value is exposed in `process.env`.
* Prefix related values so they are easy to spot: `PAYMENTS_API_KEY`, `PAYMENTS_API_URL`.
* Avoid the names of the pre-configured variables below unless you intend to change that platform behavior.

## Environments and cloning

Environment variables are **not** copied when you migrate changes between environments or clone an application. Migration moves configuration — features, hooks, menus and permissions — while variables stay tied to the deployment where they were created.

This is intentional: development, staging and production should point at different third-party accounts. After promoting changes to a new environment, create the variables that the migrated hooks expect **before** enabling them, or those hooks will read `undefined`.

## Pre-configured variables

Beyond the ones you create, every Codenull deployment reads a set of variables that change the behavior of the application server itself. These are the ones a designer may need to review or ask to have set:

| Variable | What it does | Typical value |
| - | - | - |
| `DISABLE_JOBS` | When `true`, the scheduler starts but no [scheduled job](/configurations/hooks/scheduled-jobs) hook is registered. Useful to keep a non-production environment from firing jobs against real data. | `true` / unset |
| `LOG_LEVEL` | Minimum severity written by the application logger. Defaults to `info`. | `debug`, `info`, `warn`, `error` |
| `APPLICATIONINSIGHTS_CONNECTION_STRING` | Connection string of the Azure Application Insights resource that receives traces and errors. When it is empty, error reporting is not sent anywhere. | `InstrumentationKey=...` |
| `APPLICATIONINSIGHTS_GRAPHQL_FULL_LOG` | Sends one custom event per stage of every GraphQL request (request with variables, parsed document, field resolutions, response) to Application Insights. Off by default: only the request itself is tracked, without payloads. Enable it temporarily on one application to debug; the payloads contain tenant data and weigh about 25 KB per request. | `true` / unset |
| `WHATSAPP_VERIFY_TOKEN` | Token Meta must echo back when it verifies the `/api/webhook/whatsappDelivery` subscription. Must match exactly what you typed in the Meta console, otherwise the verification returns `403`. See [WhatsApp](/configurations/hooks/whatsapp). | Any secret string |
| `SENDGRID_KEY` | SendGrid API key for hooks that call SendGrid directly. The application's own email sending is configured in the application settings, not here. | `SG....` |
| `ENABLE_GRAPHQL_PLAYGROUND` | Enables the GraphQL playground (Apollo Sandbox) at `/graphql`. Off by default outside local environments. | `true` / unset |

<Warning>
  **`ENABLE_GRAPHQL_PLAYGROUND` is a security-sensitive switch.** The playground exposes an
  interactive console over your application's full GraphQL API on a public URL. Leave it disabled in
  production; turn it on only for the moment you need to inspect the schema, and turn it back off
  immediately afterwards.
</Warning>

Other variables present in the deployment are reserved for the platform (database connections, Auth0, plan and storage validations, New Relic). Changing them is not part of application design — contact Codenull if you believe one of them needs a different value.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.