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

# Variables

> Define and resolve template variables in runbooks.

## Overview

Variables let you parameterize runbooks. Define them in the `variables` section and reference them in step values with `{{variableName}}` syntax.

## Definition

```yaml theme={null}
variables:
  email:
    source: prompt
    description: "Login email address"
    required: true
  password:
    source: prompt
    description: "Login password"
    required: true
    sensitive: true
  baseUrl:
    source: fixed
    value: "https://staging.example.com"
  timestamp:
    source: expression
    expression: "{{Date.now()}}"
  region:
    source: env
    envKey: "AWS_REGION"
```

## Variable fields

| Field         | Type           | Default | Description                                            |
| ------------- | -------------- | ------- | ------------------------------------------------------ |
| `source`      | VariableSource | —       | How the variable is resolved (see below)               |
| `description` | string         | —       | Human-readable description                             |
| `required`    | boolean        | `true`  | Whether the variable must be resolved before execution |
| `sensitive`   | boolean        | `false` | Mask value in logs and reports                         |
| `value`       | string         | —       | Static value (for `fixed` source)                      |
| `expression`  | string         | —       | Template expression (for `expression` source)          |
| `envKey`      | string         | —       | Environment variable name (for `env` source)           |

## Variable sources

| Source       | Description                                      | Example                                |
| ------------ | ------------------------------------------------ | -------------------------------------- |
| `prompt`     | Prompt the user at execution time (CLI only)     | Login credentials                      |
| `fixed`      | Hardcoded static value                           | Base URLs, constants                   |
| `context`    | AI extracts from the context markdown file       | Values described in `--context`        |
| `env`        | Read from an environment variable                | `AWS_REGION`, `APP_URL`                |
| `expression` | Evaluate a template expression                   | `{{Date.now()}}`, `{{captured_value}}` |
| `data`       | Read from a CSV/JSON data file (batch execution) | Row-specific values                    |

## Resolution priority

At execution time, variables are resolved in priority order: **secrets > data > context > env > expression > fixed > prompt**. The first match wins.

For a detailed breakdown of each source, see [Variables & Secrets: Resolution priority](/guides/variables-and-secrets#resolution-priority).

<Note>
  In SDK mode, `prompt` source is not available. Unresolved required variables will throw an error.
</Note>

## Using variables in steps

Reference variables in any string field using `{{variableName}}`:

```yaml theme={null}
steps:
  - ordinal: 0
    description: "Navigate to {{baseUrl}}"
    action:
      type: navigate
      url: "{{baseUrl}}/login"
    url: "{{baseUrl}}/login"
    riskLevel: low
    requiresConfirmation: false
  - ordinal: 1
    description: "Enter email"
    action:
      type: input
      value: "{{email}}"
      selector:
        tagName: input
        inputType: email
    url: "{{baseUrl}}/login"
    riskLevel: low
    requiresConfirmation: false
```

## Sensitive variables

Mark variables as `sensitive: true` to prevent their values from appearing in logs and reports:

```yaml theme={null}
variables:
  password:
    source: prompt
    description: "Login password"
    sensitive: true
```

Values passed via `--secrets` (CLI) or the `secrets` option (SDK) are automatically treated as sensitive.

## Batch execution with `data` source

When using `--data`, map variable names to CSV/JSON columns with `dataSource`:

```yaml theme={null}
variables:
  email:
    source: data
    description: "User email from CSV"
  name:
    source: data
    description: "User name from CSV"

dataSource:
  mapping:
    email: "Email"      # CSV column header
    name: "Full Name"   # CSV column header
```

```bash theme={null}
npx @refrainai/cli execute -- \
  --runbook ./flow.yaml \
  --data ./users.csv
```

The runbook executes once per data row, with variables populated from each row.
