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

# Steps

> Steps are the building blocks of an automation pipeline. Each step performs a specific action — transforming data, creating contacts, placing calls, syncing to CRMs, or sending notifications.

## Overview

Steps execute in order from top to bottom. Each step reads from and writes to a shared context object that carries data through the pipeline. You can add up to 20 steps per automation.

To add a step, click **+ Add step** in the pipeline builder and select the step type.

***

## Step Types

### Transform

Reshape and map data from one format to another. Transforms are typically used to:

* Map incoming webhook fields to contact fields before an Upsert Contact step
* Map call results to CRM column identifiers before a Destination step

**Configuration:**

Add one or more field mappings. Each mapping has:

| Field         | Description                                                                                                    |
| ------------- | -------------------------------------------------------------------------------------------------------------- |
| **Source**    | The field to read from (e.g., `trigger.phone`, `call.call_summary`)                                            |
| **Target**    | The field to write to (e.g., `contact.phone_number`, `long_text_7`)                                            |
| **Transform** | Optional transformation: `uppercase`, `lowercase`, `truncate:100`, `date:YYYY-MM-DD`, `to_string`, `to_number` |

**Example — mapping webhook fields for a contact:**

| Source               | Target                 |
| -------------------- | ---------------------- |
| `trigger.phone`      | `contact.phone_number` |
| `trigger.first_name` | `contact.first_name`   |
| `trigger.last_name`  | `contact.last_name`    |

Transform results are written to `mapped.*` in the context and are available to all subsequent steps.

***

### Upsert Contact

Create a new contact in Voxworks or update an existing one. The step matches on either phone number or email to determine whether to create or update.

**Configuration:**

| Field              | Description                                                                                             |
| ------------------ | ------------------------------------------------------------------------------------------------------- |
| **Match on**       | How to find existing contacts: `phone_number` or `email`                                                |
| **Field mappings** | Map context fields to contact fields (phone\_number, first\_name, last\_name, email, address, location) |

After this step runs, `contact.*` is available in the context for all subsequent steps.

**Example:**

Match on `phone_number`, with mappings:

| Source               | Target         |
| -------------------- | -------------- |
| `trigger.phone`      | `phone_number` |
| `trigger.first_name` | `first_name`   |
| `trigger.last_name`  | `last_name`    |

If a contact with that phone number already exists, their name fields are updated. If not, a new contact is created.

***

### Upsert Object

Create or update a typed data object and optionally link it to the contact. Objects store CRM identifiers and external data that your automation needs to reference later — for example, a Monday.com item ID or a HubSpot deal ID.

**Configuration:**

| Field               | Description                                                        |
| ------------------- | ------------------------------------------------------------------ |
| **Object type**     | The type of object to create (e.g., `monday_item`, `hubspot_deal`) |
| **Match on**        | The field within the object data to match against (e.g., `CRM_ID`) |
| **Match value**     | The source path for the match value (e.g., `trigger.crm_id`)       |
| **Link to contact** | Whether to link this object to the current contact in context      |
| **Field mappings**  | Map context fields to object data fields                           |

After this step runs, the object's data is available at `objects.{type_name}.*`.

**Example:**

Object type: `monday_item`, match on `CRM_ID` = `trigger.crm_id`, link to contact: yes.

| Source             | Target     |
| ------------------ | ---------- |
| `trigger.crm_id`   | `CRM_ID`   |
| `trigger.board_id` | `board_id` |
| `trigger.source`   | `source`   |

***

### Create Call

Trigger an outbound call using a specific Script. This step creates a call record and schedules it for immediate execution (or at a specified time).

**Configuration:**

| Field           | Description                                                                |
| --------------- | -------------------------------------------------------------------------- |
| **Script**      | The Script to use for the call                                             |
| **Phone field** | Context path to the phone number (e.g., `contact.phone_number`)            |
| **From number** | The outbound phone number to call from (optional, uses default if not set) |

**Important: Pipeline split.** Any steps placed after Create Call become **post-call steps**. They do not execute until the call finishes and the AI has generated the summary and structured data. The pipeline builder shows a visual divider: "after call completes".

