# Building a flow

How to create a flow and work on its canvas: adding, moving and renaming steps, saving the draft and fixing what blocks publishing.

**Language:** en
**Audience:** platform
**TLDR:** Create a flow in Marketing › Flows with New flow, blank or from a template. Add steps with the + between steps: the canvas lays them out as a tree whose branches rejoin below each split. Changes stay unsaved until you click Save changes; a draft with errors can be saved but not tested or published until Fix your flow to publish it has nothing left to list.
**Translation key:** platform.automations.flows.building-a-flow
**Search keywords:** canvas, new flow, blank flow, add step, palette, undo, copy paste step, rename step, needs attention, fix your flow, save draft, discard, Iris in the editor, flow builder, journey builder
**Related pages:** /platform/es/automations/flows/building-a-flow, /platform/en/automations/flows, /platform/en/automations/flows/triggers-and-entry, /platform/en/automations/flows/templates, /platform/en/automations/flows/versions-and-publishing, /platform/en/automations/flows/limits-and-safeguards, /platform/en/ai/ai-assistant
**Docs index (every page):** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/llms.txt
**This zone's index:** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/en/llms.txt
**This page:** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/en/automations/flows/building-a-flow/ (HTML) · https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/en/automations/flows/building-a-flow.md (Markdown)
**Other language (es):** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/es/automations/flows/building-a-flow.md

You build a flow on a canvas, in the flow's **Build** tab. The canvas starts with
the trigger that decides who enters, and you grow it one step at a time: a message,
a wait, a split that sends each contact down a different branch, an update to the
contact. The panel arranges the steps for you, so the work is deciding *what*
happens and *where* in the path, never drawing boxes or arrows.

Everything you change on the canvas is a **draft**. It only exists in your browser
until you save it, and saving still sends nothing: a flow reaches contacts only when
a person publishes it (see
[Testing, publishing and versions](/platform/en/automations/flows/versions-and-publishing)).
If the flow is already published, the contacts inside it keep following the version
they entered with while you edit the draft.

## Create a flow

#### 1. Open Flows

In the dashboard side menu, go to **Marketing › Flows** and select **New flow**.

#### 2. Choose how to start

The panel asks **How do you want to start?**

- **Blank flow** — an empty canvas that you name and build yourself.
- **From a template** — a ready-made flow for an event your project already
  receives. When some of them already work with the events your project
  receives, the option shows how many, for example **2 for you**. Using a template creates the flow and a draft, and
  nothing more: nothing is published or switched on. The gallery and what each
  template sets up are explained in [Flow templates](/platform/en/automations/flows/templates).

If your project has no templates available, **New flow** skips this question and
goes straight to naming the flow.

#### 3. Name the flow and choose how contacts enter

In **Name your flow**, type a name — it is required. Below it, **How contacts
enter** comes with **Event** selected: the flow starts each time a contact does
something, such as starting a checkout or placing an order. The other option,
**Schedule**, is shown as **Coming soon** and can't be selected yet (see
[The trigger: who enters and when](/platform/en/automations/flows/triggers-and-entry)).

Select **Create flow**. The panel confirms with **Flow created**.

The name is for you and your team, and it is also sent as `utm-campaign` in the
links of the flow's messages, so pick one you'll recognise in your analytics
tool. You can change it later from the flow header
([Managing flows](/platform/en/automations/flows/managing-flows)).

#### 4. Set the trigger event

The flow opens in its **Build** tab with the event trigger already on the canvas
and its settings open on the right. Select the event that brings a contact into the flow and,
if you need them, its conditions and audience. Everything about the trigger is
in [The trigger: who enters and when](/platform/en/automations/flows/triggers-and-entry).
From here you add steps below it, as described in the next sections.

A new flow has a single draft, marked **Draft** next to its name. If a flow's
canvas is ever empty, it shows **Start by choosing how contacts will enter the
flow** and lets you pick the trigger from there. A flow whose name has been cleared
appears as **Untitled flow**.

## The canvas

The canvas is a **tree** that grows downwards from the trigger. You never place a
step by dragging it: the panel lays the steps out automatically, and you add a
step only at a **+** between two steps (its tooltip reads **Add a step here**).

