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

# Overview

> Manage multi-site configurations for a single agent.

**Some sections on this page require Python.** Default variant handling, testing with functions, and the advanced `conv.variant` examples need Python familiarity. The UI-based setup (creating variants, adding attributes, CSV imports) does not require code.

Variant management is for agents that serve multiple locations, brands, or configurations. Each variant stores attributes like phone numbers, addresses, and hours, so one agent can give the right answer for each site. Without variants, you would need a separate agent per location – multiplying maintenance and increasing the risk of inconsistencies.

Variant management is found under **Build > Variant management** in Agent Studio.

**Use variant management when** your agent needs location- or site-specific responses (hours, addresses, phone numbers). If your agent serves a single location, you do not need variants – use [Managed Topics](/managed-topics/introduction) and [functions](/tools/introduction) directly.

<img src="https://mintcdn.com/polyai/Dlkm5JXi7Fl7VLZ9/images/variant/introduction.png?fit=max&auto=format&n=Dlkm5JXi7Fl7VLZ9&q=85&s=e5e3fbd0df8798d2c02d6570b0ac48df" alt="variant-1" width="2434" height="1326" data-path="images/variant/introduction.png" />

## Prerequisites

1. Ensure you have admin access to **Build > Variant management** in your PolyAI agent.
2. Set up [Managed Topics](/managed-topics/introduction) aligned with your multi-site configuration goals.
3. Understand how to use [functions](/tools/introduction) in your agent.

To bulk update or create variants, use the [CSV import guide](/variant-management/csv-imports).

## Key capabilities

### Multi-site configurations

Use **variant management** to manage multiple locations in the same agent. Attributes such as phone numbers and opening hours are stored per variant, so the agent gives location-specific answers.

### Knowledge integration

Attributes defined in variant management are accessible in your Managed Topics rules, templates, and actions using the `${variant_<attribute_name>}` syntax. The `variant_` prefix is required – an attribute named `opening_hours` is referenced as `${variant_opening_hours}`, not `${opening_hours}`. In Python functions, the same attribute is accessed without the prefix as `conv.variant.opening_hours`.

### Flexible routing

Set up routing in the [start function](/tools/start-tool) to direct users to the appropriate variant. For voice, route based on phone numbers or SIP headers; for webchat, use URL parameters or session data. Variants can also tailor SMS messages dynamically.

### Advanced functions

