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

# In-conversation Actions

> Trigger dynamic actions while the conversation is under way, powered by flows

Design actions the agent can invoke on demand during a live conversation. Each action can launch a visual flow where you can respond to the customer (Say) and call external APIs (API Request), then pass results back to the agent.

## Overview

* **When it runs**: On-demand based on what the customer asks for (e.g. "check order status").
* **Action definition**: Provide name, description, and optional parameters the AI should collect from the customer.
* **Flow**: Each action can launch a flow composed of nodes that respond and call APIs, returning variables the agent can use to reply.
* **One at a time**: Actions run one at a time in a conversation. If the agent calls the same action again with the same inputs, it isn't run a second time. If the agent calls a different action while one is still running, the running one can be cancelled so the new request can start, so design each action to be safe to stop part-way. On a voice call, if the caller starts talking while an action is running, the flow pauses before its next step and resumes once the agent can speak again.

> [!NOTE]
>
> In-conversation actions run on voice, chat and email. On an email thread the agent invokes them in the same way, and the results appear in the conversation's action log exactly as they do on voice and chat. The one exception is the Say node, which is skipped on email (see [Say Node](#say-node)). For more on email, see [Email Agents](/build/ai-agents/email-agents).

> [!WARNING]
>
> Action names must be 1-63 characters and use only letters, numbers, underscores, or hyphens (e.g. `check_order_status`, `CheckOrderStatus`).
>
> A name must also be different from every other action on the agent, across its pre-, in- and post-conversation actions, ignoring capital letters and surrounding spaces. Creating an action, or renaming one, to a name another action already has is refused with a message naming that action, such as **This agent already has an in-conversation action named "check\_order\_status". Choose a different name.** Saving other changes to an action doesn't check its name.
>
> Three names are reserved because the agent already uses them: `file_search`, `intent_to_transfer` and `end_conversation`. An In-conversation action can't be named any of these, whatever the capitalization. Saving with one of them fails with a general error message.

> [!NOTE]
>
> Name and Description is passed as context to the AI to better determine when to call the action. Ensure to provide as much context as possible here for the AI to better identify when to call this Action

## Create an In-conversation Action

1. Open **Build → AI Agents**, open your agent, then select the **In-conversation Actions** card under **Actions & Integrations**.
2. Select **Create New Action** and fill in:
   * **Name** and **Description** (clear, intent-focused wording helps the AI)
   * **Parameters** (optional): in **Parameters**, click **Add Parameter** for each piece of information the AI should collect from the customer.
     * **Parameter Name**, **Description**, **Type** and **Required** (Yes or No). Each name must be different from the other parameters on the action; a repeated name is refused.
     * **Type** is **String**, **Number** or **Enum**. For **Enum**, click **Add Item** under **Enum Items** to list the allowed values; the AI picks one of them.
     * Use descriptions to specify format and examples the AI should gather
   * **Assign Parameter Values to Variables**: Once the action has a parameter, a table lists each one. Pick or create a variable in the **Variable** column to hold what the AI collects, so the flow's nodes can use it. In the **Default Value** column you can also enter a value to use when the AI doesn't supply one. Whether or not you map it, every parameter is also in the flow's variable picker as `PARAM.<name>`, under **Parameter**.
