# Workflow

A **Workflow** defines how the experience responds to a matched user intent. It contains the triggers (intents, keywords, expressions) and the ordered sequence of actions to execute.

## Workflow Properties

| Property      | Type                                                                                               | Required | Default | Constraints               | Description                                                                                  |
| ------------- | -------------------------------------------------------------------------------------------------- | -------- | ------- | ------------------------- | -------------------------------------------------------------------------------------------- |
| `name`        | string                                                                                             | No       | —       | Must not start with `nm:` | Unique identifier for this workflow. Used by `execute`, `goto`, and `welcomeMessageExecute`. |
| `intents`     | array of string \| [IntentObject](#intentobject)                                                   | **Yes**  | —       | —                         | Intent triggers for this workflow.                                                           |
| `keywords`    | array of [Keyword](#keyword)                                                                       | No       | —       | —                         | Exact-match keyword triggers.                                                                |
| `expressions` | array of string \| [Expression](#expression)                                                       | No       | —       | —                         | NLU training phrases for intent matching.                                                    |
| `actions`     | array of [Action](https://playbook.nativemsg.com/rcs-experience-schema/reference/broken-reference) | **Yes**  | —       | —                         | Ordered sequence of actions to execute.                                                      |
| `validation`  | [Validation](#validation)                                                                          | No       | —       | —                         | Attribute validation applied before action execution.                                        |

{% hint style="danger" %}
Both `intents` and `actions` are required on every workflow. A workflow missing either property is invalid.
{% endhint %}

{% hint style="danger" %}
Workflow `name` values MUST NOT begin with the prefix `nm:`. This prefix is reserved for internal nativeMsg system identifiers.
{% endhint %}

## Sub-Definitions

### IntentObject

An **IntentObject** is the structured form of an intent declaration. It is used when an intent requires additional configuration beyond a bare string name.

| Property         | Type                               | Required | Default | Constraints | Description                                              |
| ---------------- | ---------------------------------- | -------- | ------- | ----------- | -------------------------------------------------------- |
| `name`           | string                             | **Yes**  | —       | —           | Intent identifier.                                       |
| `expressions`    | array of [Expression](#expression) | No       | —       | —           | NLU training phrases scoped to this intent.              |
| `excludeContext` | string                             | No       | —       | —           | Suppresses this intent when the named context is active. |

```json
{
  "intents": [
    {
      "name": "cancel_order",
      "excludeContext": "payment_in_progress",
      "expressions": [
        { "text": "I want to cancel my order" },
        { "text": "cancel order" }
      ]
    }
  ]
}
```

### Keyword

A **Keyword** defines an exact-match trigger. The platform matches keyword values before evaluating NLU intents.

| Property | Type                  | Required | Default | Constraints | Description               |
| -------- | --------------------- | -------- | ------- | ----------- | ------------------------- |
| `name`   | string                | **Yes**  | —       | —           | Keyword identifier.       |
| `values` | array of KeywordValue | No       | —       | —           | List of matchable values. |

KeywordValue sub-object:

| Property      | Type            | Required | Default | Constraints | Description                               |
| ------------- | --------------- | -------- | ------- | ----------- | ----------------------------------------- |
| `value`       | string          | **Yes**  | —       | —           | Exact string to match against user input. |
| `expressions` | array of string | No       | —       | —           | Alternate phrasings for this value.       |

```json
{
  "keywords": [
    {
      "name": "stop_keyword",
      "values": [
        { "value": "STOP" },
        { "value": "UNSUBSCRIBE", "expressions": ["opt out", "remove me"] }
      ]
    }
  ]
}
```

### Expression

An **Expression** is a natural language training phrase. It MAY be a bare string or a structured object.

| Property   | Type                   | Required | Default | Constraints | Description                                                       |
| ---------- | ---------------------- | -------- | ------- | ----------- | ----------------------------------------------------------------- |
| `text`     | string                 | **Yes**  | —       | —           | The training phrase text.                                         |
| `generate` | boolean                | No       | `true`  | —           | When `true`, the platform generates additional phrase variations. |
| `slots`    | array of [Slot](#slot) | No       | —       | —           | Entity annotations within the expression text.                    |

Bare string form:

```json
{
  "expressions": ["track my order", "where is my package"]
}
```

Structured object form:

```json
{
  "expressions": [
    {
      "text": "I want to track order number ACM-12345",
      "generate": true,
      "slots": [
        {
          "type": "order_number",
          "value": "ACM-12345",
          "name": "orderNumber"
        }
      ]
    }
  ]
}
```

### Slot

A **Slot** annotates an entity within an expression text.

| Property | Type   | Required | Default | Constraints | Description                                                             |
| -------- | ------ | -------- | ------- | ----------- | ----------------------------------------------------------------------- |
| `type`   | string | **Yes**  | —       | —           | Entity type recognized by the NLU engine.                               |
| `value`  | string | **Yes**  | —       | —           | The literal substring in the expression text that represents this slot. |
| `name`   | string | **Yes**  | —       | —           | Name under which the extracted value is stored.                         |

{% hint style="info" %}
The `value` in a Slot definition is the training example value — the literal text as it appears in the expression. At runtime, the NLU engine recognizes any matching entity of the given `type`, not just the training value.
{% endhint %}

### Validation

A **Validation** tests an attribute value before executing the workflow's actions.

| Property         | Type                      | Required | Default | Constraints           | Description                                                  |
| ---------------- | ------------------------- | -------- | ------- | --------------------- | ------------------------------------------------------------ |
| `content`        | string                    | **Yes**  | —       | —                     | Name of the attribute to validate.                           |
| `pattern`        | string                    | **Yes**  | —       | Must be a valid regex | Regular expression the attribute value must match.           |
| `executeOnError` | string \| array of string | No       | —       | —                     | Workflow or action name(s) to execute when validation fails. |

```json
{
  "validation": {
    "content": "orderNumber",
    "pattern": "^ACM-\\d{5}$",
    "executeOnError": "invalid-order-number"
  }
}
```

{% hint style="danger" %}
Both `content` and `pattern` are required in a Validation object. Omitting either property produces a schema validation error.
{% endhint %}

## Complete Example

The following example shows a realistic workflow with multiple intent forms, keyword triggers, NLU expressions, attribute validation, and several action types.

```json
{
  "name": "order-tracking",
  "intents": [
    "check_order_status",
    {
      "name": "track_package",
      "excludeContext": "order_dispute_open",
      "expressions": [
        { "text": "track my package" },
        { "text": "where is my shipment", "generate": true }
      ]
    }
  ],
  "keywords": [
    {
      "name": "track_keyword",
      "values": [
        { "value": "TRACK" },
        { "value": "TRACKORDER" }
      ]
    }
  ],
  "expressions": [
    "where is my order",
    "has my order shipped",
    {
      "text": "track order ACM-12345",
      "generate": false,
      "slots": [
        {
          "type": "order_id",
          "value": "ACM-12345",
          "name": "orderNumber"
        }
      ]
    }
  ],
  "validation": {
    "content": "sessionActive",
    "pattern": "^true$",
    "executeOnError": "session-expired"
  },
  "actions": [
    {
      "name": "ask-order-id",
      "send": {
        "message": {
          "text": "Please enter your order number (format: ACM-XXXXX)."
        }
      }
    },
    {
      "name": "capture-order-id",
      "waitFor": {
        "data": "text",
        "content": "orderNumber",
        "timeout": "2m",
        "executeOnTimeout": "order-id-timeout"
      }
    },
    {
      "name": "validate-order-id",
      "validation": {
        "content": "orderNumber",
        "pattern": "^ACM-\\d{5}$",
        "executeOnError": "invalid-order-id"
      }
    },
    {
      "name": "fetch-order-status",
      "send": {
        "request": {
          "url": "https://api.acme.com/orders/{orderNumber}/status",
          "method": "GET",
          "headers": {
            "Authorization": "Bearer {apiToken}",
            "Accept": "application/json"
          },
          "dataFormat": "json",
          "response": {
            "status": "orderStatus",
            "estimatedDelivery": "deliveryDate",
            "carrier": "carrierName"
          },
          "retries": 2,
          "fallback": "order-lookup-failed"
        }
      }
    },
    {
      "name": "send-order-status",
      "send": {
        "message": {
          "text": "Your order {orderNumber} is currently {orderStatus}. Estimated delivery: {deliveryDate} via {carrierName}.",
          "quickReplies": [
            {
              "type": "text",
              "title": "Track shipment",
              "payload": "track_shipment"
            },
            {
              "type": "text",
              "title": "Contact support",
              "payload": "contact_support"
            }
          ]
        }
      }
    }
  ]
}
```
