# Testing, publishing and versions

How to test a draft with one contact, publish it to everyone or to a small group, and work with the versions a flow keeps.

**Language:** en
**Audience:** platform
**TLDR:** A test run puts one contact through the saved draft with real, charged messages and stays out of your stats. Publish to everyone makes the draft the new Live version; Publish to a small group runs it as a live test on about 10% of entering contacts, which you then promote to 100% or archive. Contacts already inside finish on the version they entered with, and any archived version can be republished as a copy or loaded back into the draft.
**Translation key:** platform.automations.flows.versions-and-publishing
**Search keywords:** go live, launch flow, version history, rollback, roll back, revert, restore a version, canary, staged rollout, soft launch, preview, test contact, test-contacts tag, simulate flow, dry run, skip waits, pin branch, unpublished changes
**Related pages:** /platform/es/automations/flows/versions-and-publishing, /platform/en/automations/flows, /platform/en/automations/flows/building-a-flow, /platform/en/automations/flows/managing-flows, /platform/en/automations/flows/monitoring-a-flow, /platform/en/automations/flows/flow-analytics
**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/versions-and-publishing/ (HTML) · https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/en/automations/flows/versions-and-publishing.md (Markdown)
**Other language (es):** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/es/automations/flows/versions-and-publishing.md

Every flow has two sides. The **draft** is the one you edit, on the flow's **Build**
tab; the **published versions** are the ones contacts actually run. Nothing you build
reaches anyone until you publish it, and publishing never moves the contacts who are
already in the flow: each of them finishes the version they entered with. Between
editing and publishing for everyone there are two safety nets. A **test run** puts one
contact of your choice through the saved draft so you can read exactly what arrives,
and a **live test** gives a new version to about 10% of the contacts who enter, so you
can compare it with the current one before deciding.

Publishing is always done by a person, in the dashboard. Iris and integrations that use
the [Product API](/platform-api/product-api/flows/overview) can prepare a flow and leave
its draft ready for you, but testing it, publishing it, switching its entry on or off and
archiving it happen here, on the flow's page.

## Test with one contact

A test run answers the question you have before publishing: *what will a contact actually
get?* It runs the saved draft for one contact, from the trigger to the end, so you see the
real text with its variables filled in, the links, the branch the contact takes and the
order of the messages, on a real phone.

The **Test run** button sits in the toolbar of the **Build** tab, and only appears when
the draft is saved and has no errors. While there are unsaved changes, **Save changes**
and **Discard** take its place; while the draft has errors, the toolbar shows **Fix your
flow to publish it** instead (see [Building a flow](/platform/en/automations/flows/building-a-flow)).
That rule guarantees that the test always runs exactly what is on screen.

### Set up the test

**Test run** opens the dialog **Run the flow for one contact**, which explains that it
"runs the saved draft on the real engine, so you can read what arrives before publishing"
and that it "stays out of your stats and version history". It has these rows:

- **Contact** — who runs the test. The list opens on your **Test contacts**: the
  contacts that carry the tag `test-contacts`. To add one, search for the contact and
  star it; the star adds that tag to the contact in your audience, so it is waiting in
  the list the next time. You can also add the tag by hand, written exactly like that
  in lowercase. It is an ordinary tag: it shows on the contact like any other.
- **Event** — appears only when the flow's messages use event variables (`_event.*`),
  such as the order number or the cart link. The panel preselects a real, recent event
  of the trigger's type, and you can change it or remove it. Its data fills the event
  variables of your messages. It does **not** decide branches: a split that looks at the
  entry event takes its default branch unless you pin it under **Branches**. Without an
  event, those variables come out empty in a message that is still sent.
- **Branches** — appears only when the flow has splits. **Select** opens **Select
  branches for the test run** on the canvas: click a step to make the test reach it, or
  click a branch label to send the contact out through that branch. Branches you don't
  pin decide on their own, with the contact's real data. Pinning is how you walk every
  path of a flow with the same contact: run it, pin the other branch, run it again. If
  you edit the flow afterwards and a pinned branch no longer fits, the panel drops it
  and says so.