After the call completes, `call.*` is populated with the full call record including summary, transcript, structured data, and objectives.

***

### Destination

Push data to an external system. There are four destination types:

#### Integration Sync

Sync data to a connected CRM (e.g., Monday.com). Uses field mappings to map call outputs and object data to integration-specific column identifiers.

| Source                         | Target        |
| ------------------------------ | ------------- |
| `call.call_summary`            | `long_text_7` |
| `call.status`                  | `status_1`    |
| `call.duration`                | `numbers_3`   |
| `objects.monday_item.CRM_ID`   | `item_id`     |
| `objects.monday_item.board_id` | `board_id`    |

The target field names correspond to column IDs in your CRM. You'll find these in your CRM's column settings.

#### Email

Send an email to the contact, your team members, or a specific address. Email subjects and bodies support `{{variable}}` interpolation.

| Field         | Description                                                                                                                 |
| ------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **To**        | `contact` (uses contact.email), `team` (sends to selected members), or a specific email address                             |
| **Subject**   | Email subject with variable support (e.g., `Your call summary - {{contact.full_name}}`)                                     |
| **Body**      | HTML email body with variable support (e.g., `Hi {{contact.first_name}}, here is your call summary: {{call.call_summary}}`) |
| **From name** | Display name for the sender (defaults to your team name)                                                                    |
| **Reply to**  | Reply-to address (defaults to team owner email)                                                                             |

#### SMS

Send a text message to the contact or to team members.

| Field        | Description                                                                 |
| ------------ | --------------------------------------------------------------------------- |
| **SMS type** | `contact` (sends to the contact) or `team` (sends to selected team members) |
| **To**       | Phone field path for contact SMS (e.g., `contact.phone_number`)             |
| **Template** | Message text with `{{variable}}` interpolation                              |
| **Members**  | For team SMS, which team members to notify                                  |

#### Webhook

Send an HTTP request to any URL. Useful for integrating with systems that don't have a native integration.

| Field             | Description                                 |
| ----------------- | ------------------------------------------- |
| **URL**           | The destination URL (must be HTTPS)         |
| **Method**        | `POST` or `PUT`                             |
| **Headers**       | Custom HTTP headers (optional)              |
| **Body template** | JSON body with `{{variable}}` interpolation |

***

### Condition

Branch the pipeline based on a field value. If the condition is true, the **on\_true** steps run. If false, the optional **on\_false** steps run (or the condition is skipped).

**Configuration:**

| Field        | Description                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------ |
| **Field**    | Context path to evaluate (e.g., `call.status`, `call.end_reason`, `call.structured_data.rating`) |
| **Operator** | `eq`, `neq`, `gt`, `lt`, `gte`, `lte`, `in`, `exists`                                            |
| **Value**    | The value to compare against                                                                     |

**Example — notify team on low rating:**

* Field: `call.structured_data.rating`
* Operator: `lt`
* Value: `3`
* On true: SMS to team — "Low rating call: \{\{contact.full\_name}}"
* On false: (skip)

Conditions can be nested up to 2 levels deep.

***

### Source

Fetch data from an external API or connected integration. The response is written to `source.*` in the context.

**Configuration (HTTP):**

| Field             | Description                                              |
| ----------------- | -------------------------------------------------------- |
| **URL**           | The API endpoint (supports `{{variable}}` interpolation) |
| **Method**        | `GET` or `POST`                                          |
| **Headers**       | Custom HTTP headers (optional)                           |
| **Body template** | Request body for POST requests (optional)                |

**Configuration (Integration Fetch):**

| Field           | Description                             |
| --------------- | --------------------------------------- |
| **Integration** | The connected integration to fetch from |

The fetched data is resolved at runtime using object identifiers from the context (e.g., the contact's linked CRM item ID).

***

## Limits

| Limit                            | Value      |
| -------------------------------- | ---------- |
| Max steps per automation         | 20         |
| Max condition nesting depth      | 2 levels   |
| Max field mappings per transform | 50         |
| Max execution time per step      | 30 seconds |
| Max total execution time         | 5 minutes  |
