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

# Workspace variables

> Keep values that differ between workspaces, such as a mailbox or a ledger code, out of your agent's configuration.

Sandbox, UAT and Production are usually separate workspaces, and some values differ between them: the mailbox an agent sends to, a ledger scope, an ERP company code. A workspace variable lets the agent store a **reference** to such a value instead of the value itself. Each workspace supplies its own value, so an agent copied from one workspace to another works there without edits.

## Define a variable

Go to **Settings → Variables** and select **Add Variable**.

* **Name**: an upper-case letter followed by upper-case letters, digits or `_`, at most 64 characters (for example `SAP_MAILBOX`). Names are unique within a workspace.
* **Value**: the value for this workspace. It can be empty.
* **Description**: optional, for whoever maintains it.
* **Secret**: see [Secrets](#secrets).

Anyone who can view agents can see the list. Adding, editing and deleting variables needs the workspace settings permission (`workspace:update`). Variables are managed in the app only; there is no Platform MCP or public API tool for them.

## Reference a variable

Write the reference where the value would go:

```text theme={null}
{{env.SAP_MAILBOX}}
```

Spaces inside the braces are allowed (`{{ env.SAP_MAILBOX }}`). A reference can sit inside longer text, for example `Bearer {{env.ERP_TOKEN}}` or `Post to ledger {{env.LEDGER_CODE}} only.`

Anything that does not match this form exactly, such as lower-case names, single braces, or a missing `env.` prefix, is ordinary text and is left alone.

## Where references are resolved

| Location | When | Secrets |
| - | - | - |
| Agent instructions: global instructions, phase instructions, workflow-state instructions, phase progress | Each time the agent decides its next step | Not substituted |
| Instruction blocks that feed a tool | When the step is created | Not substituted |
| A configured tool's fixed settings (static bindings), including nested values | Non-secret values when the step is created; secrets when the tool runs | Substituted when the tool runs |
| Python code in a configured Python tool | When the tool runs, as part of its settings | Substituted when the tool runs |
| Configured tools called from code through `nn.tool` | When the call runs | Substituted |

Only references that you wrote into the configuration are resolved. A reference that the model writes into a tool argument itself is never expanded, so a model cannot read a variable, least of all a secret, by naming it.

### Python code

In a configured Python tool, the reference is replaced with the value as plain text before the code runs. Put it inside a string literal:

```python theme={null}
def handler(input):
    mailbox = "{{env.SAP_MAILBOX}}"
    ...
```

The value is inserted as is, so a value containing a quote character can break the string. Keep such values simple, or bind the value to an `input` field of the tool and read it from `input` instead.

## Secrets

Mark a variable as **Secret** for API keys, passwords and tokens.

* The value is never shown again after you save it. To change it, type a new value; leaving the field empty keeps the current one.
* It is never placed into text the AI model reads. In instructions the reference stays as written.
* It is substituted only into tool settings and Python code, at the moment the tool runs. The stored step arguments keep the reference, not the value.
* To turn a secret into a normal variable you must enter its new value in the same edit, so an existing secret is never revealed.

## Undefined variables

A reference to a variable the workspace does not define is caught at three points, so an agent never runs with the literal text `{{env.SAP_MAILBOX}}` as a value:

| When | What happens |
| - | - |
| Editing the agent | The agent's Configure page shows a warning that names each undefined variable. |
| Publishing a version | The publish is refused with a message naming the variables. Add them under **Settings → Variables**, then publish again. |
| Running a step | A tool step whose settings use an undefined variable fails with "workspace variable SAP\_MAILBOX is not defined in this workspace (used by …)", and the agent's normal failure handling (retry, pause or fail) applies. The same happens if the variables cannot be loaded. |

In an instruction the model reads, an undefined reference stays as written and is logged by name only, never by value. Text that merely looks similar, such as `{{po_number}}` or `{{oracle.environment}}`, is not a variable and is never checked.

Deleting a variable has the same effect on every agent that references it.


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