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

# set_variable() / get_variable()

> Pass per-call data between agent handlers

Call variables are provided as a convenient way to pass per-call data (patient name, account ID, etc.) between agent handlers.
Variables can be seeded when the call starts and read or updated at any point during the call.

<Tabs>
  <Tab title="Python">
    ```python signature theme={null}
    call.set_variable(key: str, value: Any) -> None
    call.get_variable(key: str) -> Any
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript signature theme={null}
    await call.setVariable(key: string, value: any): Promise<void>
    await call.getVariable(key: string): Promise<any>
    ```
  </Tab>
</Tabs>

## Valid variable values

<Tabs>
  <Tab title="Python">
    Variable values must be JSON-serializable: strings, numbers, booleans, `None`, and dicts/lists composed of those types.
  </Tab>

  <Tab title="TypeScript">
    Variable values must be JSON-serializable: strings, numbers, booleans, `null`, and objects/arrays composed of those types.
  </Tab>
</Tabs>

## Seeding variables at call start

For the following types of calls, variables can be seeded at the start.

<Tabs>
  <Tab title="Python">
    * **Outbound calls** — pass a `variables` dict to `call_phone()`
    * **Campaigns** — each contact's `data` dict becomes that contact's variables
  </Tab>

  <Tab title="TypeScript">
    * **Outbound calls** — pass a `variables` object to `callPhone()`
    * **Campaigns** — each contact's `data` object becomes that contact's variables
  </Tab>
</Tabs>

## Other ways to store call state

As an alternative to call variables, you can keep per-call state in an in-process dictionary keyed by `call.id`.

That said, we only recommend this for simple use cases. If your process restarts, any in-memory state will be lost.
For durable per-call state, use Redis or another session store keyed by `call.id`.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    r = redis.Redis()
    call_state: dict[str, dict] = {}

    @agent.on_call_start
    def on_call_start(call: guava.Call):
        # In-memory — lost on process restart
        call_state[call.id] = {"stage": "intro"}

        # Redis — survives restarts
        r.set(f"call_state:{call.id}", json.dumps({"stage": "intro"}), ex=3600)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const r = redis.createClient();
    const callState: Record<string, Record<string, unknown>> = {};

    agent.onCallStart(async (call: guava.Call) => {
      // In-memory — lost on process restart
      callState[call.id] = { stage: "intro" };

      // Redis — survives restarts
      await r.set(`call_state:${call.id}`, JSON.stringify({ stage: "intro" }), { EX: 3600 });
    });
    ```
  </Tab>
</Tabs>

## Example

<Tabs>
  <Tab title="Python">
    ```python example.py theme={null}
    @agent.on_call_start
    def on_call_start(call: guava.Call):
        # Variables seeded via call_phone(variables={...}) are readable immediately
        patient_name = call.get_variable("patient_name")
        call.reach_person(contact_full_name=patient_name)


    @agent.on_reach_person
    def on_reach_person(call: guava.Call, outcome: str):
        if outcome == "available":
            call.set_task(
                "confirmed",
                objective="Confirm the appointment and answer any questions.",
            )


    @agent.on_task_complete("confirmed")
    def on_confirmed(call: guava.Call):
        call.hangup()
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript example.ts theme={null}
    agent.onCallStart(async (call: guava.Call) => {
      // Variables seeded via callPhone(from, to, {...}) are readable immediately
      const patientName = await call.getVariable("patientName");
      await call.reachPerson(patientName);
    });

    agent.onReachPerson(async (call: guava.Call, outcome: string) => {
      if (outcome === "available") {
        await call.setTask({
          taskId: "confirmed",
          objective: "Confirm the appointment and answer any questions.",
        });
      }
    });

    agent.onTaskComplete("confirmed", async (call: guava.Call) => {
      await call.hangup();
    });
    ```
  </Tab>
</Tabs>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.