- **The trigger card** sits at the top. It summarises three things in rows:
  **Trigger when** (the event, or **No event set**), **Limits** (how often the
  same contact can enter, for example **Can re-enter · min 5 minutes apart**), and
  **Goal or exit** (what counts as success and when a contact leaves early). Clicking
  a row opens the trigger's settings on the matching tab: **Trigger**, **Limits**
  or **Goal & exit**. The first two are explained in
  [The trigger: who enters and when](/platform/en/automations/flows/triggers-and-entry);
  the third in [Goals and exits](/platform/en/automations/flows/goals-and-exits).
  The trigger can't be moved, copied or deleted.
- **Each step card** shows the step's icon, its name and a one-line summary of its
  settings. Clicking it opens its settings in a side panel on the right. The
  **Send message** step is the exception: it opens the full-screen **Edit message**
  editor, explained in [Sending messages](/platform/en/automations/flows/sending-messages).
- **The main path ends in Flow completed.** A contact who reaches it has finished
  the flow. You don't need to add an end step yourself.

### Splits, branches and where a step lands

A split step (a step from **Split the flow**, or a wait that has several outcomes)
opens one **branch** per outcome, side by side. Each contact takes exactly one
branch. When a branch runs out of steps, the contact **continues below the split**,
where the branches rejoin — you never draw that join, it is always there. A branch
with no steps at all is valid: contacts who take it go straight to what follows
the split.

Because of that, **where you click + decides who gets the step**:

- A **+ below the split** (after the branches rejoin) adds the step for everyone,
  whichever branch they took.
- A **+ at the top of a branch** adds the step only for the contacts who take that
  branch.
- If you add a split in the middle of a chain, the steps that were below it stay
  below the new split, for everyone. They are never pulled into one of its
  branches.

For example, a welcome flow that sends a Spanish message to contacts in Spain and an
English one to everyone else needs one tag update to mark both groups as welcomed.
Put **Update tags** once, below the split, rather than once in each branch:

```mermaid
flowchart TD
    T["Trigger: Customer created / updated"] --> S{"Check attribute: Country"}
    S -->|Spain| A["Send SMS in Spanish"]
    S -->|Otherwise| B["Send SMS in English"]
    A --> U["Update tags: add welcome-sent (everyone)"]
    B --> U
    U --> E["Flow completed"]
    class E success
```

How each split decides which branch a contact takes is explained in
[Branches](/platform/en/automations/flows/branches).

### Moving around the canvas

The bar at the bottom of the canvas has **Zoom out**, **Zoom in**, a level menu with
50 %, 100 % and 150 %, **Fit to view** to see the whole flow at once, and **Show
minimap** for a small overview in the corner. You can also zoom and pan with the
mouse wheel or the trackpad. **Esc** closes whichever panel or editor is open.

## Add a step

Click a **+** and the step palette opens. Type in **Search steps…** to filter by
name or description (with no result it shows **No step matches.**), or browse the
groups. When you choose a step, it is inserted at that **+** and its settings open
straight away.

![The step palette open from the + between two steps](/platform/en/automations/flows/images/building-a-flow--1-step-palette.png)
*The palette groups steps as the panel does; scroll it for the rest.*

