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

# Relay building blocks

> Reference for the triggers, conditions, and actions available when you build a MessageDesk Relay.

Every Relay combines three parts: triggers, conditions, and actions. Use this page as the reference when you build or edit one.

## Triggers

| Trigger                     | Fires when                                              | Notes                                                                                                           |
| --------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Message Received            | A new inbound SMS arrives                               | Default trigger on templates. Supports the Reply to message action.                                             |
| Message Sent                | Your workspace sends a message, manual or automated     | Unlocks Assign to sender.                                                                                       |
| Message Failed              | An outbound message fails to deliver                    | New in v2026.07.15. Pairs with the Message failure contains text condition. Unlocks delivery-failure workflows. |
| Conversation Opened         | A closed conversation is reopened                       |                                                                                                                 |
| Conversation Users Assigned | A teammate assigns one or more people to a conversation |                                                                                                                 |
| Conversation Label Applied  | A label is applied to a conversation                    | Turns a label into an automation trigger.                                                                       |
| Conversation Label Removed  | A label is removed from a conversation                  | New in v2026.07.15. Mirror of Conversation Label Applied.                                                       |
| Comment Created             | A teammate posts an internal comment                    | Pairs with the Comment contains text condition.                                                                 |
| Conversation Closed         | A teammate closes a conversation                        | Good for close-out and system-sync flows.                                                                       |

## Conditions

Every trigger shares a **universal core of seven conditions**:

* **My phone number equals**
* **Conversation label equals**
* **Conversation has label**
* **Is anonymous conversation**
* **Is new conversation**
* **Is unassigned conversation**
* **Active hours** (with a **Trigger outside of business hours** invert)

On top of that core, three text conditions are trigger-scoped:

* **Message contains text** appears on the message triggers (Message Received and Message Sent).
* **Comment contains text** appears only on Comment Created.
* **Message failure contains text** appears only on Message Failed. Matches a substring in the carrier/provider error text (for example, `unreachable`, `landline`, `blocked`). See [Delivery status and errors](/messaging/delivery-status-errors).

Conditions combine with **AND** or **OR**.

<Note>
  **Conversation has label** vs **Conversation label equals.** Both conditions check labels, but they behave differently, so pick the one that matches your intent.

  * **Conversation label equals** is an operator-based matcher. It exposes an operator selector with **contains**, **equals**, **notEquals**, **startsWith**, and **endsWith**. Use it for fuzzy or namespaced matches, for example `startsWith "Region:"` to match every regional label at once.
  * **Conversation has label** is a simple presence check. It evaluates true when the conversation is currently labeled with the label you pick, and false otherwise. Use it as a gate (for example, only run when the conversation already has the `VIP` label).
</Note>

<Note>
  **Relays target a phone line, not a user or an availability status.** Conditions like **My phone number equals** scope a Relay to a connected number, not to a specific teammate. There's no condition for the assigned teammate or conversation owner. Per-person workflows like out-of-office only work when a teammate has a dedicated line.
</Note>

## Actions

* **Reply to message** (supports templates, tags, and media, with an optional **Delay**; available on Message Received, Message Failed, and Conversation Label Removed)
* **Assign teammates to the conversation**
* **Assign to sender** (Message Sent trigger only)
* **Add labels to the conversation**
* **Remove labels from the conversation**
* **Remove teammates from the conversation**
* **Remove all teammates from the conversation**
* **Close the conversation**
* **Open the conversation**
* **Send webhook**

Available actions vary by trigger, so check the **Add Action** menu in the app for the trigger you're using.

### Actions on the new triggers

**Message Failed** supports the following actions:

* Reply to message
* Assign teammates to the conversation
* Close the conversation
* Open the conversation
* Remove all teammates from the conversation
* Remove teammates from the conversation
* Add labels to the conversation
* Remove labels from the conversation
* Send webhook

**Conversation Label Removed** supports the same set as Message Failed with one asymmetry: **Remove labels from the conversation isn't available** on this trigger. Every other action above is available.