- **Messages are sent for real and charged** — the last row, as a reminder.

Next to **Run flow**, at the bottom of the dialog, the **Auto-skip waits** checkbox is on
by default. Waits that only count time (**Fixed delay**, **Timezone delay**, **Smart
delay**) pass straight through, so you don't wait days for the next message. Waits that
listen for something (**Wait for delivery**, **Wait for activity**) keep waiting, because
ending them early would invent an answer; for those, use **Skip** on the step while the
test runs.

Select **Run flow** to start.

### Follow the test

The run starts straight away: test runs enter immediately, whatever the trigger's
processing mode. The canvas switches to the test view, which paints the contact's path on
the flow with the status of each step. A step where the contact is waiting shows when it
will fire and a **Skip** button. **Skip** ends that wait as if its time had run out: on a
**Wait for activity** the contact leaves through **No interaction**, and on a **Wait for
delivery** through **Not delivered**, if the message still has no delivery result. To test
a branch that reacts to the contact, tap the link or reply from the test phone instead.

The toolbar of the test view offers:

- **Details** — opens the contact journey, the step-by-step record of the run (see
  [Monitoring a flow](/platform/en/automations/flows/monitoring-a-flow)).
- **Cancel execution** — while the run is still going, stops the contact where they are.
- **Run again** — opens the dialog again with the same choices (contact, pinned
  branches), to repeat the test after a change.

To go back to editing, select the **Build** tab. The test runs a snapshot of the draft as
it was saved, so you can keep editing while it runs without changing what it does. Only
the latest test is kept: it stays under **Last test run**, the first section of the
archive box at the end of the tab strip, with the contact's name and the run's status,
and the next test replaces it.

### What a test run checks and what it doesn't

> **Warning**: Test runs and live tests are not simulations. Both run on the real engine, send real
> messages to real contacts and are charged like any other message. Try a draft first with
> a contact you can check, such as yourself or a colleague.

- **Entry is skipped.** The contact you choose enters directly: the trigger's event
  conditions, its audience and the re-entry limits aren't checked. To see whether a real
  contact would enter, look at the flow's activity once it is published (see
  [Monitoring a flow](/platform/en/automations/flows/monitoring-a-flow)).
- **Everything after entry is real.** Each message goes through its consent policy and
  the contact's subscription like any other, so if the test contact can't receive a
  message, the journey shows that step as not sent and why. **Update tags**, **Update
  lists** and **Manage subscription** steps change the test contact for real too.
- **It stays out of your figures.** A test run doesn't count in the flow's statistics and
  gets no version number. The flow's activity lists it with **Preview** as its version
  and **Test** as the way it entered.
