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

# Variables

Variables are the facts about one caller: name, order number, crop, due date. They ride along with the call as key and value pairs and come back on every read. On every call we put them in front of the model for you.

## Where they come from

* **On a campaign.** Each contact carries its own set.
  * **From a contact list or sheet.** Every column that is not the name or the phone, keyed by its header. Narrow it with [`attributeColumns`](/api-reference/contacts/upload-a-contact-file) if a sheet carries more than the call needs.
  * **Appended over the API.** `attributes` on each contact you [add to a campaign](/api-reference/campaigns/append-contacts-to-a-campaign).
* **On a direct call.** `variables` on the [call request](/api-reference/starting-a-conversation/dispatch-a-call-from-this-assistant).
* **On a web session.** `variables` on the [web session token](/api-reference/starting-a-conversation/create-a-web-session-token) request. They ride in the token the browser gets, so **don't put secrets there**.

A sheet row and what it becomes:

| Name        | Mobile No.   | Crop   | District | Last order |
| ----------- | ------------ | ------ | -------- | ---------- |
| عائشہ صدیقی | 0300 1234567 | cotton | Multan   | May        |

```json theme={null}
{ "name": "عائشہ صدیقی", "phone": "03001234567", "attributes": { "Crop": "cotton", "District": "Multan", "Last order": "May" } }
```

## What the model sees

On every call, the record goes into the prompt as a block, with a standing instruction on how to use it. A campaign call puts the contact's name first:

```text wrap theme={null}
اس call کے لیے caller record یہ ہے۔
نام: عائشہ صدیقی
Crop: cotton
District: Multan
Last order: May
اس معلومات کو صرف وہاں استعمال کریں جہاں بات میں قدرتی طور پر ضرورت ہو۔ اسے فہرست کی طرح نہ پڑھیں، بار بار نہ دہرائیں، اور فون نمبر بلند آواز میں نہ پڑھیں۔
```

The last line tells the model to use the facts only where they fit, never read them out like a list, never repeat them, and never say the phone number aloud. The `attributes` you upload or append are capped at 1,500 bytes of JSON. The block shows up to 30 variables, 160 characters per value. On a direct call or a web session, send numbers and true or false as they are. A nested object or a list stays on the record but is left out of the block.

There is no `{{crop}}` substitution, and you don't need one. The record is in front of the model, so refer to the field by name:

```text wrap theme={null}
Ask how this season's crop is going. Use the crop's name.
If the last order was more than three months ago, ask whether they switched supplier.
```

[Simulate](/voice-agents/testing/simulation) takes the same `variables` and hands them to the agent as its caller record, so you can read how the model uses them before you dial anyone.

## Where they come back

Every session read returns `variables` exactly as you sent them, on the [status read](/api-reference/sessions-%26-call-records/get-a-sessions-status) and the [session detail](/api-reference/sessions-%26-call-records/get-a-calls-transcript-and-outcomes). In the example above, the session for that call carries the row it was dialed from:

```json theme={null}
"variables": { "Crop": "cotton", "District": "Multan", "Last order": "May" }
```

So whoever reads the call, a webhook receiver included, knows which farmer and which crop it was about without looking anything up.

## Two habits

* **Type values the way you want them said.** `amount: 4500` leaves the model to guess the currency and the reading. `amount: Rs 4,500` leaves it nothing to guess. Where a value can't be typed that way, give the prompt an example of how to read it: "Read dates as day then month, 25 August." Most calls go fine either way. *This is about the one call in a hundred where the model takes a strange route with a bare number, and a spelled-out value takes that route away.*
* **Steering goes elsewhere, when you need it.** Anything that is not a fact about this caller, like "apologize for the late follow-up" or "do not pitch today", is a [per-call instruction](/voice-agents/personalization/per-call-instructions), not a variable. Most calls need none.
