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

# Actions

> Send emails, text messages, and create tasks automatically when your automations fire.

When an automation's trigger fires and its conditions are met, it performs an **action**. There are three types: send an email, send a text message, or create a task. An automation can run more than one action — add as many as you need on the same trigger.

<Info>
  **This page covers features gated by Admin-tier permissions** — typically Settings access. Admins have these by default; your administrator can adjust who has them in [Settings > Team](/settings/team).
</Info>

## Template variables

Email subjects, email bodies, and SMS messages can include variables like `{{customer.name}}` that resolve when the automation runs. The automation builder shows a panel of available variables under each message field — click one to insert the matching token at the cursor. The list adapts to the automation type: order automations expose order-related tokens, event automations expose event-related tokens, and both share the customer set.

### Order automation variables

| Variable                    | What it inserts                                                                 |
| --------------------------- | ------------------------------------------------------------------------------- |
| `{{order.number}}`          | Order number                                                                    |
| `{{order.total}}`           | Order total with currency symbol                                                |
| `{{order.fulfilment_date}}` | Fulfilment date, formatted dd-mm-yyyy                                           |
| `{{order.fulfilment_time}}` | Fulfilment time                                                                 |
| `{{order.note}}`            | Order note                                                                      |
| `{{location.review_link}}`  | Review link configured on the order's location (under **Settings > Locations**) |
| `{{customer.name}}`         | Customer's full name, or company name if the customer is a business             |
| `{{customer.first_name}}`   | Customer first name                                                             |
| `{{customer.last_name}}`    | Customer last name                                                              |
| `{{customer.email}}`        | Customer email                                                                  |
| `{{customer.phone}}`        | Customer phone                                                                  |

### Event automation variables

| Variable                     | What it inserts                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------- |
| `{{event.type}}`             | Event type                                                                      |
| `{{event.date}}`             | Event date, formatted dd-mm-yyyy                                                |
| `{{event.time}}`             | Event time                                                                      |
| `{{event.venues}}`           | Venue or venues attached to the event                                           |
| `{{event.total_paid}}`       | Total paid against the event, with currency symbol                              |
| `{{event.balance_due}}`      | Balance still due, with currency symbol                                         |
| `{{event.balance_due_date}}` | Payment due date, formatted dd-mm-yyyy                                          |
| `{{event.link}}`             | Link to the event                                                               |
| `{{location.review_link}}`   | Review link configured on the event's location (under **Settings > Locations**) |
| `{{customer.name}}`          | Customer's full name, or company name if the customer is a business             |
| `{{customer.first_name}}`    | Customer first name                                                             |
| `{{customer.last_name}}`     | Customer last name                                                              |
| `{{customer.email}}`         | Customer email                                                                  |
| `{{customer.phone}}`         | Customer phone                                                                  |

### Per-recipient contact variables (event automations only)

When an event automation action has an **Event contacts** loop on it, a second set of variables appears in the picker. These resolve to the **current recipient's** details, so each fan-out email or SMS is addressed to that specific contact rather than the event's primary customer.

| Variable                 | What it inserts                |
| ------------------------ | ------------------------------ |
| `{{contact.name}}`       | Recipient contact's full name  |
| `{{contact.first_name}}` | Recipient contact's first name |
| `{{contact.last_name}}`  | Recipient contact's last name  |
| `{{contact.email}}`      | Recipient contact's email      |
| `{{contact.phone}}`      | Recipient contact's phone      |

Use `{{customer.first_name}}` when you mean the event's primary customer (always the same across every iteration of the loop), and `{{contact.first_name}}` when you mean the person the current iteration is being sent to. The two are different on purpose — most fan-out messages want `{{contact.*}}` for the greeting and `{{customer.*}}` when referring to who booked the event.

The picker only shows the `{{contact.*}}` set when the action is configured to loop over event contacts. If you switch off the loop, those variables disappear from the picker (existing tokens in your message body keep working but resolve to empty strings outside the loop).

<Info>
  If a customer or contact doesn't have a value for the variable you've used (no phone number, for example), the variable resolves to an empty string. Unknown tokens are left as-is in the message so a typo like `{{custmer.name}}` shows up plainly in the test send rather than being silently dropped.
