# AI Action Variables

> Inject dynamic values into your API Actions using {{...}} placeholders. AI parameters, built-in conversation variables, and conversation metadata.

Anywhere you can type a value in an API Action (URL, headers, body, or query parameters) you can inject dynamic values using the `{{...}}` syntax. Quickchat substitutes these placeholders at request time, just before calling your endpoint.

Click the **+ Add AI Data** button next to any value field to browse every variable available in the current scenario.

![The API Action editor with "+ Add AI Data" buttons highlighted next to the endpoint URL and each header's value field](https://docs.quickchat.ai/_astro/01-add-ai-data-buttons.DHRitqS6.png)

_The **+ Add AI Data** button is available next to every value field: the endpoint URL, each header value, body fields, and query parameters._

## Three categories of variables

| Category | Syntax | When it's filled |
|---|---|---|
| **AI parameters**. Values your AI Agent extracts from the conversation. You define them under each Action's **Parameters** section. | `{{order_number}}`, `{{customer_email}}` | The AI Agent fills these at call time, based on the rules you write into each parameter's description. |
| **Built-in variables**. Conversation context Quickchat injects automatically. | `{{scenario_id}}`, `{{conversation_id}}`, `{{language}}`, `{{country}}`, ... | Always available. Quickchat substitutes them on every request. |
| **Conversation metadata**. Custom key-value pairs attached to the conversation. | `{{metadata_<key>}}` | Whenever the corresponding key exists on the conversation (set by the widget, a channel integration, Smart Data Gathering, or the API). |

:::tip
Each variable is rendered as a coloured **pill** inside the editor. Blue means it's an AI parameter or a built-in. Orange means it's a metadata variable or a system token. Red means the name doesn't match anything Quickchat knows (usually a typo).
:::

## The "+ Add AI Data" dropdown

The dropdown lists every variable available for the current scenario, grouped into five sections:

1. **Parameters**: the AI parameters you defined on this Action.
2. **Visitor**: four metadata keys auto-captured for every visitor, when their channel provides them.
3. **Metadata (used in recent conversations)**: custom metadata keys seen on this scenario's last 20 conversations, with a sample value for each.
4. **Built-in**: the six conversation variables that are always available, with their current value or a sample shown inline.
5. **System Tokens**: credentials provided by a connected integration (e.g. HubSpot). Only appears if the integration is connected.

![The "+ Add AI Data" dropdown opened, showing the Parameters, Visitor, Metadata (used in recent conversations), and Built-in sections with sample values inline](https://docs.quickchat.ai/_astro/02-dropdown-sections.5byXjHSt.png)

_The dropdown groups variables into sections. **Built-in** rows show the live value where it's already known (`scenario_id`) and `e.g. …` samples for the rest. The **Metadata (used in recent conversations)** group is rebuilt per scenario from real recent conversations. The **System Tokens** section (not shown here) appears only when an integration is connected._

:::note
The **Metadata (used in recent conversations)** list is rebuilt from your scenario's most recent 20 conversations and **cached for 5 minutes per AI Agent**. A metadata key set on a brand-new conversation may take up to 5 minutes to appear in this section. You can always type `{{metadata_<your_key>}}` directly: Quickchat doesn't require the key to appear in the dropdown for the substitution to work.
:::

## Built-in variables

These six variables are always available. The **+ Add AI Data** dropdown shows the live value (where it's already known) or a sample value next to each row.

| Variable | Example | What it is |
|---|---|---|
| `{{scenario_id}}` | `abc123xyz` | ID of the AI Agent the conversation belongs to. |
| `{{conversation_id}}` | `conv-d8a8…` | Unique identifier of the conversation. |
| `{{conversation_url}}` | `https://app.quickchat.ai/.../conv-d8a8…` | Direct Inbox link to this conversation. |
| `{{conversation_channel}}` | `widget`, `telegram`, `slack`, `whatsapp`, ... | Channel the conversation is happening on. |
| `{{language}}` | `en`, `nl`, `de`, `fr`, ... | ISO 639-1 lowercase code of the conversation language. |
| `{{country}}` | `US`, `GB`, `NL`, `DE`, ... | ISO 3166-1 alpha-2 uppercase country code. |

A few notes worth knowing:

- **`{{scenario_id}}`** is also visible in your browser URL while editing the Action. The **+ Add AI Data** dropdown shows the **live** ID for the scenario you're editing, not a sample.
- **`{{conversation_url}}`** is useful for posting clickable links into Slack, Jira, or any other tool that benefits from a direct jump back to the Inbox.
- **`{{language}}`** is derived from (in this order): the page URL prefix (for Shopify Markets), conversation metadata, then your AI Agent's configured language.
- **`{{country}}`** is derived from (in this order): the page URL prefix, the URL host TLD, then a language-to-country fallback.

## Conversation metadata

The `metadata_` prefix is required. Quickchat looks up `<key>` in the conversation's metadata and substitutes its value into the request.

```
{{metadata_order_id}}      →   ord_8a4f3…
{{metadata_customer_tier}} →   gold
```

### Visitor metadata keys

These four keys describe the visitor's session and get their own **Visitor** section in the dropdown. They are auto-captured by the channel, integration, widget/embed, or API. You don't need to push them yourself.

| Variable | Auto-captured by |
|---|---|
| `{{metadata_fullPathURL}}` | Website widget, website embed, or chat-channel integrations that include their own widget (HubSpot, Intercom, etc.). |
| `{{metadata_visitor_name}}` | Chat-channel profile (Telegram, Slack, etc.), channel integrations, Smart Data Gathering, your widget/embed, or the Quickchat API. |
| `{{metadata_visitor_email}}` | Chat-channel profile, channel integrations, Smart Data Gathering, your widget/embed, or the Quickchat API. |
| `{{metadata_visitor_phone_number}}` | WhatsApp and other phone-aware channels, channel integrations, Smart Data Gathering, your widget/embed, or the Quickchat API. |

### Custom metadata keys

You can attach arbitrary key-value pairs to a conversation and reference them as `{{metadata_<key>}}`.

**From the website widget or embed**

Pass `custom_params` when you initialise the widget. See the [Website channel: Advanced Features: Custom Parameters](/channels/website/#advanced-features-custom-parameters) section for the full snippet.

```html
<script>
  _quickchat("custom_params", {
    "order_id": "ord_8a4f3",
    "customer_tier": "gold"
  });
</script>
```

Reference them in any Action as `{{metadata_order_id}}` and `{{metadata_customer_tier}}`.

:::caution
Metadata keys must match `^[a-zA-Z0-9_]+$` (letters, digits, underscores). Keys with spaces or other punctuation **cannot** be referenced as `{{metadata_<key>}}`. They will still appear in the conversation's metadata view in the Inbox, but the Action substitution will skip them. Stick to snake_case names when you intend to use them in Actions.
:::

**From Smart Data Gathering**

Each field name you configure in a Smart Data Gathering campaign becomes a metadata key under the same name. If your campaign collects `delivery_address`, you can immediately use `{{metadata_delivery_address}}` in any subsequent API Action.

**From channel integrations**

HubSpot, Intercom, Telegram, Slack, WhatsApp, and similar integrations push their own metadata onto the conversation (visitor name, email, page URL, account properties, etc.). Anything visible in the conversation's metadata view in the Inbox can be referenced via `{{metadata_<key>}}`.

**From the Quickchat API**

Use `POST /v1/api_core/conversations/{conv_id}/metadata` to attach metadata programmatically. See [Conversation Metadata](/channels/api/#conversation-metadata) in the API reference.

## Pill colours in the editor

Every `{{...}}` reference is rendered as a coloured pill so you can tell at a glance whether Quickchat recognises the variable.

![API endpoint URL containing an orange {{metadata_user_type}} pill, and a Language header value containing a blue {{language}} pill](https://docs.quickchat.ai/_astro/03-pills-in-url-and-header.Dhoi-IMn.png)

_Pills work in every value field. Above: an orange `{{metadata_user_type}}` pill in the endpoint URL, and a blue `{{language}}` pill in a header value._

![JSON request body with a blue {{country}} pill and an orange {{metadata_fullPathURL}} pill](https://docs.quickchat.ai/_astro/04-pills-in-body.Cba5nJkM.png)

_The same colour rules apply inside a JSON request body. Built-in variables like `{{country}}` render blue, metadata variables like `{{metadata_fullPathURL}}` render orange._

- 🔵 **Blue**: a built-in variable or an AI parameter you defined.
- 🟠 **Orange**: a metadata variable (`{{metadata_*}}`) or a System Token from a connected integration.
- 🔴 **Red**: Quickchat doesn't recognise this name. Almost always a typo. Fix the spelling, define it as an AI parameter, or (if it really is a metadata key) make sure it starts with `metadata_`.

:::tip
Typing `{{metadata_anything}}` directly is always valid, even if the key has never appeared on a conversation yet. The pill will be orange, not red. This is the right way to wire up keys you set yourself from a widget script or Smart Data Gathering before the first conversation has happened.
:::

## Testing your Action

The **Test Response** sheet (next to **Done** in the Action editor) lets you send a real HTTP request without going through a chat. For each variable referenced in the Action, you'll see an input row to fill in the value Quickchat will substitute.

Two convenience pre-fills:

- `{{language}}` defaults to `en`
- `{{country}}` defaults to `US`

Override either field to test a different locale. All other variables (your AI parameters, `{{metadata_*}}` keys, and the other built-ins) start blank. Type any value to simulate what would happen in a live conversation.

## FAQ

**Why does my variable appear in red?**
The editor doesn't recognise the name. Either it's a typo, it doesn't match any AI parameter you've defined, it isn't a built-in variable, or it's a metadata key that's missing the `metadata_` prefix.

**Can I inject `{{language}}` or `{{country}}` even if I never set them?**
Yes. Quickchat always derives both from the conversation context (page URL, browser locale, or your AI Agent's configured language). You'll always get a value, even if it falls back to `en` / `US`.

**What's the difference between `{{language}}` and `{{metadata_locale}}`?**
- `{{language}}` is the built-in. Always available, always in `en` / `nl` / `de` ... format. Use this 99% of the time.
- `{{metadata_locale}}` only exists if a channel integration or your widget explicitly set a `locale` key on the conversation metadata, often in `xx_YY` format (e.g. `en_GB`). Reach for this only when you need the exact locale string verbatim.

**Is there a limit on the number of AI parameters per Action?**
Yes, **30 per Action**. If you genuinely need more, [contact support](mailto:contact@quickchat.ai).

**Are built-in and metadata values sent to the AI?**
No. They're injected into the HTTP request **after** the AI has decided to call the Action. The AI doesn't see them and isn't asked to fill them in. That's why they don't need to be defined as AI parameters.

**How often is the "Metadata (used in recent conversations)" list refreshed?**
It's cached for 5 minutes per AI Agent. A metadata key set on a brand-new conversation may take up to 5 minutes to appear in the dropdown, but you can always type `{{metadata_<your_key>}}` directly without waiting.

**Are metadata key names case-sensitive?**
Yes. `{{metadata_orderId}}` and `{{metadata_orderid}}` are different keys. Use exactly the same casing you set on the widget, integration, or API side.

**Does the Test Response sheet know about these variables?**
Yes. When your Action references `{{language}}` or `{{country}}`, the Test Response sheet pre-fills them with `en` and `US` respectively. All other variables start blank. Type any value to simulate a live call.

## Related

- [Custom Actions](/ai-agent/actions/#custom-actions): how to create and configure an API Action.
- [Website channel: Custom Parameters](/channels/website/#advanced-features-custom-parameters): how to push metadata from your website.
- [API: Conversation Metadata](/channels/api/#conversation-metadata): how to push metadata programmatically.
