# Variables

> Capture a value once in a call and reuse it in what the agent says, in API calls and in branches.

Source: https://docs.vlayers.ai/build/variables

Kind: How-to guide

## What you'll learn

Where variables come from, how to use them, and how to fill them before a call starts. Variables are how a call remembers.

## Prerequisites

- A flow. See [Flow builder](https://docs.vlayers.ai/build/flow-builder).

## Step 1: Use a variable

Write `{{ variable_name }}` anywhere you write text:

```text
Thanks {{ customer_name }}, I have your {{ plan }} account open.
```

You can use variables in Say and Ask prompts, LLM instructions, transfer briefings, tool URLs and bodies, and branch conditions. An unknown name renders as empty rather than failing, so a typo shows up as a gap in the sentence.

## Step 2: Fill it

Variables come from:

| Source | How |
|---|---|
| **Ask steps** | The answer lands in the variable you name on the step. The most common source. |
| **API results** | A **Call an API** step saves fields from the answer (Step 3). |
| **Set variable steps** | Compute or set a value mid-call, including from other variables. |
| **Trigger variables** | Values sent with an outbound trigger arrive before the call connects (Step 4). |
| **Built-ins** | Always there: `caller_id`, `to`, `call_id`, `room_name`, `agent_name`, `channel`, `now`, `today`. |
| **Workspace variables** | Defaults defined once under **Settings → Variables**, given to every call. |

`call_id` is the call's id in the API and in webhooks. It is empty in a text conversation, or when the call could not be registered with the API.

## Step 3: Save values from an API

On a **Call an API** step, use **Save outputs to variables**, one `name = path` per line:

```text
customer_name = data.name
plan          = data.subscription.plan
open_tickets  = data.tickets.count
```

Values are saved as text, so numbers and true/false read naturally when spoken. Outputs are saved only when the call succeeds; handle the rest on the **Failure** exit. A path missing from the answer is skipped, and the call detail says so.

## Step 4: Send values with an outbound trigger

A trigger turns an event in your system into a phone call. Whatever you send in `variables` is available from the agent's first word:

```bash
curl -X POST https://api.vlayers.ai/v1/triggers/$TRIGGER_TOKEN/call \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155550100",
    "variables": { "order_id": "A-4471", "eta": "Thursday" }
  }'
```

The flow can then open with "Calling about order \{\{ order_id \}\}: it is running late and now arrives \{\{ eta \}\}."

## Test it

Run a **Dry run** in the builder and read the conversation. Every saved value shows inline ("Saved customer_name"), and an empty spot in a spoken line is easy to spot. See [Testing](https://docs.vlayers.ai/build/testing).

## Common problems

| Problem | Fix |
|---|---|
| The agent speaks an empty gap | The variable was never captured, or the name is misspelt. Names are case-sensitive. |
| A trigger is refused with `reserved_metadata_key` (400) | You used a name the platform keeps: `projectId`, `agentId`, `sessionId`, `callId`, `phoneNumberId`, `bindingId`, `apiKeyId`, `tenantId`, `moduleId`, `toNumber`, `fromNumber`, `callerId`. Pick another name, such as `lead_source`. |
| A variable you sent is missing | `source`, `route`, `direction`, `carrier`, `mode` and `turnId` are reserved too: they are dropped silently and the call goes ahead. Rename them. |
| A tool step fails with `url_placeholder_empty` | A placeholder in the tool's URL path had no value, so the tool was not called. An empty optional query parameter is fine. |

Name variables in `snake_case`: letters, digits and underscores, starting with a letter. A value set later in the call replaces the earlier one.

## Next steps

- [Tools](https://docs.vlayers.ai/build/tools): Call your API with captured values.
- [Transfers](https://docs.vlayers.ai/build/transfers): Use variables in a transfer briefing.