3. Select **Save & Edit Flow** to save the action and open the Flow Builder in one step. **Create** (or **Save Changes** when you're editing an action) saves the action and closes the drawer instead; select **Go to Flow** on its card to open the flow later.

> [!TIP]
>
> **Tell the agent when to use it.** In your agent's **Guidelines**, type `{{` and choose the action under **ACTIONS** to insert a reference that follows the action if you rename it. The picker also lists two built-in actions, `end_conversation` and `intent_to_transfer`. See [Reference Actions in Your Guidelines](/best-practices/prompting-guide#reference-actions-in-your-guidelines).

> [!TIP]
>
> **Start from a description.** While creating an action (not when editing one), click the sparkle button in the drawer header (tooltip **Generate**). In **Generate Action with AI**, describe what the action should do, including its inputs, behavior and expected output, then click **Create** or press Ctrl/Cmd+Enter. The drawer fills in with a suggested name, description and parameters. Nothing is saved until you review it and save. Every generated parameter is marked **Required**, so check each parameter's type and whether it should be required.

## Flow Builder

The flow defines what happens when this action is invoked. Drag nodes from the palette on the left, grouped as **Flow Control** (Say, Decision) and **Actions** (API Request, AI Context, Set Variable), and drop each one on the **Drop to connect** area that appears under the node it should follow, starting from the Start node. You don't draw connections by hand and nodes can't be dragged around the canvas. A node dropped in the middle of a chain is inserted there, and the nodes after it move down. Dropping a Decision node opens its settings first, and the nodes that follow a Decision are chosen in its settings (see [Decision Node](#decision-node)).

* **Variables**: You can reference variables from Pre-conversation Actions and from previous nodes in the same flow. Saved values are available to the nodes that come after. To tell the agent a value, pass it back with an [AI Context](#ai-context-node) node, or through the API response (see [API Request Node](#api-request-node)).
* **Filler messages**: Use a Say node to keep the customer informed while an API request is in progress.
* **Find a node**: In a large flow, use the search box in the top-right of the canvas to jump to any node by name or type — see [Find a Node on the Canvas](#find-a-node-on-the-canvas).

### Say Node

Deliver a message to the customer — spoken on a call, sent as a message in chat — with support for variables and language-specific content. Say messages are delivered on voice and chat only. On an email thread a Say node is skipped and nothing is sent.

* **Message (Default)**: Main text to deliver. Supports variables like `{{firstName}}`.
* **Language-specific messages**: Optionally tailor messages per language. If not provided, the default message is used. A field for each language, such as **Message in Spanish**, appears only when the agent has additional languages set up. Click the wand button beside a field (tooltip **Translate to Spanish**) to fill it from the default message, then review the result.
* **Variables support**: Insert variables using the variable picker. You can use:
  * Pre-conversation variables (e.g. contact details)
  * Variables created earlier in the flow

Use cases:

* Provide confirmations, prompts, or interim updates while waiting on API calls.
* Share results from previous nodes (e.g. "Your order `{{orderId}}` is on the way.")

### API Request Node

Call an external HTTP API and map response fields to variables.

Configuration (same capabilities as Pre-conversation API requests):

* **Method**: GET, POST, PUT, DELETE, PATCH
* **URL**: Static URL (e.g. `https://api.example.com/orders/`)
* **Query Params**: Key-value pairs, variable-aware (the **Params** tab)
* **Headers**: Static or variable-aware (e.g. `Authorization`)
* **Body**: Choose a **Body Type**: **None**, **JSON**, **Text**, **XML** or **x-www-form-urlencoded** (a table of key-value pairs). Variables supported. The **Body Type** control is locked to **None** when the method is GET. When you change the type, Studio adds, updates or removes the matching `Content-Type` header for you and shows a message, so check the **Headers** tab afterwards.
* **Auth**: Either tick **Use Auth Profile** and pick a reusable credentials profile — see [Auth Profiles](/manage/auth-profiles) for details, including [mTLS](/manage/auth-profiles#mtls-client-certificate) for APIs that require certificate-based mutual authentication — or leave it unticked and set up **Bearer Token**, **API Key**, **Basic Auth** or **OAuth 2.0** right in the node (**None** sends no credentials).
* **Test Request**: Use "Send" to preview response in Data or Meta tabs

> [!NOTE]
>
> The URL must be a publicly reachable `http://` or `https://` address. Addresses on a private or internal network, such as `localhost`, `10.x.x.x` or `192.168.x.x`, and link-local addresses are refused, and so are hostnames that can't be resolved. This applies to **Send** as well as to live conversations.

Using variables in a JSON body:

* A variable on its own, without quotes, is sent as a JSON value rather than text. In `{"quantity": {{quantity}}}`, a value like `5` is sent as the number 5, `true` or `false` as a boolean, and a variable holding an object or a list as JSON.
* Put quotes around the variable to send it as text, as in `{"zip": "{{zip}}"}`. Do this whenever the API expects a string, especially for values such as `007` or `0412345678`: without quotes they are sent as numbers and lose their leading zeros.
* Inside longer text, such as `"Hi {{name}}"`, the value is inserted as text and special characters are escaped for you.
* A variable with no value is sent as `null` when it stands alone, and as empty text inside longer text.

Response handling:

* Click **Send** and inspect the response. **Data** shows the response body. **Meta**, shown with the status code such as **Meta (200)**, shows the status and response headers.
* In **JSON Path Expressions**, click a field in the **Data** or **Meta** view to add its path, or type one such as `$.data.user.name`. Pick a **Variable** for each path; built-in Interaction and System variables, parameter variables and campaign variables can't be used here. A **Default Value (optional)** is used when the path isn't found in the response or is empty.
* Mapped variables are available to the nodes that come after.

> [!NOTE]
>
> By default the agent is given the whole API response. To give it only some fields, tick **Add to Context** on those JSON Path rows. As soon as at least one row is ticked, the agent receives only the ticked variables and not the rest of the response. Mapping a path to a variable without ticking **Add to Context** doesn't limit what the agent sees. The **Add to Context** column appears only in In-conversation action flows.

Tips:

* Use a preceding Say node as a filler message while the request runs.
* Keep payloads minimal and map only the fields you need.

### Set Variable Node

Assign or overwrite variable values at any point in the flow without making an API call. One node can set several variables.

* **Add Variable**: Adds another numbered assignment to the node. Each assignment has a **Variable** and a **Transformation Logic**. Remove an assignment with the **×** at the top-right of its card (shown once the node has more than one).
* **Variable**: Choose an existing variable or create a new one. Built-in Interaction and System variables, and campaign variables, can't be set with this node, so they aren't offered here.
* **Transformation Logic**: Choose how the value is worked out.
  * **Static Value**: Enter a fixed value or reference another variable (e.g. `{{orderId}}`).
  * **A data transformer**: Every [data transformer](/build/data-transformers) in your account is listed after **Static Value**. Pick one, then fill in each of its inputs, which can include `{{variables}}`. The result is saved to the variable. See [Use a transformer in Set Variable and Decision steps](/build/data-transformers#use-a-transformer-in-set-variable-and-decision-steps) for how the inputs work. If the transformer fails on real data, what is saved depends on how many inputs it has — see [When a transformer fails during a conversation](/build/data-transformers#when-a-transformer-fails-during-a-conversation).
* **Required**: Every assignment needs a variable and either a value or all of its transformer's inputs before the node can be saved.

Use cases:

* Store a computed or default value mid-flow (e.g. set `transferReason` before a handoff).
* Overwrite a Pre-conversation variable with updated information gathered during the conversation.

> [!NOTE]
>
> A value set here is saved for the nodes that come after it. It isn't sent to the agent unless you pass it back with an [AI Context](#ai-context-node) node.

### Decision Node

Add conditional branching to your flow based on variable values.

* **Condition**: Click **Add Condition** to define each one. A condition has a **Condition Rule** (a data transformer, such as **Compare**), the **Input Values** to test (e.g. check that `{{accountStatus}}` equals `active`) and a **Go To Node**.
* **Branches**: Each condition routes to its own downstream node, and **Otherwise** catches everything that matches none of them.

How a Decision runs:

1. Conditions are checked from top to bottom (**Condition 1**, **Condition 2**, and so on). The first one whose data transformer returns `true` wins and the rest aren't checked, so put the most specific condition first. For how **Compare** and **Conditions** decide true or false, see [Behaviour worth knowing](/build/data-transformers#behaviour-worth-knowing).
2. A condition that returns anything other than `true`, or can't produce a result, is skipped and the next one is checked.
3. If no condition is `true`, the flow continues from **Otherwise**.

Setting up the branches:

* **Go To Node**: Choose where the flow goes for a condition, or for **Otherwise**. Pick an existing node under the Decision, or add a new node under **Add New Node**. A new node can be any type except another Decision.
* **Otherwise is required**: The node can't be saved until **Otherwise** has a **Go To Node**, even if the Decision has no conditions. Each condition also needs its rule, all of its inputs and a **Go To Node**.
* **Delete a condition**: Click the **×** on its card, then **Delete Condition**. Everything under that condition is removed when you save the node, and this can't be undone.

Use cases:

* Route the flow differently based on customer data (e.g. VIP vs. standard customer).
* Skip an API call when a required variable is missing.
* Gate actions behind boolean checks from Data Transformers.

> [!NOTE]
>
> Decision node outcomes are recorded in the conversation's action log, so you can review which branch was taken for every conversation.

### AI Context Node

Choose what the AI agent is told when this action finishes. Each variable listed in an AI Context node is handed to the agent with its name and current value, as part of the action's result, alongside any API responses from the flow. The agent uses it to decide what to say next.

Find **AI Context** under **Actions** in the palette, drop it under the node it should follow, then click the node to configure it.

* **Variables**: Click **Add Variable**, then pick a variable in the **Select or create variable** field. To create one, type a new name and click **Add Variable** beside it; it's marked **(new)** and created as a custom variable when you save the node. Names can use only letters, numbers and underscores, and can't end with an underscore. Built-in `interaction.` variables, such as `interaction.ANI`, aren't offered here. Remove a variable with the **×** at the top-right of its card.
* **Required**: Add at least one variable and fill every row. A row marked *Not set* stops the node from saving.
* **Value**: A variable is passed with the value it holds when the node runs, so place the node after the nodes that set it. A variable with no value yet is passed with no value.
* **Repeats**: If the same variable is added more than once, in the same node or a later one, only its latest value is sent.

If the flow passes nothing back (no AI Context node runs and no API response is added), the agent is only told that the action ran. Say messages and Set Variable values don't add to the result on their own.

Use cases:

* **Add context conditionally**: Put an AI Context node on each branch of a Decision node, so the agent hears different information depending on which branch the conversation takes. For example, add a condition that uses a **Compare** [data transformer](/build/data-transformers) to check whether `{{tier}}` equals `gold` and send it to an AI Context node that passes `loyaltyOffer`, then send **Otherwise** to an AI Context node that passes `standardOffer`. Both variables need a value earlier in the flow, or from a Pre-conversation Action.
* **Give the agent a fixed response**: Use a Set Variable node to give a variable a fixed value, then pass it with an AI Context node. The agent receives it as the action's result, with no API call.
* **Mock an API response**: While an API isn't ready yet, or to test a flow without calling it, use the same pattern to stand in for the API Request node: set a variable such as `orderStatus` to the response you expect (for example `shipped`) and pass it to the agent. A value you type is passed as plain text, so a pasted JSON response reaches the agent as text rather than as separate fields. When the real API is ready, replace the Set Variable node with an API Request node. Its response reaches the agent on its own, so keep the AI Context node only if you also want to pass a mapped variable, and check that the agent's guidelines still match the names the real response uses.

> [!NOTE]
>
> The AI Context node is available only in In-conversation Action flows, because it adds to the result of an action the agent calls during the conversation. Pre- and Post-conversation Actions run before the first message and after the conversation ends, with no request from the agent waiting on a result, so their flows don't offer it. To use a Pre-conversation value, save it to a variable and reference it in the **Greeting message** or Guidelines.

> [!NOTE]
>
> Each AI Context node run is recorded in the conversation's action log. Turn on **Action Logs** in the transcript and expand the action: the node's **Context Variables** list shows each variable as **Stored** (passed to the agent) or **Not stored**, and clicking a variable shows its value.

### Reopen, Edit and Save a Flow

* **Reopen a flow**: Open the **In-conversation Actions** card on your agent and click **Go to Flow** on the action's card.
* **Edit a node**: Click the node to open its settings. You can also right-click it, or use the **…** button that appears when you hover over it, and choose **Edit Node**. The drawer shows the node's **Name** and **Description** along with its settings.
* **Delete a node**: Choose **Delete Node** from the same menu and confirm. The nodes before and after it are joined back together. You can't delete the Start node, or a node that sits directly under a Decision branch. On a Decision that has nodes under it, the menu shows **Delete Branch** instead of **Delete Node**. It removes the Decision and every node under it, and this can't be undone. To remove just one condition's nodes, delete that condition in the Decision's settings.
* **Saving**: Adding, editing and deleting nodes saves the flow automatically, and a **Flow saved** message appears. **Save Flow** at the top right saves the flow as it stands on the canvas. A saved action and its flow are part of the agent's draft: on an agent you've published, live conversations keep running the flow as it was published until you **Publish** again, while **Talk** and **Chat** use your latest changes (see [What Waits for Publish](/build/ai-agents#what-waits-for-publish)).

### Find a Node on the Canvas

Large flows are easier to navigate with the search box in the **top-right corner of the canvas**.

* **Search by name or type**: Type any part of a node's name, or a node type such as `decision` or `api`, to match every node of that kind. Matching is case-insensitive. Node *contents* — prompt text, URLs, variable values — are not searched.
* **See every match at once**: Every matching node on the canvas is ringed in amber while the search is active.
* **Jump to a node**: Pick a result to pan and centre the canvas on it. Moving through the results with the arrow keys previews each node the same way.
* **Restore your view**: Clearing or dismissing the search returns the canvas to exactly where it was.

> [!NOTE]
>
> There are two search boxes in the flow editor and they do different jobs. **Search node types…** in the left sidebar filters the palette of nodes you can *add*. **Search nodes by name or type…** in the top-right searches the nodes already *placed* on the canvas.

## Visibility & Logging

Every in-conversation action execution is automatically recorded:

* **Live Transcript**: Action invocations and results appear inline alongside the conversation, so you can follow along in real time.
* **Action Logs**: A detailed log of each action execution—including decision node outcomes—is kept with the conversation record for review after it ends. For calls you will find it in [Call History](/analyze/call-history).

Turn on **Action Logs** in the transcript and expand an action to see what each step did:

* **Parameters**: The values the agent passed to the action.
* **Say**: **Text Played** is the message that was delivered, and **Detected Language** is the language detected in the conversation.
* **API Request**: The request (**Headers**, **Query Params**, **Request Body**), the **Response** and the **Updated Variables**.
* **Set Variable**: **Assigned Variables** lists each variable that was set. Expand one to see its **Old value** and **New value**.
* **Decision**: **Matched** shows the condition that matched, or **Otherwise**, and **Next Node** shows where the flow went. **Evaluated Conditions** lists each condition as **Matched** or **Not matched**, with its **Transformer**, **Result**, **Next If True** and **Inputs**.
* **AI Context**: **Context Variables**, as described under [AI Context Node](#ai-context-node).
* **Added Context**: What was handed back to the agent as the action's result.

## Best Practices

* Start with simple flows: Say -> API Request -> Say.
* Use descriptive parameter names and clear descriptions to help the AI collect inputs reliably.


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