# Variables

Anything in `{{double braces}}` in a prompt, a greeting or a spoken line is filled in when the call is placed. It is how one agent greets ten thousand people by name instead of ten thousand agents greeting one each.

## Your own

Write the placeholder wherever the text is, and supply the value on the call.

**JSON**

```json
{
  "languages": [{
    "code": "en-IN",
    "greeting": "Hello {{first_name}}, this is Acme about order {{order_id}}.",
    "system_prompt": "You are calling {{first_name}} about order {{order_id}}, which was due on {{due_date}}. The balance is {{balance}} rupees."
  }]
}
```

`POST /v1/calls`

**Shell**

```bash
curl -s -X POST https://voice.sphoro.com/v1/calls \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "'"$AGENT_ID"'",
    "to": "+919876543210",
    "call_variables": {
      "first_name": "Priya",
      "order_id": "AC-40192",
      "due_date": "the fourteenth of August",
      "balance": "2,480"
    }
  }'
```

> **A call missing a variable its agent uses is refused.** `POST /v1/calls` answers `422` naming the ones you left out, before anything is dialled. The alternative is an agent reading "Hello `{{first_name}}`" to a customer, which is worse than a failed request every time.

## The eight the platform fills in

These never have to be sent, and sending them changes nothing — they are supplied per call from what the platform already knows.

| Variable | Is |
| --- | --- |
| `{{agent_id}}` | The agent running the call. |
| `{{agent_name}}` | Its name, as you set it. |
| `{{call_id}}` | This call's id — useful in a prompt that tells the agent to read a reference out. |
| `{{call_direction}}` | `inbound` or `outbound`. The cheapest way to run one agent on both, with one prompt that knows which it is on. |
| `{{from_number}}` | The number the call is from. |
| `{{to_number}}` | The number the call is to. |
| `{{current_date}}` | Today, where the call is. |
| `{{current_time}}` | Now, where the call is. |

> **Put `{{current_date}}` in any prompt that reasons about dates.** A model has no idea what day it is, so "book me for next Tuesday" against a prompt with no date in it produces a confident answer about a Tuesday in the model's training data. This one variable removes an entire class of wrong bookings.

## Where variables are read

| Place | Filled? |
| --- | --- |
| A language's `system_prompt` | Yes |
| A language's `greeting`, `silence_prompt` and `final_message` | Yes |
| A static flow node's `say` and `say_in` | Yes |
| A keypad entry's `say` | Yes |
| A flow node's `prompt` | Yes |
| A journey's message and API step bodies | Yes — plus whatever the journey itself has captured. See [journeys](https://voice.sphoro.com/docs/journeys). |
| Field names, ids, numbers | No. Variables are for spoken and written text, not for addressing objects. |

## Variables captured during the call

The ones above are set before the call. A [flow](https://voice.sphoro.com/docs/flows) can also *capture* values mid-conversation, on an edge, and those become available to later nodes and to expression edges that branch on them.

**JSON**

```json
{
  "to": "confirm",
  "type": "intent",
  "when": "the caller gives a date and a time",
  "capture": { "appointment_date": "date", "appointment_time": "time" }
}
```

Declare the type of anything numeric in the flow's `variables` map. An undeclared variable is compared by inference, and inference reads `"18" > "9"` as false.

## Writing values that are read aloud

Every variable in a spoken line is going through a voice, so supply the value in the form you want *heard*, not the form your database holds.

| Instead of | Send |
| --- | --- |
| `"due_date": "2026-08-14"` | `"the fourteenth of August"` |
| `"balance": "2480.00"` | `"2,480"`, and let the prompt say "rupees" |
| `"name": "PRIYA SHARMA"` | `"Priya"` — a voice reads capitals as capitals |
| `"status": "PEND_VERIF"` | `"waiting to be verified"` |