| Group                  | Step                    | What it does (as the palette describes it)                         | Explained in                                                           |
| ---------------------- | ----------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| **Send**               | **Send SMS**            | A text message. Every phone can receive one.                       | [Sending messages](/platform/en/automations/flows/sending-messages)    |
|                        | **Send RCS**            | A branded message, with an SMS fallback if it cannot be delivered. | [Sending messages](/platform/en/automations/flows/sending-messages)    |
| **Wait**               | **Fixed delay**         | Wait a fixed amount of time.                                       | [Waits](/platform/en/automations/flows/waits)                          |
|                        | **Timezone delay**      | Wait for an allowed hour in their own timezone.                    | [Waits](/platform/en/automations/flows/waits)                          |
|                        | **Smart delay**         | Wait for the best moment to reach them.                            | [Waits](/platform/en/automations/flows/waits)                          |
|                        | **Wait for delivery**   | Split on whether the last message arrived.                         | [Waits](/platform/en/automations/flows/waits)                          |
|                        | **Wait for activity**   | Wait for a click or a reply, with a time limit.                    | [Waits](/platform/en/automations/flows/waits)                          |
| **Split the flow**     | **Check tag**           | Route by the tags the contact carries.                             | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **Check list**          | Route by the lists they belong to.                                 | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **Check segment**       | Route by which segment they are in.                                | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **Check attribute**     | Route by any field of the contact.                                 | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **Check consent**       | Route by the channel's consent policy.                             | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **Check reachability**  | Route by whether a channel can reach them.                         | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **Check event**         | Route by whether the contact did an event.                         | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **Check entry event**   | Route by the event that started the flow.                          | [Branches](/platform/en/automations/flows/branches)                    |
|                        | **A/B split**           | Split by percentage to compare branches.                           | [Branches](/platform/en/automations/flows/branches)                    |
| **Update the contact** | **Update tags**         | Add or remove tags on the contact.                                 | [Updating the contact](/platform/en/automations/flows/contact-updates) |
|                        | **Update lists**        | Add them to lists, or take them out.                               | [Updating the contact](/platform/en/automations/flows/contact-updates) |
|                        | **Manage subscription** | Change their subscription on a channel.                            | [Updating the contact](/platform/en/automations/flows/contact-updates) |
| **Goal**               | **Goal reached**        | Record that the contact met the flow's goal, and carry on.         | [Goals and exits](/platform/en/automations/flows/goals-and-exits)      |
| **End the flow**       | **Exit flow**           | End the flow here for this contact.                                | [Goals and exits](/platform/en/automations/flows/goals-and-exits)      |

A few rules about what the palette offers:

- **Send RCS** appears only when your project can send RCS; otherwise the **Send**
  group has **Send SMS** alone. To start sending RCS, see
  [What is RCS](/platform/en/channels/rcs/what-is-rcs).
- **The channel of a send is fixed when you add it.** On the canvas both appear as
  **Send message**; to switch a message from SMS to RCS or back, delete the step and
  add the other one.
- **Exit flow** is offered only inside a branch, never on the main path (which
  already ends in **Flow completed**), and nothing can follow it in that branch.
- When you have copied a step, a **Clipboard** group with **Paste** appears at the
  top of every palette (see the next section).

## Move, copy and delete steps

Every step except the trigger has a **⋮** menu on its card while you are editing the
draft:

| Action                      | What it does                                                                                                                                                                                                                                                                                                                      |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Move up** / **Move down** | Swaps the step with its neighbour in the same chain. A step never leaves its branch, and a split moves together with all its branches. The option is greyed out at either end of a chain.                                                                                                                                         |
| **Duplicate**               | Drops a copy right after the original and opens it. A split is copied with all its branches and the steps inside them, but not with what follows it.                                                                                                                                                                              |
| **Copy**                    | Keeps a copy of the step so you can paste it somewhere else; the panel confirms with **Copied. Paste it with (+)**. Then click any **+** and choose **Paste** under **Clipboard**.                                                                                                                                                |
| **Delete**                  | Removes the step and closes the gap. Deleting a single step asks for no confirmation. Deleting a split removes all its branches and everything inside them, so if those branches hold steps the panel first asks **Delete this step?** and tells you how many more steps will go; the flow continues where the branches rejoined. |

How copy and paste behave:

- The clipboard holds **one** step and empties once you paste it. A split travels
  with its branches, and a message with its texts, languages and sender.
- You can paste into another flow of the **same project**: the copy survives
  opening a different flow. Opening a flow in another project empties it. It lives
  in that browser tab and is not your computer's clipboard.
- **Goal reached** and **Exit flow** have nothing to configure, so they can't be
  copied (Goal reached can still be duplicated).

**Undo** and **Redo** appear in the toolbar whenever there is something to undo or
redo, and reach back over your recent changes on the canvas. Quick edits to the same
step, such as typing a text or dragging a slider, count as one change. Inside
**Edit message**, undo only reaches the changes you made since you opened that
message.