</Info>

Loops use a different syntax (`%name%`, `%quantity%` and so on) and only work inside a looping action — see [Loops](#loops) below for the full set per loop type.

## Send an email

The most common action. When the automation fires, an email goes out to the customer on the order or event, wrapped in your standard notification layout and branding.

### Setting it up

<Steps>
  <Step title="Write the subject">
    Type the subject line. Insert variables from the picker so each email is personalised — see [Template variables](#template-variables) for the full list.
  </Step>

  <Step title="Write the message">
    Compose the email body. Variables work here too. You don't need to recreate headers, footers, or styling — the message is dropped into your branded notification layout.
  </Step>
</Steps>

The email always goes to the customer recorded on the order or event. If you need to notify a team member instead of (or as well as) the customer, set up a separate notification event for that — see [Notifications](/settings/notifications).

If the email action has a loop on it, the body is rendered once per loop item, with loop variables like `%name%` filled in for each one. See [Loops](#loops) for the full variable list per loop type.

## Send a text message (SMS)

Sends a text message to the customer's phone number when the automation fires. Useful for time-sensitive notifications like delivery updates.

### Setting it up

Enter the SMS content. The same variables work in SMS as in email — see [Template variables](#template-variables). Keep the message short: standard SMS messages are 160 characters, and longer ones are split into multiple parts and use multiple credits, so insert variables sparingly.

The SMS sends to the phone number on the customer record by default. If the action has an [Event contacts loop](#event-contacts-loop-sends-to-each-contact-in-turn) on it, the SMS sends to each contact's phone instead, once per contact. If a phone number is missing, the automation logs that the SMS was skipped and moves on. Your order or event isn't blocked.

<Warning>
  Text messages use SMS credits from your plan. If a phone number is missing or credits run out, the automation logs the skip and the rest of your workflow keeps running.
</Warning>

## Create a task

Automatically creates a task when the automation fires. This is great for making sure preparation steps, follow-ups, or checks don't get forgotten.

### Setting it up

<Steps>
  <Step title="Enter the task title">
    Give the task a clear name, like "Prepare arrangement" or "Follow up with client".
  </Step>

  <Step title="Add a description (optional)">
    Include any extra detail the team needs.
  </Step>

  <Step title="Add a checklist (optional)">
    You can generate a checklist from a loop — for example, one checklist item per product in the order, or one per recipe in an event quotation. See Loops below.
  </Step>
</Steps>

### Scheduling the due date

By default a created task is due straight away. To prep ahead, set a due date relative to the order or event using one of these fields.

* **Days Before** — the task is due that many days before the order's fulfilment date or the event date (like a prep task 7 days before).
* **Days After** — the task is due that many days after (like a follow-up 14 days after).

Set one or the other, not both. Digital Florists works out the due date when the automation fires. If the order or event date changes afterwards, the task's due date doesn't recalculate.

The created task appears on your [Tasks](/daily-operations/tasks) board and can be assigned, completed, and tracked like any other task.

## Loops

Loops let you repeat part of an action for each item in a list. Tick **Enable Looping** on an action and pick what to loop over.

| Loop                            | What it loops over                                  | Available for     |
| ------------------------------- | --------------------------------------------------- | ----------------- |
| **Order items**                 | Each product line on the order                      | Order automations |
| **Event quotation recipes**     | Each recipe in the event's quotation                | Event automations |
| **Event quotation ingredients** | Each ingredient across all recipes in the quotation | Event automations |
| **Event contacts**              | Each contact attached to the event                  | Event automations |

### Loop variables

Inside a loop, the message body is rendered once per item with the `%variable%` values filled in for that item. Each loop has its own variable set:

| Loop                            | Variables                                                                |
| ------------------------------- | ------------------------------------------------------------------------ |
| **Order items**                 | `%name%`, `%quantity%`, `%price%`, `%note%`                              |
| **Event quotation recipes**     | `%name%`, `%quantity%`, `%price%`                                        |
| **Event quotation ingredients** | `%name%`, `%quantity%`, `%price%`                                        |
| **Event contacts**              | `%name%`, `%first_name%`, `%last_name%`, `%email%`, `%phone%`, `%label%` |

Outside a loop, use the `{{ }}` variables from [Template variables](#template-variables) instead. The two syntaxes are intentional: `{{ }}` refers to the order or event the automation fired on, `%%` refers to the current item inside the loop.

### How loops work with emails

The email is sent once per loop item with the loop variables filled in. Three of the loops (Order items, Event quotation recipes, Event quotation ingredients) all send to the customer recorded on the order or event, with a different message each time. The Event contacts loop is different — see below.

### Event contacts loop — sends to each contact in turn

The Event contacts loop is the only loop that changes who the email or SMS is sent to. For each contact on the event:

* The email goes to that contact's email address (not the event customer's)
* The SMS goes to that contact's phone number (not the event customer's)
* The `{{contact.*}}` template variables from [Per-recipient contact variables](#per-recipient-contact-variables-event-automations-only) resolve to the current recipient's details, so the greeting reads "Hi Sarah" for the bride and "Hi Tom" for the groom on the same automation
* The legacy `%first_name%`, `%last_name%`, `%email%`, `%phone%`, `%label%` loop tokens still work and resolve to the same values — the modern `{{contact.*}}` syntax is the recommended one because it's shown in the variable picker
* If a contact is missing a value (no email on a contact who's phone-only, for example), the loop falls back to the event's customer details so the message still goes out — but only when it's a sensible fallback, never to the wrong person

Use it for any "fan out" scenario: send the same reminder to the bride, groom, and venue coordinator without writing three automations.

### How loops work with tasks

When you use a loop with a create task action, Digital Florists generates a **checklist** on the task with one item per loop entry. For example, if an order has three products and you use the Order items loop, the task gets a three-item checklist — one for each product, with `%name% x %quantity%` filled in per line.

<Tip>
  Loops are especially powerful for event automations. You can automatically create a prep task with a checklist of every recipe that needs to be made for a wedding, send the client an email listing every ingredient in their quotation, or fan a reminder out to every named contact on a funeral.
</Tip>

## Common questions

<AccordionGroup>
  <Accordion title="Can one automation perform multiple actions?">
    Yes. Click **Add Action** to chain as many actions as you need onto a single automation. Each action runs in turn when the trigger fires and the conditions match.
  </Accordion>

  <Accordion title="Can I test an automation before enabling it?">
    There's no dry-run mode. Create a test order or event and let the automation fire on it, then check the [Logs](/settings/automations-logs) to confirm it worked.
  </Accordion>

  <Accordion title="Why does my email look styled even though I only typed plain text?">
    The subject and message you write are wrapped in your branded notification layout — header, footer, colours, signature — before being sent. You write the content; Digital Florists handles the styling. Adjust the layout itself in [Notification Templates](/settings/notifications-templates).
  </Accordion>

  <Accordion title="Do loop variables work in SMS messages?">
    Yes — `%name%`, `%quantity%`, `%price%`, `%note%`, and the contact-specific ones (`%first_name%`, `%email%`, `%phone%`, `%label%`) all resolve in SMS the same way they do in email. The Event contacts loop also re-routes the SMS to each contact's phone in turn. Just keep the message short, since each loop iteration is a separate SMS and counts against your credits.
  </Accordion>

  <Accordion title="What happens to a scheduled task's due date if the order date changes?">
    The task keeps its original due date. The due date is worked out when the automation fires and doesn't recalculate if the order or event date shifts afterwards.
  </Accordion>
</AccordionGroup>

## What's next?

<Columns cols={2}>
  <Card title="Triggers & Conditions" icon="bolt" href="/settings/automations-triggers">
    Control when your automations fire.
  </Card>

  <Card title="Logs & Troubleshooting" icon="list-check" href="/settings/automations-logs">
    Check what your automations have done and fix issues.
  </Card>

  <Card title="Notifications" icon="bell" href="/settings/notifications">
    Manage the email templates your automations use.
  </Card>

  <Card title="Tasks" icon="list-check" href="/daily-operations/tasks">
    View and manage tasks created by automations.
  </Card>
</Columns>
