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

# Dynamic Variables

> Two types of dynamic variables available in policy settings, connection configurations, and routing addresses in Apinizer: Environment Variable (${key}) and Context Variable (#{key}). Differences between the two types, supported fields, and usage methods.

## Overview

In Apinizer, dynamic variables can be used in many string fields such as policy settings, connection configurations, and routing addresses. This allows you to define values that change based on environment, request, or runtime instead of using fixed values.

There are two types of dynamic variables:

<CardGroup cols={2}>
  <Card title="Environment Variable — ${key}" icon="key">
    Environment variables are resolved at deploy time. They can have different values for environments such as development, test, and production.
  </Card>

  <Card title="Context Variable — #{key}" icon="sparkles">
    Context variables are resolved on each request. They contain system data such as request information, date/time, or custom values assigned via script.
  </Card>
</CardGroup>

## Two Variable Types

| Feature                    | Environment Variable (`${key}`)                    | Context Variable (`#{key}`)                                                           |
| -------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------- |
| **Format**                 | `${variableName}`                                  | `#{variableName}`                                                                     |
| **Resolution Time**        | At deploy time                                     | On each request                                                                       |
| **Value Source**           | Defined in Environment Variable management screen  | Auto-generated by system or assigned via script                                       |
| **Environment Dependent**  | Yes — different values for dev, test, prod         | No — per-request                                                                      |
| **Definition Requirement** | Requires definition in Environment Variable screen | System variables: not required. Global variables: requires Custom Variable definition |
| **Typical Usage**          | Host names, base URLs, ports, connection details   | User information, request details, date/time, error details                           |
| **Mutability**             | Fixed after deployment                             | Can vary on each request                                                              |

### Environment Variable (`${key}`)

Environment Variables allow you to use different values across environments (development, test, production). They are resolved at deploy time and remain fixed during runtime.

**Example:** `${api.hostname}` → `localhost:8080` in development, `api.example.com` in production

<Info>
  For detailed information about Environment Variable definition and management, see the [Environment Variable](/en/concepts/core-concepts/environment-variable) page. For CRUD operations and usage scenarios, see the [Environment Variable Management](/en/develop/environment-variables) page.
</Info>

### Context Variable (`#{key}`)

Context Variables are resolved on each request and consist of two subcategories:

**1. System Context Variables** — Auto-generated, no definition required:

* `#{context.request.httpMethod}`, `#{context.request.uri}`, `#{context.request.remoteAddress}`
* `#{context.system.year}`, `#{context.system.dateTime}`
* `#{context.message.correlationId}`
* `#{context.apiProxy.name}`, `#{context.apiProxy.id}`
* `#{context.credential.clientId}`, `#{context.credential.username}`
* `#{error.defaultErrorCode}`, `#{error.defaultMessage}`

**2. Global Variables** — Created via script, requires Custom Variable definition:

* `#{userId}`, `#{tenantId}`, `#{customValue}`
* Values are assigned using `customVariableMap.put("key", "value")` in Script policy

<Info>
  For detailed information about variable definitions, see the [Variables](/en/concepts/core-concepts/variable) page.
</Info>

### Mixed Usage

Both types can be used together:

```
https://${api.hostname}/v1/users/#{userId}
```

`${api.hostname}` is resolved at deploy time (e.g., `api.example.com`), while `#{userId}` gets a different value on each request.

## Supported Fields

Dynamic variables can be used in nearly all string fields in policy and connection settings.

### Policies

| Policy                               | Supported Fields                                                           | Variable Types        |
| ------------------------------------ | -------------------------------------------------------------------------- | --------------------- |
| **REST API Call**                    | URL, header, parameter, body                                               | `${key}` and `#{key}` |
| **OIDC**                             | Token endpoint, introspection endpoint, resource endpoint, form parameters | `${key}` and `#{key}` |
| **JOSE Validation / Implementation** | Dynamic key HTTP endpoint                                                  | `${key}` and `#{key}` |
| **Authentication API**               | URL, header, parameter                                                     | `${key}` and `#{key}` |
| **Message Builder**                  | Template, header, form fields                                              | `${key}` and `#{key}` |
| **Redaction**                        | Key-value list                                                             | `${key}` and `#{key}` |
| **Other policies**                   | Text (string) input fields                                                 | `${key}` and `#{key}` |

<Warning>
  **Script policy is not included in this table.** The `#{key}` placeholder mechanism is not used in Script policy because variables are already accessed directly via the `customVariableMap` object and bindings such as `request_httpMethod`, `dateTime_year`. See [Script Format Difference](#script-format-difference) for details.
</Warning>

### Connections

| Connection Type         | Supported Fields                                  |
| ----------------------- | ------------------------------------------------- |
| **Database Connection** | Host, port, username, password, connection string |
| **LDAP Connection**     | URL, base DN, username, password                  |
| **Email Connection**    | Host, port, username                              |

### Other Fields

| Field                                 | Supported Types                      |
| ------------------------------------- | ------------------------------------ |
| **Routing Address**                   | `${key}` and `#{key}`                |
| **JSON Error Response Template**      | `#{key}` (including error variables) |
| **XML Error Response Template**       | `#{key}` (including error variables) |
| **Identity Provider (DB, LDAP, API)** | `${key}` and `#{key}`                |
| **IP Group**                          | `${key}` and `#{key}`                |
| **Credential**                        | `${key}` and `#{key}`                |

<Note>
  In connection settings (Database, LDAP, Email), `${key}` (Environment Variable) is typically used because these values are environment-specific and should be resolved at deploy time. `#{key}` (Context Variable) is resolved at request time and is more commonly used in policy settings and routing addresses.
</Note>

## Variable Selection in UI

In policy and connection edit screens, a **"Variable"** button is available in the breadcrumb area. Clicking this button opens a menu providing access to two dialogs:

### Environment Variable Dialog

When **"Environment Variable"** is selected from the menu, the dialog lists all defined environment variables:

* **Global Variables** — Variables valid across all environments
* **Environment-Specific Variables** — Variables defined for specific environments

Clicking a variable copies it to the clipboard in `${variableName}` format, ready to be pasted into the relevant field.

### Context Variable Dialog

When **"Context Variable"** is selected from the menu, the dialog lists all available context variables organized by category:

* **Error Variables** — Error information
* **Request Variables** — Request information
* **Message Variables** — Message information
* **API Variables** — API Proxy information
* **Credential Variables** — Authenticated credential information
* **DateTime Variables** — Date/time information

Clicking a variable copies it to the clipboard in `#{variableName}` format.

<Info>
  Both dialogs are independent. You can use both `${key}` and `#{key}` in the same field.
</Info>

## Context Variable Reference

### Request

| Format                             | Description       | Example Value      |
| ---------------------------------- | ----------------- | ------------------ |
| `#{context.request.httpMethod}`    | HTTP method       | `GET`, `POST`      |
| `#{context.request.uri}`           | Request URI       | `/api/users/123`   |
| `#{context.request.contentType}`   | Content type      | `application/json` |
| `#{context.request.remoteAddress}` | Client IP address | `192.168.1.100`    |
| `#{context.request.queryString}`   | Query parameters  | `?id=123`          |
| `#{context.request.pathInfo}`      | Path information  | `/api/users`       |
| `#{context.request.contextPath}`   | Context path      | `/apinizer`        |

### DateTime

<Info>
  All `context.system.*` date/time variables return **UTC** values. To get time in a specific timezone, use `dtf.format('+03:00')` inside a JEXL expression in the [Message Builder](/en/develop/policies/message-builder) policy.
</Info>

| Format                          | Description                      | Example Value              |
| ------------------------------- | -------------------------------- | -------------------------- |
| `#{context.system.year}`        | Year                             | `2026`                     |
| `#{context.system.month}`       | Month (1-12)                     | `2`                        |
| `#{context.system.dayOfMonth}`  | Day (1-31)                       | `4`                        |
| `#{context.system.dayOfWeek}`   | Day of week (1=Monday, 7=Sunday) | `3`                        |
| `#{context.system.hour}`        | Hour (0-23)                      | `14`                       |
| `#{context.system.minute}`      | Minute (0-59)                    | `30`                       |
| `#{context.system.second}`      | Second (0-59)                    | `45`                       |
| `#{context.system.epochMillis}` | Unix timestamp (milliseconds)    | `1707058245000`            |
| `#{context.system.dateTime}`    | Formatted date/time (UTC)        | `2026-02-04T14:30:45.000Z` |
| `#{context.system.date}`        | Formatted date                   | `2026-02-04`               |
| `#{context.system.time}`        | Formatted time                   | `14:30:45`                 |

### Message

| Format                             | Description       | Example Value          |
| ---------------------------------- | ----------------- | ---------------------- |
| `#{context.message.correlationId}` | Unique request ID | `abc123-def456-ghi789` |

<Info>
  Custom message variables defined on API Proxy or Proxy Group are also displayed in this category.
</Info>

### API

| Format                     | Description    | Example Value         |
| -------------------------- | -------------- | --------------------- |
| `#{context.apiProxy.id}`   | API Proxy ID   | `api-proxy-123`       |
| `#{context.apiProxy.name}` | API Proxy name | `User Management API` |

### Credential

| Format                           | Description                           | Example Value       |
| -------------------------------- | ------------------------------------- | ------------------- |
| `#{context.credential.clientId}` | Authenticated credential key/username | `my-app-key`        |
| `#{context.credential.username}` | Credential username                   | `admin`             |
| `#{context.credential.email}`    | Credential email                      | `admin@example.com` |
| `#{context.credential.fullName}` | Credential full name                  | `John Doe`          |

### Error

| Format                         | Description           | Example Value       |
| ------------------------------ | --------------------- | ------------------- |
| `#{error.customizedErrorCode}` | Customized error code | `CUSTOM_001`        |
| `#{error.customizedHttpCode}`  | Customized HTTP code  | `400`               |
| `#{error.customizedMessage}`   | Customized message    | `Please try again`  |
| `#{error.defaultErrorCode}`    | Default error code    | `DEFAULT_001`       |
| `#{error.defaultMessage}`      | Default message       | `An error occurred` |
| `#{error.defaultHttpCode}`     | Default HTTP code     | `500`               |

### Script Format Difference

Context variables use a **different format** inside Script policy. The dot (`.`) separator used at runtime is replaced with underscore (`_`) in scripts:

| Runtime Format                     | Script Format            |
| ---------------------------------- | ------------------------ |
| `#{context.request.httpMethod}`    | `request_httpMethod`     |
| `#{context.system.year}`           | `dateTime_year`          |
| `#{context.message.correlationId}` | `message_correlationId`  |
| `#{context.apiProxy.name}`         | `apiProxy_name`          |
| `#{error.defaultErrorCode}`        | `error_defaultErrorCode` |

```groovy theme={null}
// Using context variables inside script
String method = request_httpMethod
String year = dateTime_year
String correlationId = message_correlationId
```

## Global Variable Usage

Global variables are created through Custom Variable definitions and assigned values via script. They are used for data transfer between policies.

<Steps>
  <Step title="Create Variable Definition">
    Go to Project > Variables and create a new definition with **Custom Variable** type.
  </Step>

  <Step title="Assign Value via Script">
    In Script policy, assign a value using `customVariableMap.put("variableName", "value")`.
  </Step>

  <Step title="Use the Variable">
    Use `#{variableName}` format in other policies and settings.
  </Step>
</Steps>

**Script Example:**

```groovy theme={null}
// Extract user information from request body
if (bodyTextFC != null && !bodyTextFC.isEmpty()) {
    def jsonBody = new groovy.json.JsonSlurper().parseText(bodyTextFC)
    if (jsonBody.userId) {
        customVariableMap.put("userId", jsonBody.userId.toString())
    }
}

// Get value from header
String token = headerMapFC.get("X-Custom-Token")
if (token != null) {
    customVariableMap.put("customToken", token)
}
```

<Warning>
  Global variables are available only after the script policy executes. The policy that uses the variable must run **after** the script policy that assigns the value (policy order matters).
</Warning>

## Usage Examples

### Error Response Template

```json theme={null}
{
  "error": {
    "code": "#{error.defaultErrorCode}",
    "message": "#{error.defaultMessage}",
    "requestId": "#{context.message.correlationId}",
    "timestamp": "#{context.system.epochMillis}"
  }
}
```

### Dynamic Routing

```
https://${api.hostname}/v1/#{tenantId}/users/#{context.request.pathInfo}
```

`${api.hostname}` is resolved at deploy time, while `#{tenantId}` and `#{context.request.pathInfo}` are resolved on each request.

### Response Header Addition

```
X-Request-ID: #{context.message.correlationId}
X-API-Name: #{context.apiProxy.name}
X-Processed-At: #{context.system.dateTime}
```

## Behavior Rules

* Missing `#{key}` values are replaced with empty string (`""`); no exception is thrown, a warning-level log is written
* Missing `${key}` values cannot be resolved and remain as-is
* In Script policy, the custom variable map is accessed directly, so the `#{...}` placeholder mechanism is not used there
* Variable names are case-insensitive

## Next Steps

<CardGroup cols={2}>
  <Card title="Environment Variable" icon="key" href="/en/concepts/core-concepts/environment-variable">
    Learn about environment variables in detail
  </Card>

  <Card title="Variables" icon="code" href="/en/concepts/core-concepts/variable">
    Learn about variable definitions
  </Card>

  <Card title="Script Policy" icon="terminal" href="/en/develop/policies/script">
    Variable usage in Script policy
  </Card>

  <Card title="Environment Variable Management" icon="sliders" href="/en/develop/environment-variables">
    Environment Variable CRUD operations
  </Card>
</CardGroup>
