# Actions

An **Action** is a single executable step within a workflow. Actions are processed sequentially. If an action includes a `conditions` array, the platform evaluates those conditions first; if they are not satisfied, the action is skipped and execution continues with the next action.

## Action Properties

| Property           | Type                                                                                                                                                                                                 | Required | Default | Constraints                    | Description                                                                  |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ------------------------------ | ---------------------------------------------------------------------------- |
| `name`             | string                                                                                                                                                                                               | No       | —       | Must not start with `nm:`      | Unique identifier for this action. Used as a target by `execute` and `goto`. |
| `conditions`       | array of [Condition](https://playbook.nativemsg.com/rcs-experience-schema/reference/broken-reference) \| [Operator](https://playbook.nativemsg.com/rcs-experience-schema/reference/broken-reference) | No       | —       | —                              | Predicates controlling whether this action executes.                         |
| `validation`       | [Validation](https://playbook.nativemsg.com/rcs-experience-schema/reference/broken-reference)                                                                                                        | No       | —       | —                              | Attribute validation applied before this action executes.                    |
| `channel`          | string                                                                                                                                                                                               | No       | —       | e.g. `"rcs"`, `"dsc"`, `"dlc"` | Restricts this action to a specific channel type.                            |
| `send`             | [SendAction](#sendaction)                                                                                                                                                                            | No       | —       | —                              | Delivers a message, email, HTTP request, note, RSS feed, or data population. |
| `waitFor`          | [WaitForAction](#waitforaction)                                                                                                                                                                      | No       | —       | —                              | Pauses execution to collect user input.                                      |
| `delay`            | [DelayAction](#delayaction)                                                                                                                                                                          | No       | —       | —                              | Pauses execution for a fixed duration.                                       |
| `execute`          | string \| array of string                                                                                                                                                                            | No       | —       | —                              | Executes one or more named workflows or actions.                             |
| `goto`             | string                                                                                                                                                                                               | No       | —       | —                              | Transfers execution to a named workflow or action.                           |
| `assignTags`       | string \| array of string                                                                                                                                                                            | No       | —       | —                              | Assigns one or more tags to the conversation.                                |
| `assignAttributes` | [AssignAttributesAction](#assignattributesaction)                                                                                                                                                    | No       | —       | —                              | Assigns or updates named attributes.                                         |
| `updateAttribute`  | [UpdateAttributeAction](#updateattributeaction)                                                                                                                                                      | No       | —       | —                              | Updates a single attribute with transformation options.                      |
| `subscribe`        | boolean                                                                                                                                                                                              | No       | —       | —                              | Subscribes the contact to the current channel when `true`.                   |
| `updateSettings`   | [UpdateSettingsAction](#updatesettingsaction)                                                                                                                                                        | No       | —       | —                              | Updates experience or conversation settings at runtime.                      |
| `pause`            | [PauseAction](#pauseaction)                                                                                                                                                                          | No       | —       | —                              | Inserts a short pause (typing indicator) before the next action.             |

{% hint style="info" %}
An action with no primary operation property (no `send`, `waitFor`, `delay`, etc.) is valid — it can exist solely for its `conditions`, `assignTags`, or `assignAttributes` side effects.
{% endhint %}

## SendAction

The `send` property delivers content to the user or an external system. At most one sub-property SHOULD be populated per `send` object.

| Property   | Type                                                                                       | Required | Description                              |
| ---------- | ------------------------------------------------------------------------------------------ | -------- | ---------------------------------------- |
| `message`  | [Message](https://playbook.nativemsg.com/rcs-experience-schema/reference/broken-reference) | No       | Sends a message to the user.             |
| `email`    | [EmailAction](#emailaction)                                                                | No       | Sends an email.                          |
| `request`  | [RequestAction](#requestaction)                                                            | No       | Sends an HTTP request.                   |
| `json`     | object \| array                                                                            | No       | Sends a raw JSON payload.                |
| `note`     | [NoteAction](#noteaction)                                                                  | No       | Sends an internal note.                  |
| `rss`      | [RssAction](#rssaction)                                                                    | No       | Fetches and renders an RSS feed.         |
| `populate` | [PopulateData](#populatedata)                                                              | No       | Populates attributes from a data source. |

### EmailAction

Sends an email from within a workflow.

| Property  | Type                      | Required | Default | Constraints             | Description                                          |
| --------- | ------------------------- | -------- | ------- | ----------------------- | ---------------------------------------------------- |
| `to`      | string \| array of string | **Yes**  | —       | Valid email address(es) | Recipient address(es).                               |
| `cc`      | string \| array of string | No       | —       | Valid email address(es) | CC recipient(s).                                     |
| `bcc`     | string \| array of string | No       | —       | Valid email address(es) | BCC recipient(s).                                    |
| `subject` | string                    | No       | —       | —                       | Email subject line. Supports attribute placeholders. |
| `text`    | string                    | No       | —       | —                       | Email body. Supports attribute placeholders.         |
| `isHtml`  | boolean                   | No       | `false` | —                       | When `true`, the `text` body is rendered as HTML.    |

{% code title="email-action.json" %}

```json
{
  "send": {
    "email": {
      "to": "support-team@acme.com",
      "cc": "manager@acme.com",
      "subject": "New support request from {contactName}",
      "text": "Contact: {contactName}\nPhone: {contactPhone}\nIssue: {issueDescription}",
      "isHtml": false
    }
  }
}
```

{% endcode %}

### RequestAction

Sends an HTTP request and optionally maps the response into attributes.

| Property          | Type             | Required    | Default  | Constraints                                       | Description                                                                              |
| ----------------- | ---------------- | ----------- | -------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `url`             | string           | **Yes**     | —        | Must be a valid URL or `{attribute}` placeholder  | Request URL. Supports attribute placeholders.                                            |
| `method`          | string           | No          | `"GET"`  | `GET`, `POST`, `PUT`, `PATCH`, `DELETE`           | HTTP method.                                                                             |
| `dataFormat`      | string           | No          | `"text"` | `text`, `json`, `form`                            | Request body format.                                                                     |
| `headers`         | object           | No          | —        | Map of string → string                            | HTTP request headers.                                                                    |
| `content`         | string \| object | Conditional | —        | Required when method is `POST`, `PUT`, or `PATCH` | Request body.                                                                            |
| `response`        | string \| object | No          | —        | —                                                 | Attribute name or mapping object for storing the response body.                          |
| `responseHeaders` | string \| object | No          | —        | —                                                 | Attribute name or mapping for storing response headers.                                  |
| `retries`         | integer          | No          | `0`      | minimum: 0                                        | Number of retry attempts on failure.                                                     |
| `fallback`        | string           | No          | —        | —                                                 | Workflow or action to execute on request failure.                                        |
| `process`         | boolean          | No          | `true`   | —                                                 | When `true`, attribute placeholders in `content` are substituted before sending.         |
| `async`           | boolean          | No          | `false`  | —                                                 | When `true`, the request is sent asynchronously and execution continues without waiting. |
| `allowHtml`       | boolean          | No          | `false`  | —                                                 | When `true`, HTML in the response is not sanitized.                                      |

{% hint style="danger" %}
`content` is required when `method` is `POST`, `PUT`, or `PATCH`. Omitting it when using these methods produces a validation error.
{% endhint %}

{% hint style="danger" %}
When `dataFormat` is `"json"` and `method` is `POST`, `PUT`, or `PATCH`, the `content` field MUST be a JSON object or a string beginning with `{`.
{% endhint %}

{% code title="request-action-get.json" %}

```json
{
  "send": {
    "request": {
      "url": "https://api.acme.com/v1/orders/{orderNumber}",
      "method": "GET",
      "headers": {
        "Authorization": "Bearer {apiToken}",
        "Accept": "application/json"
      },
      "dataFormat": "json",
      "response": {
        "status": "orderStatus",
        "estimatedDelivery": "deliveryDate"
      },
      "retries": 2,
      "fallback": "api-error-handler"
    }
  }
}
```

{% endcode %}

POST example:

{% code title="request-action-post.json" %}

```json
{
  "send": {
    "request": {
      "url": "https://api.acme.com/v1/leads",
      "method": "POST",
      "dataFormat": "json",
      "headers": {
        "Content-Type": "application/json",
        "Authorization": "Bearer {apiToken}"
      },
      "content": {
        "name": "{contactName}",
        "phone": "{contactPhone}",
        "source": "rcs_chat"
      },
      "response": "leadId",
      "retries": 1,
      "fallback": "lead-creation-failed"
    }
  }
}
```

{% endcode %}

### NoteAction

Sends an internal note (not visible to the end user).

| Property         | Type                      | Required | Default | Constraints | Description                                                     |
| ---------------- | ------------------------- | -------- | ------- | ----------- | --------------------------------------------------------------- |
| `text`           | string                    | **Yes**  | —       | —           | Note content. Supports attribute placeholders.                  |
| `channelId`      | integer \| null           | No       | —       | —           | Target channel ID for the note.                                 |
| `recipientPhone` | string \| null            | No       | —       | —           | Phone number of the recipient. Supports attribute placeholders. |
| `executeOnError` | string \| array of string | No       | —       | —           | Workflow or action to execute on error.                         |

{% code title="note-action.json" %}

```json
{
  "send": {
    "note": {
      "text": "Customer {contactName} requested a refund for order {orderNumber}. Escalation required.",
      "channelId": 42
    }
  }
}
```

{% endcode %}

### RSSAction

Fetches an RSS feed and renders it as a carousel or list.

| Property         | Type   | Required | Default      | Constraints            | Description                 |
| ---------------- | ------ | -------- | ------------ | ---------------------- | --------------------------- |
| `url`            | string | **Yes**  | —            | format: uri            | URL of the RSS feed.        |
| `preferedLayout` | string | No       | `"carousel"` | `"list"`, `"carousel"` | Preferred rendering layout. |

{% code title="rss-action.json" %}

```json
{
  "send": {
    "rss": {
      "url": "https://blog.acme.com/feed.xml",
      "preferedLayout": "carousel"
    }
  }
}
```

{% endcode %}

### PopulateData

Populates attributes from a data source.

| Property               | Type            | Required | Default | Constraints | Description                                   |
| ---------------------- | --------------- | -------- | ------- | ----------- | --------------------------------------------- |
| `from`                 | string \| null  | No       | —       | —           | Source attribute name.                        |
| `attribute`            | string \| null  | No       | —       | —           | Target attribute name.                        |
| `allowInnerAttributes` | boolean \| null | No       | `true`  | —           | Whether to allow nested attribute resolution. |

{% code title="populate-data.json" %}

```json
{
  "send": {
    "populate": {
      "from": "apiResponseData",
      "attribute": "productList",
      "allowInnerAttributes": true
    }
  }
}
```

{% endcode %}

## WaitForAction

Pauses workflow execution until the user provides input of the specified type.

| Property           | Type                      | Required | Default | Constraints                        | Description                                               |
| ------------------ | ------------------------- | -------- | ------- | ---------------------------------- | --------------------------------------------------------- |
| `data`             | string \| array of string | **Yes**  | —       | See enum values                    | Type(s) of data to accept from the user.                  |
| `content`          | string                    | **Yes**  | —       | Pattern: `^[a-zA-Z][a-zA-Z0-9_]*$` | Attribute name in which to store the received input.      |
| `keywords`         | array of KeywordCapture   | No       | —       | —                                  | Keyword-to-attribute mappings recognized during the wait. |
| `executeOnError`   | string \| array of string | No       | —       | —                                  | Target(s) to execute when input fails validation.         |
| `executeOnTimeout` | string \| array of string | No       | —       | —                                  | Target(s) to execute when the wait times out.             |
| `timeout`          | string                    | No       | —       | e.g. `"30s"`, `"5m"`, `"1h"`       | Duration after which the timeout handler fires.           |

**Accepted `data` values:**

| Value            | Description                     |
| ---------------- | ------------------------------- |
| `"message"`      | Any message, including media    |
| `"text"`         | Plain text input                |
| `"quick reply"`  | Quick reply selection           |
| `"multi select"` | Multiple quick reply selections |
| `"number"`       | Numeric input                   |
| `"money"`        | Monetary amount                 |
| `"distance"`     | Distance measurement            |
| `"coordinates"`  | Geographic coordinates          |
| `"datetime"`     | Date and/or time                |
| `"file"`         | File attachment                 |

{% hint style="danger" %}
Both `data` and `content` are required in a `waitFor` object. The `content` value MUST match the pattern `^[a-zA-Z][a-zA-Z0-9_]*$`.
{% endhint %}

KeywordCapture sub-object:

| Property    | Type   | Required | Description                                            |
| ----------- | ------ | -------- | ------------------------------------------------------ |
| `name`      | string | **Yes**  | Keyword name to watch for.                             |
| `attribute` | string | **Yes**  | Attribute in which to store the matched keyword value. |

{% code title="waitfor-action.json" %}

```json
{
  "waitFor": {
    "data": "text",
    "content": "userEmail",
    "timeout": "5m",
    "executeOnTimeout": "email-capture-timeout",
    "executeOnError": "invalid-email-format"
  }
}
```

{% endcode %}

## DelayAction

Pauses execution for a fixed amount of time, with optional timeout routing.

| Property           | Type                      | Required | Default | Constraints | Description                           |
| ------------------ | ------------------------- | -------- | ------- | ----------- | ------------------------------------- |
| `seconds`          | integer                   | No       | —       | minimum: 0  | Delay duration in seconds.            |
| `milliseconds`     | integer                   | No       | —       | minimum: 0  | Delay duration in milliseconds.       |
| `executeOnTimeout` | string \| array of string | No       | —       | —           | Target(s) to execute after the delay. |
| `timeout`          | string                    | No       | —       | —           | Alternative timeout duration string.  |

{% code title="delay-action.json" %}

```json
{
  "delay": {
    "seconds": 3
  }
}
```

{% endcode %}

## Execute

Executes one or more named workflows or actions by name. Use `execute` when you want to run a sub-workflow and then continue in the current workflow. Contrast with `goto`, which does not return.

| Form             | Type            | Description                            |
| ---------------- | --------------- | -------------------------------------- |
| Single target    | string          | Executes the named workflow or action. |
| Multiple targets | array of string | Executes each named target in order.   |

{% code title="execute-single.json" %}

```json
{
  "execute": "send-confirmation-message"
}
```

{% endcode %}

{% code title="execute-multiple.json" %}

```json
{
  "execute": ["log-event", "send-confirmation-message", "notify-agent"]
}
```

{% endcode %}

## Goto

Transfers execution to a named workflow or action. Unlike `execute`, `goto` does not return to the current workflow after the target completes.

{% code title="goto.json" %}

```json
{
  "goto": "main-menu"
}
```

{% endcode %}

## AssignTags

Assigns one or more tags to the conversation.

| Form          | Type            | Description             |
| ------------- | --------------- | ----------------------- |
| Single tag    | string          | Assigns the named tag.  |
| Multiple tags | array of string | Assigns each named tag. |

{% code title="assign-tags.json" %}

```json
{
  "assignTags": ["vip-customer", "order-inquiry"]
}
```

{% endcode %}

## AssignAttributesAction

Assigns or updates multiple attributes in a single action.

| Property                 | Type                                              | Required | Default | Constraints | Description                                                           |
| ------------------------ | ------------------------------------------------- | -------- | ------- | ----------- | --------------------------------------------------------------------- |
| `attributes`             | array of [AttributeValue](#attributevalue)        | **Yes**  | —       | —           | List of attribute assignments.                                        |
| `value`                  | string \| object \| array \| null                 | No       | —       | —           | Default value applied when an `AttributeValue` has no explicit value. |
| `replace`                | string \| null                                    | No       | —       | —           | Regex pattern for string replacement.                                 |
| `process`                | boolean \| null                                   | No       | `true`  | —           | When `true`, attribute placeholders in values are substituted.        |
| `evaluate`               | boolean \| null                                   | No       | `false` | —           | When `true`, values are evaluated as expressions.                     |
| `embeddingMode`          | boolean \| null                                   | No       | `false` | —           | Enables embedding mode for AI vector operations.                      |
| `takeNext`               | boolean \| null                                   | No       | `false` | —           | Extracts the next value in a sequence.                                |
| `takeNextPath`           | string \| null                                    | No       | —       | —           | JSON path for `takeNext` extraction.                                  |
| `multipleValues`         | `"array"` \| `"object"` \| null                   | No       | —       | —           | How to store multiple values.                                         |
| `multipleValuesSettings` | [MultipleValuesSettings](#multiplevaluessettings) | No       | —       | —           | Configuration for multi-value storage.                                |
| `format`                 | string \| null                                    | No       | —       | —           | Format string applied to values.                                      |
| `remove`                 | boolean \| null                                   | No       | `false` | —           | When `true`, removes the attribute instead of setting it.             |

### AttributeValue

| Property                 | Type                                              | Required | Default | Constraints                         | Description                              |
| ------------------------ | ------------------------------------------------- | -------- | ------- | ----------------------------------- | ---------------------------------------- |
| `attributePath`          | string                                            | **Yes**  | —       | Pattern: `^[a-zA-Z][a-zA-Z0-9_.]*$` | Dot-notation path to the attribute.      |
| `value`                  | string \| object \| array \| null                 | No       | —       | —                                   | Value to assign.                         |
| `replace`                | string \| null                                    | No       | —       | —                                   | Regex pattern for string replacement.    |
| `process`                | boolean \| null                                   | No       | —       | —                                   | Attribute placeholder substitution flag. |
| `evaluate`               | boolean \| null                                   | No       | —       | —                                   | Expression evaluation flag.              |
| `embeddingMode`          | boolean \| null                                   | No       | —       | —                                   | Embedding mode flag.                     |
| `takeNext`               | boolean \| null                                   | No       | —       | —                                   | Extract next value in sequence.          |
| `takeNextPath`           | string \| null                                    | No       | —       | —                                   | JSON path for `takeNext`.                |
| `format`                 | string \| null                                    | No       | —       | —                                   | Format string.                           |
| `multipleValues`         | `"array"` \| `"object"` \| null                   | No       | —       | —                                   | Multi-value storage mode.                |
| `multipleValuesSettings` | [MultipleValuesSettings](#multiplevaluessettings) | No       | —       | —                                   | Multi-value configuration.               |
| `remove`                 | boolean \| null                                   | No       | —       | —                                   | Remove flag.                             |

{% hint style="danger" %}
`attributePath` MUST match the pattern `^[a-zA-Z][a-zA-Z0-9_.]*$`. Paths starting with a digit or containing special characters (other than `.` and `_`) are invalid.
{% endhint %}

{% code title="assign-attributes.json" %}

```json
{
  "assignAttributes": {
    "attributes": [
      {
        "attributePath": "contactName",
        "value": "{firstName} {lastName}",
        "process": true
      },
      {
        "attributePath": "order.status",
        "value": "pending"
      },
      {
        "attributePath": "sessionTimestamp",
        "value": "{currentTimestamp}",
        "process": true
      }
    ]
  }
}
```

{% endcode %}

### MultipleValuesSettings

| Property                | Type    | Required | Default | Constraints            | Description                                                   |
| ----------------------- | ------- | -------- | ------- | ---------------------- | ------------------------------------------------------------- |
| `singleValueStandalone` | boolean | No       | `true`  | —                      | When `true`, a single value is stored directly (not wrapped). |
| `delimiter`             | string  | No       | —       | —                      | Delimiter for joining multiple values.                        |
| `prefix`                | string  | No       | —       | —                      | Prefix prepended to each value.                               |
| `suffix`                | string  | No       | —       | —                      | Suffix appended to each value.                                |
| `rootElement`           | string  | No       | —       | —                      | XML/JSON root element name.                                   |
| `valueElement`          | string  | No       | —       | —                      | XML/JSON value element name.                                  |
| `xmlOptions`            | object  | No       | —       | Map of string → string | Additional XML serialization options.                         |

## UpdateAttributeAction

Updates a single attribute. Similar to `AssignAttributesAction` but scoped to one attribute.

| Property    | Type                      | Required | Default | Constraints | Description                           |
| ----------- | ------------------------- | -------- | ------- | ----------- | ------------------------------------- |
| `attribute` | string \| array of string | **Yes**  | —       | —           | Attribute name(s) to update.          |
| `value`     | string \| object \| array | No       | —       | —           | Value to assign.                      |
| `replace`   | string                    | No       | —       | —           | Regex pattern for string replacement. |
| `process`   | boolean                   | No       | `true`  | —           | Attribute placeholder substitution.   |
| `evaluate`  | boolean                   | No       | `false` | —           | Expression evaluation.                |
| `takeNext`  | boolean                   | No       | `false` | —           | Extract next value in sequence.       |

{% hint style="danger" %}
`attribute` is required. An `updateAttribute` object with no `attribute` property is invalid.
{% endhint %}

{% code title="update-attribute.json" %}

```json
{
  "updateAttribute": {
    "attribute": "orderStatus",
    "value": "confirmed",
    "process": false
  }
}
```

{% endcode %}

## Subscribe

When set to `true`, subscribes the current contact to the channel.

{% code title="subscribe.json" %}

```json
{
  "subscribe": true
}
```

{% endcode %}

## UpdateSettingsAction

Updates experience or conversation settings at runtime.

| Property                | Type                   | Required | Description                             |
| ----------------------- | ---------------------- | -------- | --------------------------------------- |
| `rcsExperience`         | object                 | No       | RCS experience settings.                |
| `rcsExperience.enabled` | boolean                | No       | Enables or disables the RCS experience. |
| `conversation`          | object                 | No       | Conversation-level settings.            |
| `conversation.priority` | `"normal"` \| `"high"` | No       | Sets the conversation priority.         |

{% code title="update-settings-priority.json" %}

```json
{
  "updateSettings": {
    "conversation": {
      "priority": "high"
    }
  }
}
```

{% endcode %}

{% code title="update-settings-rcs.json" %}

```json
{
  "updateSettings": {
    "rcsExperience": {
      "enabled": false
    }
  }
}
```

{% endcode %}

## PauseAction

Inserts a brief pause before the next action, typically displayed as a typing indicator.

| Property       | Type    | Required | Default | Constraints | Description                     |
| -------------- | ------- | -------- | ------- | ----------- | ------------------------------- |
| `seconds`      | integer | No       | —       | minimum: 0  | Pause duration in seconds.      |
| `milliseconds` | integer | No       | —       | minimum: 0  | Pause duration in milliseconds. |

{% code title="pause-action.json" %}

```json
{
  "pause": {
    "milliseconds": 800
  }
}
```

{% endcode %}

## Complete Action Sequence Example

The following shows a realistic action sequence that collects user input, calls an API, and branches based on the response.

{% code title="complete-action-sequence.json" %}

```json
[
  {
    "name": "prompt-for-email",
    "send": {
      "message": {
        "text": "Please enter your email address to look up your account."
      }
    }
  },
  {
    "name": "capture-email",
    "waitFor": {
      "data": "text",
      "content": "userEmail",
      "timeout": "3m",
      "executeOnTimeout": "email-timeout-handler"
    }
  },
  {
    "name": "pause-before-lookup",
    "pause": {
      "milliseconds": 500
    }
  },
  {
    "name": "lookup-account",
    "send": {
      "request": {
        "url": "https://api.acme.com/v1/accounts/lookup",
        "method": "POST",
        "dataFormat": "json",
        "headers": {
          "Authorization": "Bearer {apiToken}",
          "Content-Type": "application/json"
        },
        "content": {
          "email": "{userEmail}"
        },
        "response": {
          "accountId": "accountId",
          "tier": "accountTier",
          "found": "accountFound"
        },
        "retries": 1,
        "fallback": "api-error"
      }
    }
  },
  {
    "name": "check-account-found",
    "conditions": [
      {
        "comparisons": [
          ["accountFound", "==", "false"]
        ]
      }
    ],
    "goto": "account-not-found"
  },
  {
    "name": "send-account-summary",
    "send": {
      "message": {
        "text": "Found your account! You are on the {accountTier} plan. Account ID: {accountId}.",
        "quickReplies": [
          {
            "type": "text",
            "title": "View billing",
            "payload": "view_billing"
          },
          {
            "type": "text",
            "title": "Upgrade plan",
            "payload": "upgrade_plan"
          }
        ]
      }
    }
  },
  {
    "name": "tag-account-tier",
    "assignTags": "{accountTier}"
  }
]
```

{% endcode %}