- **It does count towards the contact's re-entry limits.** The flow's limits look at every
  run of the flow, the test included. Right after a test, the contact is within the
  **Minimum time between enrollments**; while the test is running, it is one of their
  **Simultaneous runs per contact**; and it counts as one of their entries for the
  **Enrollments per contact limit**, so with **Once only** that contact doesn't enter for
  real while the test is on record. A test leaves no permanent mark: it counts only while
  its run is kept (14 days), and after that it stops counting. If a test contact then triggers the flow for real and
  appears under **Didn't enter** with "Per-contact frequency limit reached" or "Per-contact
  re-entry limit reached", this is why (see
  [Monitoring a flow](/platform/en/automations/flows/monitoring-a-flow#why-a-contact-didnt-enter)).

Each message a test run sends is charged like any other message a flow sends; waits,
branches and contact updates cost nothing.

## Publish

Publishing turns the saved draft into a numbered version that contacts run. There are two
destinations: **everyone** who meets the entry conditions, or a **small group** of them as
a live test (explained [below](#live-test-try-a-version-on-about-10)).

#### 1. Save the draft

Select **Save changes**. The **Publish** button only appears when the draft is saved,
has no errors and differs from what is live. The **Build** tab tells you when
there is something to publish: it shows an amber cloud icon whose tooltip reads
**Unpublished changes**.

#### 2. Open the Publish menu

Select **Publish** in the toolbar of the **Build** tab. The menu offers two options,
each with the share of contacts it reaches:

- **Publish to everyone** — tagged **100%** (or **90%** while a live test is running):
  "From now on, every contact that meets the entry conditions runs this version."
- **Publish to a small group** — tagged **10%**: starts a live test, explained in
  [Live test: try a version on about 10%](#live-test-try-a-version-on-about-10).

#### 3. Confirm

For **Publish to everyone**, the panel asks **Publish draft to Live?**: "The draft
becomes the active version. Contacts already inside finish on their current version;
new contacts enter the new one." Select **Publish**. The panel confirms with **Draft
published to Live**.

![The Publish menu with Publish to everyone and Publish to a small group](/platform/en/automations/flows/images/versions-and-publishing--1-publish-menu.png)

The new version appears on the **Live** tab with its number (**v1** the first time). The
**Build** tab keeps a draft with the same content, ready to be the starting point of your
next change, and the cloud icon disappears until you save something different.

### When the Publish button isn't there

The panel shows **Publish** only when there is something valid to publish. If it's
missing, the reason is one of these:

- **There are unsaved changes.** **Save changes** and **Discard** sit in its place; save
  first.
- **The draft has errors.** The toolbar shows **Fix your flow to publish it** with the
  list of problems (see [Building a flow](/platform/en/automations/flows/building-a-flow)).
- **The draft is identical to what is live.** There is nothing new to publish, which is
  also why the **Build** tab shows no cloud icon.
- **The flow is archived, or your user can only view automations.** An archived flow is
  read-only (see [Managing flows](/platform/en/automations/flows/managing-flows)).

### The first publish switches entry on

A new flow is created with its entry off, and its header reads **Draft**. The first time
you publish it — to everyone or to a small group — entry switches on by itself: the header
changes to **Active** and the switch reads **Enrollment active**. If you're publishing,
you want the flow to start.

Later publishes leave the switch as it is. If you paused the flow with **Pause
enrollment** (the same action as **Disable** in the flows list), it stays paused after you
publish a new version, and nobody enters until you select **Activate enrollment**.

There is one exception to the first publish. If the project already has as many active
flows as its plan allows, the version is published but entry stays off: the header reads
**Enrollment paused** and nothing at publish time says why. The reason appears in the
tooltip of the entry switch. Pause another flow to free a slot and then activate this one;
the limit is explained in [Managing flows](/platform/en/automations/flows/managing-flows#active-flows-limit).

Publishing costs nothing. What is billed is each message the flow then sends, as
explained in [Sending messages](/platform/en/automations/flows/sending-messages).

## Contacts already inside keep their version

Every run is tied to the version the contact entered on, and follows that version to the
end, even if you publish newer ones in the meantime. Contacts who enter after you publish
run the new version. The version you replaced is archived, but publishing cancels nothing
in it: the contacts still inside carry on, step by step, until they finish. The one
exception is a version that has been archived for about three months, counted from the
day it was archived: the platform then retires it, and its remaining runs end as **Canceled**, as explained in
[Monitoring a flow](/platform/en/automations/flows/monitoring-a-flow#why-a-run-ended).

This is why you can change a flow that is running without affecting the contacts already
inside. A contact halfway through a
three-day wait never lands on a step that no longer exists, or on a branch you've
reorganised: the path they started is the path they finish. In the archive box, each
archived version shows how many contacts are still inside it, and the flow's activity
shows the version of each run (see [Monitoring a flow](/platform/en/automations/flows/monitoring-a-flow)).

The flip side is that a fix doesn't reach the people already inside. For example:

1. Your **Ask for a review** flow waits three days after an order is delivered and then
   sends a message with the review link. Version **v1** is live.
2. You notice a typo in the message. Two customers are in the middle of the three-day
   wait.
3. You fix the text on the **Build** tab, select **Save changes**, then **Publish** ›
   **Publish to everyone**. The fix becomes **v2**.
4. Every customer who enters from now on gets the corrected text. The two customers who
   were already waiting are still on **v1**, so when their wait ends they receive the
   message **with the typo**.

If those messages must not go out, stop the old version's runs: open **v1** from
**Archived versions** in the archive box and use the cancel button next to **N inside
now** to **Cancel executions**. Its contacts stop where they are and receive nothing else;
they don't move to **v2**, so they won't get the corrected message either. How cancelling
works, and how to stop a single contact, is explained in
[Managing flows](/platform/en/automations/flows/managing-flows#cancel-executions).

Pausing the flow doesn't stop them either: **Pause enrollment** closes the entry, while
the contacts inside finish their journey and their messages are charged.

## Versions and the tab strip

A flow keeps several versions at once, each with a role. The roles are permanent and
there is at most one of each:

| Role          | What it is                                                                                           | Numbered |
| ------------- | ---------------------------------------------------------------------------------------------------- | -------- |
| **Draft**     | The only editable version, on the **Build** tab. Saving replaces it. Contacts never run a draft.     | No       |
| **Live**      | The version that every contact who meets the entry conditions runs.                                  | Yes      |
| **Live test** | A version published to a small group: it runs for about 10% of the contacts who enter, next to Live. | Yes      |
| **Preview**   | The snapshot of the draft that a test run uses. It never appears in the version history.             | No       |

**Archived** is not a role but a state. When a Live version is replaced, or a live test
ends, that version keeps its role, gains an archive date and becomes read-only. Its
contacts finish, its figures stay available, and you can republish it or load it into the
draft at any time (see [Go back to an earlier version](#go-back-to-an-earlier-version)).

Version numbers — **v1**, **v2**, **v3**… — are given when a version is published, to
everyone or to a small group. Live and live test share the same count, and a number is
never reused. Every publish creates a **new** version with the next number, including
promoting a test and republishing an old version, because both publish a copy. For
example: **v4** is live and you start a live test, which becomes **v5**. When you promote
it, the copy that goes live is **v6**, and **v4** and **v5** are archived.

```mermaid
stateDiagram-v2
    state "Live test" as LiveTest
    [*] --> Draft: new flow
    Draft --> Live: Publish to everyone
    Draft --> LiveTest: Publish to a small group
    LiveTest --> Live: Promote to 100%
    LiveTest --> Archived: test archived or promoted
    Live --> Archived: replaced by a newer version
    Archived --> Live: Republish to everyone
    Archived --> LiveTest: Republish to a small group
    Archived --> Draft: Edit as draft
    class Live success
```

Every publish, republish or **Edit as draft** creates a copy: the version it starts from
stays where it was.

### The tab strip

Below the flow's name, a strip of tabs says at all times which versions exist and which
one you're looking at:

- **Build** — the draft. An amber cloud icon (**Unpublished changes**) appears when the
  saved draft differs from what is published.
- **Live** — the live version, with its number. While a live test runs, it also shows
  **90%**.
- A second **Live** tab, with a flask icon and **10%** — the live test, while one runs.
  The panel calls it **Live test** where you start or end it.
- **The archive box**, the last icon on the strip. Its menu has two sections: **Last test
  run**, the latest test with its contact and status, and **Archived versions**. The number
  next to **Archived versions** counts the archived versions that still have contacts
  inside. Each row shows the archive date, the version number and how many contacts are
  still inside; versions with contacts inside come first, then the most recent. It lists
  up to 20 versions.

The version number on each tab is a coloured pill: **green** while entry is active,
**grey** while entry is paused, and **amber** once archived. A flow with nothing
published, archived or tested shows only the **Build** label, without a strip.

![The version tabs of a flow with the archived versions menu open](/platform/en/automations/flows/images/versions-and-publishing--2-version-tabs.png)

Each tab offers what makes sense for that version, and the rest sits in the **⋮** menu
next to it:

| Tab                         | Main action                                         | In the ⋮ menu                       |
| --------------------------- | --------------------------------------------------- | ----------------------------------- |
| **Build**                   | Edit, **Test run**, **Publish**                     | —                                   |
| **Live**                    | None: it is read-only, and shows the flow's figures | **Edit as draft**                   |
| **Live** at 10% (live test) | **Promote to 100%**                                 | **Edit as draft**, **Archive test** |
| An archived version         | **Republish**                                       | **Edit as draft**                   |

The figures shown on the **Live** tabs and on archived versions are explained in
[Flow analytics](/platform/en/automations/flows/flow-analytics).

### Publish state in the flows list

The flows list sums up each flow's versions in its **Publish state** column:

| State                   | Meaning                                                         |
| ----------------------- | --------------------------------------------------------------- |
| **Published**           | There is a Live version and the draft is identical to it.       |
| **Unpublished changes** | There is a Live version and a saved draft that differs from it. |
| **Draft**               | Only a draft; nothing has been published yet.                   |
| **Empty**               | The flow has no versions yet.                                   |
| **Live test · 10%**     | A live test is running.                                         |

## Live test: try a version on about 10%

A live test lets you try a change on real traffic while limiting who sees it: a new text,
an extra reminder, a different wait. The new version runs for about 10% of the contacts who
enter; the rest keep running Live. You compare how the two perform and then decide whether
the change goes to everyone.

To start one, select **Publish** › **Publish to a small group** on the **Build** tab. The
panel asks **Start a live test on 10%?**: "About 10% of contacts that meet the entry
conditions run the test version; the rest stay on Live. It sends for real and takes about
10% of Live's reach while active." Confirm with **Publish to a small group**; the panel
shows **Live test started on \~10%**, and the flows list marks the flow **Live test · 10%**.

### Who is in the test group

- **About 10% of the contacts who meet the entry conditions.** The share is fixed: you
  can't change the percentage or choose a segment as the test group.
- **The split is per contact, not per entry.** The same contact always lands on the same
  side, so someone who enters several times while the test runs always gets the same
  version.
- **There is no fallback to Live.** The split happens before each version checks its own
  audience. A contact in the test group who doesn't meet the test version's audience
  doesn't enter at all; they don't run Live instead. Keep this in mind if the test version
  changes the audience.
- **It shares the flow's limits.** The live test doesn't add capacity: Live and the test
  count against the same **Enrollment pace**, and if the flow reaches it, both sides are
  trimmed in proportion.
- **It is real traffic.** The test version sends real messages, and its runs, goals and
  conversions count in the flow's figures like any others.

### A flow with nothing published yet

If the flow has never been published, **Publish to a small group** works as a soft launch:
only about 10% of the contacts who meet the entry conditions enter, and the rest don't run
anything yet. The confirmation reads **Launch to 10% of contacts?**: "This flow has nothing
published yet, so only about 10% of contacts that meet the entry conditions enter it. It
sends for real. Publish to everyone when you're happy with the results." As a first
publish, it also switches the flow's entry on.

### While the test runs

You can keep working on the draft. Two things happen if you publish it again before the
test ends:

- **Publish to everyone** replaces Live — the option shows **90%** — and the live test
  keeps running next to the new Live.
- **Publish to a small group** replaces the running test: the old one is archived and its
  runs finish on it.

How Live and the test compare — runs, goals, conversions, with a check of whether the
difference is significant — is explained in
[Flow analytics](/platform/en/automations/flows/flow-analytics#live-test-vs-live).

### End the test

Open the live test's tab (**Live** with **10%**) and choose one of two endings:

- **Promote to 100%** — the button on that tab. The panel asks **Promote the test to
  everyone?**: "Sends 100% to the tested version and ends the test. Running executions
  finish on their version." It publishes a copy of exactly the tested version as the new
  Live, with a new number, and archives the test. The panel confirms with **Test promoted
  to everyone**.
- **Archive test** — in the tab's **⋮** menu. The panel asks **Archive the test?**:
  "Archives the test version and sends 100% back to Live. Running test executions finish
  on their own." It confirms with **Test archived**. In a soft launch there is no Live to
  go back to, so archiving the test means the flow stops running for everyone.

If the test version no longer passes the editor's checks, the tab shows **This version has
errors and can't be published.** in place of **Promote to 100%**.

> **Warning**: **Publish to everyone** ships the **draft**, not the test. If you've edited the draft
> since you started the live test, publishing it gives everyone something nobody tested.
> To give everyone exactly what you tested, use **Promote to 100%**.

**Example.** Your **Abandoned cart** flow sends one reminder, and **v4** is live. You want
to know whether a second reminder with a discount code brings more orders. You add it on
the **Build** tab, save, and select **Publish to a small group**: the test becomes **v5**,
and about one in ten shoppers who start a checkout get two reminders, while the rest keep
getting one. After a couple of weeks you compare goal rate and revenue in the flow report.
If the test wins, **Promote to 100%** makes the copy **v6** live for everyone; if not,
**Archive test** sends everyone back to **v4**.

The live test is billed like Live: each message its contacts receive is charged, and
nothing else.

## Go back to an earlier version

Archived versions are kept, so you can return to one if a change didn't work out. Open it
from the archive box › **Archived versions**; it opens read-only with its own figures. From
there, there are two ways back.

### Republish an archived version

**Republish** opens the same menu as **Publish**:

- **Publish to everyone** — "A copy of this version goes live for every contact that meets
  the entry conditions." The confirmation, **Publish this version to everyone?**, adds that
  "contacts already inside another version finish the journey they entered on."
- **Publish to a small group** — "A copy of this version starts a live test on a small
  group of the contacts that meet the entry conditions." The confirmation is **Start a live
  test with this version?**; if a live test is already running, it adds "The current live
  test is archived and replaced."

Either way, what gets published is a **copy** with a new number. The archived version
stays archived, and your draft isn't touched. The button isn't offered, and a sentence
takes its place, when there is nothing to publish — **This version already matches Live**
— or when the version no longer passes today's checks — **This version has errors and
can't be published.** In that case, load it into the draft, fix it there and publish it.

**Example.** On **v3** you changed the wait of your **Welcome new contacts** flow, and
fewer people are converting. You open **v2** from **Archived versions** and select
**Republish** › **Publish to everyone**. A copy of **v2** goes live as **v4**. The contacts
who entered on **v3** finish it, unless you cancel its executions.

### Edit as draft

**Edit as draft**, in the **⋮** menu of any published or archived version (Live
included), copies that version into the draft so you can start your next change from it.
The panel asks **Replace your draft with v2?** (with the version you chose): "Your draft
will be replaced by a copy of v2. What's published doesn't change." It confirms with
**Draft replaced with a copy of v2**.

Use it to undo experiments on the draft and go back to what is live, or to rebuild on top
of an older version. Your current draft is overwritten, including any work you haven't
published, and nothing reaches contacts until you publish the draft again.

## Related

- [Building a flow](/platform/en/automations/flows/building-a-flow) - Work on the canvas, save the draft and fix what blocks publishing.
- [Managing flows](/platform/en/automations/flows/managing-flows) - Pause entry, archive, and cancel the executions of a version.
- [Monitoring a flow](/platform/en/automations/flows/monitoring-a-flow) - See who entered, on which version, and follow each contact's journey.
- [Flow analytics](/platform/en/automations/flows/flow-analytics) - Read each version's figures and compare a live test with Live.

---

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.