## Rename steps and branches

A step is called by its type until you give it a name. To rename it, open the step
and click its title or the pencil next to it: **Rename step** asks for a **Custom
name**. Leave the field empty to go back to the default name.

Branches are renamed the same way, from the branch's menu inside the split's
settings: **Rename branch** asks for a **Branch name**. Names are optional; a branch
without one is titled from its condition (for example **One of: vip**) or as
**Branch 1**, **Branch 2**… The branches of an **A/B split** are titled by their
percentage and can't be renamed.

> **Tip**: Name your steps and branches after what they mean to you — "Spain", "VIP
> customers", "Second reminder". When you follow a contact through a flow, the
> contact journey lists the steps they went through by name, but it doesn't say
> which branch they took; clear names are what let you tell the paths apart (see
> [Monitoring a flow](/platform/en/automations/flows/monitoring-a-flow)).

## Save, discard and conflicts

**There is no autosave.** As soon as you change something, two buttons appear in the
toolbar: **Save changes** stores the draft, and **Discard** throws away everything
since the last save (and clears the undo history). If you try to leave the flow, or
switch to another of its versions, with unsaved changes, the panel warns **You have
unsaved changes. Leave without saving?** and confirming discards them.

- **Inside Edit message** there is **Save changes** but no **Discard**: use **Back
  to the flow builder** to return to the canvas.
- **A draft with errors can be saved.** Saving often is safe; the errors stay
  marked until you fix them, and the draft simply can't be tested or published
  until then.
- **One draft per flow.** If the same draft was saved from somewhere else — another
  tab, or a teammate — after you opened it, saving shows **This draft changed
  somewhere else**. **Overwrite** replaces it with your version; cancelling keeps
  your changes unsaved on screen. To keep the other version instead, discard your
  changes and reload the page.

Saving is not publishing. Once everything is saved and the draft has no errors, the
toolbar offers **Test run** and **Publish** (Publish only while the draft differs
from what is live). Until then neither button is there: while there are unsaved
changes, **Save changes** and **Discard** take their place, and while the draft has
errors, the toolbar shows **Fix your flow to publish it**. Testing and publishing are
explained in
[Testing, publishing and versions](/platform/en/automations/flows/versions-and-publishing).
A published version is shown read-only on its own tab; to change it, you work on
the draft and publish again.

## Fix what blocks publishing

The panel checks the flow while you build it. A step with a problem shows an amber
triangle on its card — its tooltip reads **Needs attention** — and the toolbar shows
**Fix your flow to publish it** with the number of problems. Open it to see the
list: problems that affect the whole flow come first, then one row per step, with
the step's name and what is missing. Click a step row to open that step.

Most problems appear the moment you make them; the rest show up a moment later, when
the panel has checked the whole flow. If you expect a problem that isn't listed yet,
save the draft: the check made on saving is the one that decides whether the flow
can be published. Some range errors, such as a wait that is too short, are shown in
red inside the step's own settings, so open the step to read the exact message.

![The Fix your flow to publish it list with three steps that need attention](/platform/en/automations/flows/images/building-a-flow--2-fix-your-flow.png)
*Click an error to open the step.*

#### Errors that block publishing

The messages below are the ones you can run into while building from the panel.
The panel shows the step's name before each one.