Use the [`conv.variant`](/tools/classes/conv-object#set-variant) object to retrieve variant attributes during conversations or make decisions based on variant data.

### Testing and troubleshooting

You can select a specific variant when making in-app test calls. The variant selector appears in the **Call configuration** section when variants exist for your project, letting you test variant-specific behavior directly in Agent Studio without manual function workarounds.

<Warning> The first variant created is used as the default for the agent. If this variant is deleted, the next variant in the list automatically becomes the new default. To control which variant is active, use `conv.set_variant()` in your [start function](/tools/start-tool).  </Warning>

## Real-life use case

A hotel chain with multiple branches worldwide uses Variant Management to manage its agent. Each branch (e.g., "London" and "New York") has a variant configured with attributes like phone numbers, addresses, and check-in hours. When a guest contacts the agent, the branch is identified based on the user's context–phone number for voice, URL parameters for webchat–and the response is tailored accordingly.

## Variants and attributes

Think of the variant management table like a spreadsheet:

* **Add variant** (with the **Add variant** button) adds a new **row**. Each variant represents a distinct location or site, such as "London" or "Tokyo." It is the *who* – a new instance of the configuration.
* **Add attribute** (with the **+** plus sign) adds a new **column**. Each attribute is a data field that exists across *all* variants, such as phone number, address, or operating hours. It is the *what* – a new piece of information that every variant can hold a value for.

<img src="https://mintcdn.com/polyai/Dlkm5JXi7Fl7VLZ9/images/variant/example-variant.png?fit=max&auto=format&n=Dlkm5JXi7Fl7VLZ9&q=85&s=377aab57232156ea47b95c6e81f3667f" alt="variant-2" width="2072" height="690" data-path="images/variant/example-variant.png" />

### Setting up a new variant

<img src="https://mintcdn.com/polyai/Dlkm5JXi7Fl7VLZ9/images/variant/add-variant-annexe.png?fit=max&auto=format&n=Dlkm5JXi7Fl7VLZ9&q=85&s=5d04c1242d3c138b88fd12a9b45ffa9a" alt="variant-3" width="1352" height="1346" data-path="images/variant/add-variant-annexe.png" />

To configure variants:

1. Open **Build > Variant management** in the sidebar.
2. Add a new variant and provide a name, such as "London" or "Tokyo."
3. Save your configuration.

<img src="https://mintcdn.com/polyai/Dlkm5JXi7Fl7VLZ9/images/variant/added.png?fit=max&auto=format&n=Dlkm5JXi7Fl7VLZ9&q=85&s=bcd83abe434a5637b42d6368bcd26dc4" alt="variant-4" width="2474" height="1224" data-path="images/variant/added.png" />

### Setting up a new attribute

<img src="https://mintcdn.com/polyai/Dlkm5JXi7Fl7VLZ9/images/variant/add-attribute.png?fit=max&auto=format&n=Dlkm5JXi7Fl7VLZ9&q=85&s=e2def89e5f10a470f04cc3adf0c50acd" alt="variant-5" width="1438" height="1182" data-path="images/variant/add-attribute.png" />

Define attributes for the variant, such as:

* **Phone numbers**
* **Address**
* **Operating hours**
* **Menu**
* **Accessibility**

<img src="https://mintcdn.com/polyai/Dlkm5JXi7Fl7VLZ9/images/variant/attribute-added.png?fit=max&auto=format&n=Dlkm5JXi7Fl7VLZ9&q=85&s=c3f63b00e7fb539f2f5e6c4f0b46ad2c" alt="variant-6" width="2238" height="1196" data-path="images/variant/attribute-added.png" />

<Note>
  **Attribute values are stored as strings.** Whatever you type or paste into the variant management table — including JSON, dict literals, comma-separated lists, or numbers — is persisted verbatim as a string and returned as a string from `conv.variant.<attribute>`. To use structured data:

  * Store it as **JSON** (use `null`, not `None`; lists, not tuples) and parse with `json.loads()` in your function, or
  * **Split** structured values into multiple attributes (for example `tuesday_open`, `tuesday_close`) so each cell holds a single scalar value.

  Reading an attribute that does not exist on the active variant returns `None`, not an `AttributeError`.
</Note>

### Default variant handling

By default, the first variant in the list is used unless otherwise specified. If a variant needs to be changed programmatically, use
the `conv.set_variant()` method in your start function.

**Example**:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
if not conv.variant:
    conv.set_variant("default_variant_name")
```

## Using variants in SMS templates

Main article: [SMS](/sms/introduction)

To include variants dynamically in SMS messages, use the syntax `${variant_<attribute_name>}` (the `variant_` prefix is required). For example:

* `${variant_phone_number}` dynamically includes the phone number associated with the active variant.

The same `variant_`-prefixed syntax works in Managed Topics rules, templates, and actions. Inside Python functions, the prefix is dropped: `conv.variant.phone_number`.

## Testing variants

### In-app calling

When making test calls from Agent Studio, you can select a specific variant from the **Call configuration** section. The variant selector only appears when variants exist for your project. Call settings are grouped in a collapsible panel for easier navigation.

### In chat

For webchat testing, you can set variants manually in the start function:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
if not conv.callee_number:
    conv.set_variant("London")
```

Alternatively, create functions such as `set_variant1`, `set_variant2` to switch variants during testing.

## Advanced: Accessing variants in functions

This example shows how to assign variants dynamically based on user context. The `conv.variant` object lets you retrieve and set the appropriate variant so responses match the user's location or context.

### Voice example (phone number-based)

Match the dialled number against a variant attribute to set the active variant. The attribute name (e.g., `phone_number`, `callee`) must match a column you defined in **Build > Variant management**.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def start_function(conv: Conversation):
    phone_numbers = {
        variant.phone_number: variant_name
        for variant_name, variant in conv.variants.items()
    }
    if conv.callee_number and conv.callee_number in phone_numbers:
        conv.set_variant(phone_numbers[conv.callee_number])
```

If your variant table uses a different column name for the phone number (for example, `callee`), replace `variant.phone_number` with `variant.callee`:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def start_function(conv: Conversation):
    callee_map = {
        variant.callee: variant_name
        for variant_name, variant in conv.variants.items()
    }
    if conv.callee_number and conv.callee_number in callee_map:
        conv.set_variant(callee_map[conv.callee_number])
```

### Webchat example (URL parameter-based)

For webchat interactions, you can use URL parameters or session data to determine the variant:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def start_function(conv: Conversation):
    # Get variant from webchat metadata (e.g., URL parameter)
    location = conv.metadata.get("location")
    if location and location in conv.variants:
        conv.set_variant(location)
```

## Flow activation per variant

Variants control which [flows](/flows/introduction) are available during a conversation. Each variant supports two fields:

* `active_flows` – a list of flow names that are enabled for this variant
* `inactive_flows` – a list of flow names that are disabled for this variant

When a variant is active, only its `active_flows` are available to the agent. Any flows listed in `inactive_flows` are skipped during processing — this lets you enable or disable specific conversation paths per location or configuration without duplicating flow logic.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Check which flows are active for the current variant
if conv.variant:
    active = conv.variant.active_flows
    log.info(f"Active flows: {active}")
```

## Automate with the Agents API

If your variants live in a source of truth outside Agent Studio — a locations database, a CRM, a spreadsheet — you can sync them directly rather than editing by hand.

<AccordionGroup>
  <Accordion title="Manage variants via the Agents API" icon="code">
    The [Agents API](/api-reference/agents/introduction) exposes full CRUD for both [attributes](/api-reference/agents/endpoint/variants/list-attributes) (the dimensions) and [variants](/api-reference/agents/endpoint/variants/list-variants) (the per-site combinations).

    <CodeGroup>
      ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
      # Create an attribute (a variant dimension)
      curl -X POST https://api.us.poly.ai/v1/agents/AGENT_ID/branches/main/attributes \
        -H "x-api-key: $POLYAI_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{ "name": "location_id" }'

      # Create a variant with attribute values
      curl -X POST https://api.us.poly.ai/v1/agents/AGENT_ID/branches/main/variants \
        -H "x-api-key: $POLYAI_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "London Flagship",
          "attributes": {
            "location_id": "LON-01",
            "address": "12 Regent Street",
            "hours": "9am - 10pm"
          }
        }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import os, requests

      BASE = "https://api.us.poly.ai"
      HEADERS = {"x-api-key": os.environ["POLYAI_API_KEY"]}

      # Sync many sites in one pass
      for site in load_locations_from_crm():
          requests.post(
              f"{BASE}/v1/agents/{AGENT_ID}/branches/main/variants",
              headers=HEADERS,
              json={
                  "name": site["name"],
                  "attributes": {
                      "location_id": site["id"],
                      "address": site["address"],
                      "hours": site["hours"],
                  },
              },
          )
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Related pages

<CardGroup cols={2}>
  <Card title="CSV imports" icon="file-csv" href="/variant-management/csv-imports">
    Bulk create or update variants using CSV files.
  </Card>

  <Card title="Managed Topics" icon="book" href="/managed-topics/introduction">
    Use variant attributes in topic responses with \${variant_attribute} syntax.
  </Card>

  <Card title="Functions" icon="code" href="/tools/introduction">
    Access variant data programmatically with conv.variant.
  </Card>

  <Card title="Start tool" icon="play" href="/tools/start-tool">
    Route callers to the correct variant based on phone number or metadata.
  </Card>

  <Card title="Variants endpoints" icon="square-terminal" href="/api-reference/agents/endpoint/variants/list-variants">
    CRUD for variants and attributes in the Agents API.
  </Card>
</CardGroup>
