> ## 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.

# Post-conversation Actions

> Run follow-up work after a conversation ends, powered by flows

Configure visual flows that execute when the conversation completes. Use flow nodes to push summaries, transcripts, and variables to your CRM or external systems when the conversation ends.

## Overview

* **When it runs**: After the conversation ends (asynchronously).
* **Typical tasks**:
  * Send the conversation's summary and disposition to your CRM or ticketing system
  * Persist the transcript to CRM or data warehouse
  * Trigger downstream workflows (e.g. ticket creation)

SquawkVoice creates the summary and records the disposition when the conversation ends, before your flow runs, so your flow doesn't need to produce them. Use them in any node as `{{interaction.SUMMARY}}`, `{{interaction.BRIEF_SUMMARY}}` (a shorter version) and `{{interaction.DISPOSITION}}`. The transcript is available as `{{interaction.TRANSCRIPT}}`. `{{interaction.CALL_DURATION}}` is the length of the conversation in seconds (it reads 0 for an email conversation), and `{{interaction.TRANSFER_DESTINATION}}` is the phone number or SIP address a call was transferred to, when the agent transferred it. See [Available Interaction Variables](/essentials/call-lifecycle-hooks#available-interaction-variables) for the full list.

## Create a Post-conversation Action Flow

1. Open **Build → AI Agents**, open your agent, then select the **Post-conversation Actions** card under **Actions & Integrations**.
2. Select **Create New Action** and fill in:
   * **Name**: Short, descriptive identifier. It must be different from every other action on the agent, across its pre-, in- and post-conversation actions, ignoring capital letters and surrounding spaces. A name that's already taken is refused with a message naming the action that has it.
   * **Description**: What the action does and why
   * **Execute on channels**: Which channels the action runs on — **Voice**, **Chat** or **Email**, in any combination (at least one must be selected). New actions start with **Voice** only.
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.

To open a flow again later, select **Go to Flow** on the action's card. Each card also shows the channels the action runs on, and its menu lets you edit, duplicate, copy to another agent or delete the action — see [AI Agents](/build/ai-agents) for duplicating and copying.

## Channel Scoping

Post-conversation actions can be scoped to run only on specific channels — for example, log a ticket only for voice calls, or send a chat transcript email only for chat sessions. An action is skipped on any channel that isn't ticked under **Execute on channels**.

* Existing and newly created actions default to **Voice** only. If your agent also handles chat or email, tick **Chat** or **Email** under **Execute on channels** on each action that should run there; otherwise it's skipped on that channel.
* An action with **Email** ticked runs for email agents' conversations. See [Email Agents](/build/ai-agents/email-agents) for when post-conversation actions run on email.
* To branch *within* a shared flow instead, use the built-in `interaction.CHANNEL` variable (resolves to `voice`, `chat` or `email`) in a Decision node.

## Flow Builder

The flow defines what happens when the conversation ends. Drag nodes from the node palette on the left, grouped as **Flow Control** (Decision) and **Actions** (API Request, Set Variable), and drop each one on the **Drop to connect** area under the node it should follow, starting from the Start node. You don't draw connections by hand. A node dropped in the middle of a chain is inserted there. Dropping a Decision node opens its settings first, and the nodes under a Decision are chosen in its **Go To Node** fields. In a large flow, use the search box in the top-right of the canvas to jump to a node by name or type — see [Find a Node on the Canvas](/build/ai-agents/in-conversation-actions#find-a-node-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)).

### API Request Node

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