| Where                                | Message                                                                                      | How to fix it                                                                                                                                                                                                   |
| ------------------------------------ | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Whole flow                           | *The flow has N steps, over the 50-step limit.*                                              | Remove steps, or split the journey into two flows. The trigger and each exit event count as steps too; see [Limits and safeguards](/platform/en/automations/flows/limits-and-safeguards#how-big-a-flow-can-be). |
| Whole flow                           | *Flow can run up to N days on its longest branch, over the 180-day limit.*                   | Shorten the waits on the longest path through the flow.                                                                                                                                                         |
| Trigger                              | The trigger is marked until it has an event.                                                 | Select the trigger event.                                                                                                                                                                                       |
| Send message                         | *The … message is incomplete: it needs a sender and a text* (the channel name fills the gap) | Open **Edit message** and complete the sender and the text. An RCS message with its SMS fallback switched on needs both levels complete, and every language you added needs its own sender and text.            |
| Check tag, Check list, Check segment | *Every membership branch must have a mode and at least one value*                            | Give each branch at least one tag, list or segment.                                                                                                                                                             |
| Check attribute                      | *Every attribute branch must carry a filter*                                                 | Add a condition to each branch.                                                                                                                                                                                 |
| Check entry event                    | *Every trigger-event branch must carry a filter*                                             | Add a condition on the entry event to each branch.                                                                                                                                                              |
| Check event                          | *Every event-search branch must specify an event type*                                       | Select the event for each branch.                                                                                                                                                                               |
| Check reachability                   | *Every capability branch must have at least one state*                                       | Select at least one state for each branch.                                                                                                                                                                      |
| Wait for activity                    | *Every wait branch must have at least one matcher*                                           | Add at least one condition (a click, a reply, an event…) to each specific branch.                                                                                                                               |
| Wait for activity                    | *A fallback branch must come after every specific branch*                                    | Move the fallback branches below the specific ones.                                                                                                                                                             |
| Wait for activity, **Did an event**  | The step is marked while the condition uses **Any data source**.                             | Select the specific data source the event comes from.                                                                                                                                                           |
| Fixed delay, Wait for activity       | *This wait is shorter than 1 minute, the minimum.* (shown in the step's settings)            | Set a wait of at least 1 minute.                                                                                                                                                                                |
| Timezone delay, Smart delay          | *Maximum delay must be greater than minimum delay*                                           | Make **As late as** later than **As early as**.                                                                                                                                                                 |

What each step needs is explained on its own page:
[Sending messages](/platform/en/automations/flows/sending-messages),
[Waits](/platform/en/automations/flows/waits),
[Branches](/platform/en/automations/flows/branches). The flow-wide limits are
gathered in [Limits and safeguards](/platform/en/automations/flows/limits-and-safeguards).

Two notices in the toolbar look similar but **don't** block anything:

- **N of 50 steps** appears when the flow gets close to the step limit. Up to the
  limit the flow publishes normally; the notice suggests splitting it into smaller
  flows. The count includes the trigger and each exit event, so it can be higher than
  the number of cards you add (see
  [Limits and safeguards](/platform/en/automations/flows/limits-and-safeguards#how-big-a-flow-can-be)).
- **1 goal step with no message before it** warns that a **Goal reached** step can be
  reached without any message being sent first. A goal only counts once the contact
  has been sent at least one message, so a contact who reaches it that way records
  nothing.
  Move it after a message or add one before it (see
  [Goals and exits](/platform/en/automations/flows/goals-and-exits)).

## Iris in the flow editor

Iris is available on every plan; on the Free plan its usage is very limited, enough to
try it. The floating **Ask Iris** button opens it
right in the editor, working on the flow in front of you. Iris reads the draft as it
is on screen — including changes you haven't saved yet and the errors the panel is
flagging — so you can ask what the flow does, why a step needs attention or how to
build a part of it.

When Iris suggests changes, it first shows them in a confirmation card that lists
each change (for example, adding a step after another one, or changing a step's
settings). Once you confirm, the changes land on the canvas as a single change, **not
saved**, and the card offers **Undo** while it is still the last change you made. Iris
leaves the draft ready for you: reviewing it, saving it and publishing it stay with
you. More about the assistant in [Iris, your AI assistant](/platform/en/ai/ai-assistant).

## Related

- [The trigger: who enters and when](/platform/en/automations/flows/triggers-and-entry) - The event, its conditions, the audience and how often a contact can enter.
- [Flow templates](/platform/en/automations/flows/templates) - Start from a ready-made flow for the events your project receives.
- [Testing, publishing and versions](/platform/en/automations/flows/versions-and-publishing) - Try the draft with one contact, then publish it to everyone or to a small group.

---

This is one page of the Instasent documentation. For the complete machine-readable index of every guide and API reference, fetch https://staging-instasent-docs-nextjs.oscar-284.workers.dev/llms.txt — start there for full context.
