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

> A library of ready-made MessageDesk Relay templates: starter templates that ship in the app, plus an outcome-first library covering customer service, operations and routing, and webhook integrations.

# Relay templates

A library of ready-made Relay templates. Start from a template that ships in the app, or build from the outcome-first library below. Each library entry lists the **trigger**, any **conditions**, the **actions**, and a brief **why this works** note.

<Note>
  **Every template here is a starting point.** Adjust the wording, labels, assignees, active hours, and conditions to match your team's workflow. For step-by-step instructions on building a Relay from scratch, including how to use **AND/OR** between conditions, chain actions, and add delays, see [Create and edit a Relay](/relays/create-edit). For a full reference of the available [triggers, conditions, and actions](/relays/building-blocks), see the Relay building blocks page.
</Note>

<Tip>
  **Stacking templates on the same Trigger?** You can build more than one Relay on the same trigger. For example, an after-hours reply and a keyword reply both on **Message Received**. Set the **Order** on the Relays list so the more specific Relay runs first. All matching Relays run in Order. See [Order your Relays](/relays/create-edit#1a-order-your-relays).
</Tip>

***

## Starter templates that ship today

These starter templates are available from the Relays module in the app. Pick one, name it, and adjust the fields to match your workflow.

| Template                              | What it does                                             | Underlying build                                                |
| ------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------- |
| **Out-of-Office (Away) Autoresponse** | Texts an autoresponse outside operating hours            | Message Received + Active hours (inverted) + Reply to message   |
| **Respond to a Keyword**              | Auto-replies when a keyword is texted in                 | Message Received + Message contains text + Reply to message     |
| **Identify Unknown Contacts**         | Asks anonymous contacts for their info                   | Message Received + Is anonymous conversation + Reply to message |
| **Assign to Teammate**                | Assigns new conversations to a teammate                  | Message Received + Assign teammates                             |
| **Auto Assign to First Responder**    | Assigns a conversation to the first teammate who replies | Message Sent + Is unassigned conversation + Assign to sender    |
| **Label Conversation**                | Auto-labels new conversations                            | Message Received + Add labels                                   |
| **Custom Relay**                      | Blank canvas for your own build                          | Any trigger, conditions, actions                                |
| **Send Webhook**                      | Sends events to a webhook endpoint                       | Any trigger + Send webhook                                      |
| **Unassign on Close**                 | Removes all teammates when a conversation closes         | Conversation Closed (no conditions) + Remove all teammates      |

Every starter is a starting point you can customize.

***

## Foundational templates

The outcomes below are the building blocks that most teams start from. Each entry lists the **trigger**, any **conditions**, the **actions**, and a short "Why it works." Adjust wording, labels, assignees, and scoping to fit your team.

<Note>
  **Confirmed vs. pending.** The Add Action menu can vary by trigger. The templates below cover only the combinations confirmed to appear in the app today. Three additional foundational templates (on **Conversation Opened**, **Comment Created**, and **Conversation Label Applied**) are staged for a follow-up once their action menus land.
</Note>

### Whoever answers a lead first owns the follow-up

| Field          | Value                      |
| -------------- | -------------------------- |
| **Trigger**    | Message Sent               |
| **Conditions** | Is unassigned conversation |
| **Actions**    | Assign to sender           |

**Why it works:** The first teammate to reply gets assigned. The conversation is no longer unassigned, so later replies from others don't steal it. Follow-up never lands in an unclaimed pile. This is the outcome behind the shipped **Auto Assign to First Responder** starter.

***

### Clean reset and system sync every time a thread closes

| Field          | Value                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Conversation Closed                                                                                     |
| **Conditions** | None (or scope to a line)                                                                               |
| **Actions**    | Remove all teammates from the conversation → Add labels to the conversation (`Resolved`) → Send webhook |

**Why it works:** Closing resets assignment in one step and pushes the close event to your other systems. This extends the shipped **Unassign on Close** starter with a `Resolved` label and an outbound webhook so your CRM, data warehouse, or ticketing tool stays in sync.

***

### One rule that routes an entire namespace of labels

| Field          | Value                                                               |
| -------------- | ------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                    |
| **Conditions** | Conversation label equals, operator **startsWith**, value `Region:` |
| **Actions**    | Send webhook → Add labels to the conversation (`Routed`)            |

**Why it works:** The **Conversation label equals** condition is a matcher, not a fixed equality check. A single `startsWith "Region:"` rule catches every label in a namespace at once (`Region:North`, `Region:South`, `Region:West`, etc.), so you avoid maintaining one Relay per region. See the operator-selector Note in [Relay building blocks](/relays/building-blocks) for the full operator list.

***

### Catch every text that fails to deliver

| Field          | Value                                                                                                                                                         |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Failed                                                                                                                                                |
| **Conditions** | None (or scope to a line with **My phone number equals**)                                                                                                     |
| **Actions**    | Add labels to the conversation (`Delivery failed`) → Open the conversation → Assign teammates to the conversation (an owner) → Send webhook (alert a channel) |

**Why it works:** A failed text is invisible today because the sender assumes it went through. This surfaces every failure immediately, reopens and flags the thread, and puts it on someone to follow up. Most valuable for time-sensitive dispatch, staffing, and safety messages.

***

### Branch on the reason a message failed

| Field          | Value                                                                                               |
| -------------- | --------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Failed                                                                                      |
| **Conditions** | Message failure contains text (match the carrier error text for a temporary or unreachable failure) |
| **Actions**    | Add labels to the conversation (`Retry later`) → Send webhook                                       |

**Why it works:** Not all failures are equal, so matching on the failure text lets you retry what's worth retrying and clean up what isn't. Build a second Relay on the same trigger that matches a permanent-failure reason and labels it `Bad number` instead. Use provider-agnostic error wording in your matches so the Relay keeps working if the underlying carrier or provider changes.

<Note>
  **Verify before enabling.** The **Message failure contains text** condition ships with the v2026.07.15 release. If your workspace doesn't see it on the Message Failed trigger yet, hold this template until it appears.
</Note>

***

### When a label comes off, sync the change

| Field          | Value                                                                                                                                       |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Conversation Label Removed                                                                                                                  |
| **Conditions** | Conversation has label (or scope by line with **My phone number equals**)                                                                   |
| **Actions**    | Send webhook (update the downstream system) → Assign teammates to the conversation (as needed) → Add labels to the conversation (as needed) |

**Why it works:** A label coming off often signals a state change. Firing on removal keeps your CRM or reporting in sync automatically. **Remove labels isn't an available action on this trigger**, so this Relay reacts to a removal rather than performing one.

***

## Vertical library

The templates below are grouped by industry and by common cross-industry use cases.

Every template uses the canonical trigger, condition, and action names. See [Relay building blocks](/relays/building-blocks) for the full reference.

***

### Construction and dispatch

#### No job stalls because one supervisor's phone went dark

| Field          | Value                                                                                                         |
| -------------- | ------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                              |
| **Conditions** | My phone number equals (the shared main or dispatch line)                                                     |
| **Actions**    | Assign teammates to the conversation (crew or job coordinator) → Add labels to the conversation (job or crew) |

**Why it works:** Inbound texts land in a shared Inbox with an owner and a job label. Threads stay covered when a supervisor is on a site or out.

#### Subcontractor and supplier texts never sit unclaimed

| Field          | Value                                                         |
| -------------- | ------------------------------------------------------------- |
| **Trigger**    | Message Received                                              |
| **Conditions** | Is unassigned conversation                                    |
| **Actions**    | Add labels to the conversation (`Needs owner`) → Send webhook |

**Why it works:** Anything that slips past routing gets flagged instead of aging in the queue.

***

### Logistics and trucking

#### Route every driver text to the right dispatcher, no shared handset required

| Field          | Value                                                                                                                  |
| -------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                       |
| **Conditions** | My phone number equals (dispatch line). Optionally add Conversation label equals a region.                             |
| **Actions**    | Add labels to the conversation (region or load type) → Assign teammates to the conversation (that region's dispatcher) |

**Why it works:** Every dispatcher sees every message in one Inbox, and texts self-sort by region. That replaces the single shared phone.

#### Off-duty driver messages still get an instant acknowledgement

| Field          | Value                                                                                                                                              |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                   |
| **Conditions** | Active hours (with **Trigger outside of business hours** enabled)                                                                                  |
| **Actions**    | Reply to message ("Dispatch is closed. Text URGENT for the on-call line. Reply STOP to opt out.") → Add labels to the conversation (`After-hours`) |

**Why it works:** An off-hours text gets an immediate acknowledgement and waits for dispatch in the morning.

#### Policy and route acknowledgements get tracked, not chased

| Field          | Value                                                          |
| -------------- | -------------------------------------------------------------- |
| **Trigger**    | Message Received                                               |
| **Conditions** | Message contains text `ACK`                                    |
| **Actions**    | Add labels to the conversation (`Acknowledged`) → Send webhook |

**Why it works:** Pair a broadcast with a keyword reply, and MessageDesk labels and logs every acknowledgement automatically.

***

### Field operations

#### Safety and incident texts escalate the second they land

| Field          | Value                                                                                                                                                                                                           |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                                                                                |
| **Conditions** | Message contains text `incident`                                                                                                                                                                                |
| **Actions**    | Reply to message ("Received. A supervisor is being notified now.") → Assign teammates to the conversation (safety lead) → Add labels to the conversation (`Incident`) → Send webhook (alert the safety channel) |

**Why it works:** A field emergency routes to the safety lead and alerts the team in one step.

#### Rig recruiting stops living on personal phones

| Field          | Value                                                                                                                             |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                  |
| **Conditions** | Message contains text `available`                                                                                                 |
| **Actions**    | Assign teammates to the conversation (recruiter) → Add labels to the conversation (`Available`) → Send webhook (push to your ATS) |

**Why it works:** MessageDesk captures every candidate availability reply, assigns an owner, and pushes it to your system. Nobody gets called twice.

#### Every field message is retained and auditable

| Field          | Value                                                     |
| -------------- | --------------------------------------------------------- |
| **Trigger**    | Message Received (build a matching Relay on Message Sent) |
| **Conditions** | None (or scope to field lines)                            |
| **Actions**    | Send webhook (to your retention or audit store)           |

**Why it works:** Inbound and outbound field messages stream to your system of record. MessageDesk facilitates 10DLC registration as your CSP and honors opt-outs at the workspace level.

***

### Staffing and recruiting

#### Every candidate reply gets claimed by a recruiter

| Field          | Value                                                                                                                                                    |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                         |
| **Conditions** | Message contains text `yes`                                                                                                                              |
| **Actions**    | Assign teammates to the conversation (staffing coordinator) → Add labels to the conversation (`Shift response`) → Send webhook (sync to your ATS or CRM) |

**Why it works:** After a shift-fill text, replies route to the coordinator. The fastest responder gets placed first, and MessageDesk logs the reply.

#### Applicant first-touch that never goes cold

| Field          | Value                                                                                                                                                                                                           |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                                                                                |
| **Conditions** | Message contains text `apply`                                                                                                                                                                                   |
| **Actions**    | Reply to message ("Thanks for your interest. Here is the quick application: \[link]. Reply STOP to opt out.") → Assign teammates to the conversation (recruiter) → Add labels to the conversation (`Applicant`) |

**Why it works:** An instant reply with the application link plus an assigned recruiter keeps the pipeline warm.

#### Unsaved candidate numbers get named automatically

| Field          | Value                                                                                                                           |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                |
| **Conditions** | Is anonymous conversation                                                                                                       |
| **Actions**    | Reply to message ("Thanks for reaching out. What is your first and last name?") → Add labels to the conversation (`Unverified`) |

**Why it works:** Capturing the name up front keeps the directory clean and every thread attributable.

***

### Professional services

#### Website-to-text intake lands in a shared, trackable inbox

| Field          | Value                                                                                                                                                                                                                                                               |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                                                                                                                                    |
| **Conditions** | Is new conversation                                                                                                                                                                                                                                                 |
| **Actions**    | Reply to message ("Thanks for reaching out. What is your name and a short note on what you need help with?") → Assign teammates to the conversation (intake coordinator) → Add labels to the conversation (`Intake`) → Send webhook (create the record in your CRM) |

**Why it works:** The first inbound text runs intake and creates a trackable record.

#### Billing questions route straight to AR

| Field          | Value                                                                                       |
| -------------- | ------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                            |
| **Conditions** | Message contains text `invoice`                                                             |
| **Actions**    | Assign teammates to the conversation (billing) → Add labels to the conversation (`Billing`) |

**Why it works:** Money questions bypass the general queue.

***

### More industries and use cases

The patterns below cover common use cases across additional industries.

#### Automotive service: a shared department inbox

| Field          | Value                                                                                       |
| -------------- | ------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                            |
| **Conditions** | My phone number equals (the service department line)                                        |
| **Actions**    | Assign teammates to the conversation (advisor) → Add labels to the conversation (`Service`) |

**Why it works:** Status texts stop landing on one advisor's phone. Any advisor can pick up the thread, and replies can carry photos and invoice links.

<Tip>
  Pair this with an inverted **Active hours** Relay on the same line that uses **Reply to message** to acknowledge after-hours questions and set expectations for the morning.
</Tip>

#### Financial advisors: broadcast replies come back to a tracked inbox

| Field          | Value                                                                                                                                        |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received (build a matching Relay on Message Sent)                                                                                    |
| **Conditions** | None (or scope to the advisor line)                                                                                                          |
| **Actions**    | Assign teammates to the conversation (the advisor) → Add labels to the conversation (`Client`) → Send webhook (to your recordkeeping system) |

**Why it works:** After a broadcast, replies land with an owner and both directions stream to your records.

#### Home services and emergency trades: turn an after-hours text into tomorrow's job

| Field          | Value                                                                                                                                                                                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Trigger**    | Message Received                                                                                                                                                                                                                                                   |
| **Conditions** | Active hours (with **Trigger outside of business hours** enabled), My phone number equals (jobs or emergency line)                                                                                                                                                 |
| **Actions**    | Reply to message ("We received your message and will follow up first thing. If this is an active emergency, call \[number]. Reply STOP to opt out.") → Add labels to the conversation (`After-hours`) → Assign teammates to the conversation (on-call coordinator) |

**Why it works:** MessageDesk captures and routes the lead even when the office is dark.

***

### Support and sales

#### A texted keyword menu that routes itself

| Field          | Value                                                                                                                                                |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                     |
| **Conditions** | Message contains text `support` (build parallel Relays for `pricing` and `sales`)                                                                    |
| **Actions**    | Reply to message (matching acknowledgement) → Assign teammates to the conversation (matching team) → Add labels to the conversation (matching topic) |

**Why it works:** One number handles support, pricing, and sales, each with its own reply and owner.

<Tip>
  Keep a keyword-free catch-all Relay ordered **last** so any message that doesn't match a keyword still gets a graceful reply and an owner.
</Tip>

***

## Customer service

### 1. After-hours auto-reply

| Field         | Value                                                                                                         |
| ------------- | ------------------------------------------------------------------------------------------------------------- |
| **Trigger**   | Message Received                                                                                              |
| **Condition** | Active hours: set your business hours, then toggle **Trigger outside of business hours** to invert the window |
| **Actions**   | **Reply to message:** "We'll get back to you at 8am. Reply STOP to opt out."                                  |

**Why this works:** Inverting the Active hours window means the Relay only fires when an inbound message lands **outside** your business hours, so customers always get an immediate acknowledgement. The STOP language keeps you compliant with carrier opt-out requirements.

<Note>
  **Auto-replies don't mark a conversation as Read.** When this Relay sends its after-hours reply, the conversation moves to **Replied** status and leaves the Unread filter. It isn't marked Read until a teammate opens it in the Inbox. See [Relays and conversation status](/relays/create-edit#relays-and-conversation-status) for details.
</Note>

<Tip>
  Add a **Delay** to the Reply action to avoid sending repeat auto-replies inside a tight back-and-forth.
</Tip>

***

### 2. First-touch reply for anonymous contacts

| Field          | Value                                                                                                                                                                      |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                                           |
| **Conditions** | Is anonymous conversation = **true**                                                                                                                                       |
| **Actions**    | **Reply to message:** "Thanks for texting us! What's your first and last name so we know who to help? Reply STOP to opt out." → **Add labels to the conversation:** `Lead` |

**Why this works:** New inbound texts from unsaved numbers come in as **anonymous conversations**. A first-touch reply captures the contact's name while it's fresh, and the `Lead` label gives sales/intake a single filter to work from. See [Anonymous, opted out & blocked](/contacts/anonymous-opt-out-blocked) for how anonymous status is determined.

***

### 3. Opted-out conversation handler

| Field          | Value                                                                                                                                                                      |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                                                                                                           |
| **Conditions** | **Message contains text** = `STOP` (catches the opt-out keyword itself), or **Conversation label equals** `Opted Out` (routes on a label applied earlier in your workflow) |
| **Actions**    | **Add labels to the conversation:** `Opted Out` → **Assign teammates to the conversation:** support queue                                                                  |

**Why this works:** There's no built-in "contact is opted out" condition on the trigger, so build the handler from conditions that do exist. Match the STOP keyword on the inbound message itself, or route on an `Opted Out` label that a keyword Relay, a teammate, or an integration applied upstream. Labeling the thread keeps it visible to compliance and support. Routing it to your support queue ensures someone confirms you honored the customer's request. Once you apply `Opted Out`, downstream filters and Relays can avoid touching that contact.

<Note>
  MessageDesk automatically blocks sending to **opted-out contacts** at the workspace level. This Relay is for **internal awareness and audit**, not for blocking the outbound message itself.
</Note>

***

## Operations and routing

### 4. Phone line routing

| Field         | Value                                                                                                                                                         |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**   | Message Received                                                                                                                                              |
| **Condition** | **My phone number equals** = the specific connected phone line                                                                                                |
| **Actions**   | **Assign teammates to the conversation:** designated teammate(s) → **Add labels to the conversation:** line-specific label (e.g., `Front Desk`, `Sales Line`) |

**Why this works:** Teams running multiple phone lines (Front Desk, Support, Sales) want every inbound message on that line to land with the right owner immediately. Adding a line-specific label also gives you ready-made filtered views in the Inbox.

***

### 5. Keyword-based routing

| Field         | Value                                                                                                                                 |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Trigger**   | Message Received                                                                                                                      |
| **Condition** | **Message contains text** = `HELP` (or `SUPPORT`, `BILLING`, etc.)                                                                    |
| **Actions**   | **Reply to message:** "Got it. A support teammate will be with you shortly." → **Assign teammates to the conversation:** support team |

**Why this works:** Keyword routing is fast triage: the customer gets an instant acknowledgement and the right team picks up the thread without manual sorting. Combine with **My phone number equals** if you want the keyword to behave differently on different lines.

<Tip>
  Stack multiple keyword Relays (one per keyword) and use a default Relay without a keyword condition as a catch-all.
</Tip>

***

### 6. Auto-assign (round-robin note)

| Field          | Value                                                                                   |
| -------------- | --------------------------------------------------------------------------------------- |
| **Trigger**    | Message Received                                                                        |
| **Conditions** | Optional: **My phone number equals** a specific line, or **Is unassigned conversation** |
| **Actions**    | **Assign teammates to the conversation:** teammate                                      |

**Why this works:** A single Relay assigns every inbound conversation to one teammate. **True round-robin distribution requires multiple Relays**, one per teammate, each segmented by a different **line** or **label** condition so they don't all fire on the same message. There isn't a built-in "rotate to next teammate" action today. This multi-Relay pattern is the supported workaround.

<Tip>
  Pair this with a `Triage` label and an Inbox filter on **Assignee = Unassigned** so anything that slips through is easy to spot.
</Tip>

***

### 7. Assign unassigned conversations to whoever replies first

| Field         | Value                                     |
| ------------- | ----------------------------------------- |
| **Trigger**   | Message Sent                              |
| **Condition** | **Is unassigned conversation** = **true** |
| **Actions**   | **Assign to sender**                      |

**Why this works:** When a shared Inbox has no owner on a thread, the first teammate to reply usually should own the follow-up. This Relay watches outbound messages, checks that no one's assigned yet, and assigns the conversation to whoever hit send. New inbound messages on the same thread then route to that teammate by default.

<Note>
  **Ships as a template:** This template is available as the **Auto Assign to First Responder** starter from the Relays module. Install it as-is or use the fields above to build it yourself.
</Note>

<Note>
  The **Assign to sender** action is only available with the **Message Sent** trigger.
</Note>

<Tip>
  Drop the **Is unassigned conversation** condition if you want the sender to always take ownership, even on threads someone else was already assigned to.
</Tip>

***

### 8. Notify the new assignee on assignment

| Field          | Value                                                     |
| -------------- | --------------------------------------------------------- |
| **Trigger**    | Conversation Users Assigned                               |
| **Conditions** | None (or scope by line/label)                             |
| **Actions**    | **Send webhook** → your Slack/Teams/notification endpoint |

**Why this works:** MessageDesk's in-app notifications reach assignees inside the product. Teams that live in Slack or Teams want a ping in their chat tool the moment a conversation lands in their queue. Fire a webhook on **Conversation Users Assigned** and route the payload to your notifier of choice.

<Tip>
  Pair with **Add labels to the conversation** (for example, `Handoff`) so the receiving teammate can filter their Inbox to just newly assigned threads.
</Tip>

***

### 9. Re-triage on reopen

| Field          | Value                                                                                           |
| -------------- | ----------------------------------------------------------------------------------------------- |
| **Trigger**    | Conversation Opened                                                                             |
| **Conditions** | None (or scope by line/label)                                                                   |
| **Actions**    | **Remove all teammates from the conversation** → **Add labels to the conversation:** `Reopened` |

**Why this works:** When a closed conversation gets reopened (a customer replies days later, or a teammate reopens for follow-up), the original assignees may no longer be the right owners. Clearing assignees and applying a `Reopened` label sends the thread back through your normal triage so it gets picked up by the right person.

<Tip>
  Pair this with a **Message Received** Relay that auto-assigns based on line or keyword. Reopens get reset here; the next inbound gets routed there.
</Tip>

***

## Webhooks and integrations

<Note>
  Webhook actions require a configured webhook endpoint and signing secret. Set those up in [**Settings → Developer Tools**](/settings/workspace-settings/developer-tools) before turning on the Relays below. See [Send Webhook](/relays/webhooks) for the full payload format, headers, and signature validation.
</Note>

### 10. Push new inbound message to an external system

| Field          | Value                                       |
| -------------- | ------------------------------------------- |
| **Trigger**    | Message Received                            |
| **Conditions** | None (or scope by line/keyword)             |
| **Actions**    | **Send webhook** → your configured endpoint |

**Why this works:** Streams every new inbound text to your CRM, data warehouse, ticketing tool, or notification service. Pair with **My phone number equals** to limit the firehose to a specific line, or add **Message contains text** to forward only certain keywords.

***

### 11. Notify an external system on conversation close

| Field          | Value                                                                                           |
| -------------- | ----------------------------------------------------------------------------------------------- |
| **Trigger**    | Conversation Closed                                                                             |
| **Conditions** | None (or scope by line/label)                                                                   |
| **Actions**    | **Send webhook** → your configured endpoint (plus any close-out actions you want to run in-app) |

**Why this works:** Use the **Conversation Closed** trigger directly. It fires whenever a teammate closes a conversation, so you can push the close event straight into a CRM, ticketing tool, or data warehouse. Add **My phone number equals** or **Conversation label equals** if you only want to forward closes from certain lines or queues. No label workaround needed.

***

### 12. Reset assignees on close

| Field          | Value                                          |
| -------------- | ---------------------------------------------- |
| **Trigger**    | Conversation Closed                            |
| **Conditions** | None                                           |
| **Actions**    | **Remove all teammates from the conversation** |

**Why this works:** When a conversation closes, the previous assignees usually shouldn't stay attached. Reopens or new inbound messages on the same thread often need fresh triage. The **Remove all teammates from the conversation** action clears every assignee in one step, so the next inbound lands unassigned and can be routed by your normal auto-assign Relays.

<Note>
  **Ships as a template:** This template is available as the **Unassign on Close** starter from the Relays module. Install it in one click, or build it from the fields above.
</Note>

<Tip>
  Pair this with a **Message Received** Relay that auto-assigns based on line or keyword. Closed threads get reset here; the next inbound gets routed there.
</Tip>

***

### 13. Auto-close after acknowledgement

| Field          | Value                                                                                              |
| -------------- | -------------------------------------------------------------------------------------------------- |
| **Trigger**    | Message Sent                                                                                       |
| **Conditions** | Optional: **My phone number equals** a specific line, or match an acknowledgement template/keyword |
| **Actions**    | **Close the conversation**                                                                         |

**Why this works:** One-shot confirmation flows (appointment confirmations, delivery notifications, "on my way" pings) don't need to stay open in the Inbox after the outbound message goes out. The **Close the conversation** action closes the thread as soon as the confirmation is sent, keeping the Inbox focused on conversations that still need a human.

<Tip>
  MessageDesk handles reopens automatically: a new inbound message on a closed conversation reopens the thread and fires any **Conversation Opened** Relays you've configured (see [Template 9](#9-re-triage-on-reopen)).
</Tip>

***

## See also

* [Relay building blocks](/relays/building-blocks): reference for all triggers, conditions, and actions
* [Create and edit a Relay](/relays/create-edit): step-by-step Relay building, including AND/OR conditions, delays, and active hours
* [Send Webhook](/relays/webhooks): payload structure, signature validation, and retry behavior
* [Developer Tools](/settings/workspace-settings/developer-tools): configure your webhook endpoint and signing secret
* [Relays overview](/relays/overview): concepts and examples