* **Method**: GET, POST, PUT, DELETE, PATCH
* **URL**: The endpoint. You can include variables, e.g. `https://api.example.com/customers/{{customerId}}`.
* **Query Params**: Key-value pairs, variable-aware (the **Params** tab)
* **Headers**: Static or variable-aware (e.g. `Authorization`)
* **Body**: Choose a **Body Type** of **None**, **JSON**, **Text**, **XML** or **x-www-form-urlencoded** (a table of key-value pairs). Variables supported, e.g. passing `{{interaction.SUMMARY}}` and `{{interaction.TRANSCRIPT}}` in a JSON body. **Body Type** is locked to **None** when the method is GET.
* **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 the response in the **Data** or **Meta** tabs
* **JSON Path Expressions**: Under the response, click a value in the **Data** or **Meta** view to add its path, or type one such as `$.data.ticket.id`. Pick a **Variable** for each path (e.g. save the ticket number to `{{ticketNumber}}`). Built-in variables such as `interaction.ANI` or `agent.TIMEZONE`, and campaign variables, can't be used as the target, and every path needs a variable before the node can be saved. An optional **Default Value** is used when the path isn't found in the response or is empty.

> [!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: put quotes around a variable to send it as text, as in `{"summary": "{{interaction.SUMMARY}}"}`. A variable on its own, without quotes, is sent as a JSON value rather than text, so quote any value an API expects as a string. See [Using variables in a JSON body](/build/ai-agents/in-conversation-actions#api-request-node) for the full rules.

### Set Variable Node

Assign or overwrite variable values at any point in the flow without making an API call, for example to hold a value calculated from the conversation's outcome. One node can set several variables.

* **Add Variable**: Adds another assignment to the node. Each assignment has a **Variable** and a **Transformation Logic**.
* **Variable**: Choose an existing variable or create a new one. Built-in call variables, system variables and campaign variables can't be set with this node, so they aren't offered.
* **Transformation Logic**: Choose how the value is worked out.
  * **Static Value**: Enter a fixed value or reference another variable (e.g. `{{interaction.DISPOSITION}}`). It can't be left empty.
  * **A data transformer**: Every saved [Data Transformer](/build/data-transformers) 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 the [Set Variable Node](/build/ai-agents/in-conversation-actions#set-variable-node) on In-conversation Actions for more.

### Decision Node

Route post-conversation logic conditionally, for example only calling your ticketing API for some outcomes:

* **Condition**: Select **Add Condition** for each one. A condition has a **Condition Rule**, the **Input Values** to test, and a **Go To Node**. The **Condition Rule** is one of your saved [Data Transformers](/build/data-transformers), and the condition matches when that transformer returns `true`. Create the transformer you need first, because the list shows only saved ones.
* **Branches**: Each condition routes to its own downstream node, and **Otherwise** catches everything that matches none of them. Conditions are checked from top to bottom, and the first one that returns `true` wins. **Otherwise** also needs a **Go To Node**, and the node can't be saved without one.

For example, to open a follow-up ticket only when a caller hung up before being helped, create a Data Transformer called `Caller hung up` with one **Compare** step: set its **Input** to `{{input1}}`, **Operator** to **Equal To** and **Value** to `Caller-Hungup`. In the Decision, add a condition, choose `Caller hung up` as the **Condition Rule**, and enter `{{interaction.DISPOSITION}}` as the value for `input1`. Then choose the API Request node that creates the ticket under **Go To Node**. To test one of your own outcome options instead, enter its name as the **Value**.

`{{interaction.DISPOSITION}}` is the exact name of an outcome, and **Compare** is case sensitive by default, so match the capital letters, hyphens and spaces. See [Available Interaction Variables](/essentials/call-lifecycle-hooks#available-interaction-variables) for the values a call can have.

> [!NOTE]
>
> A **Decision** the [Co-pilot](/build/squawk-copilot) adds arrives with its **Otherwise** path unconnected, because these flows can't hold a **Say** step to fill it. Connect it yourself in the editor, or ask the Co-pilot to.

> [!NOTE]
>
> Post-conversation flows do not support **Say** nodes as the conversation has already ended. The **AI Context** node isn't offered here either.

## Best Practices

* Keep post-conversation operations idempotent; the same payload may be retried.
* If you need both summary and transcript, design your backend to accept a single payload in the API Request node to minimize network calls.
* Store external IDs (e.g. ticket number) for cross-system traceability.


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