Skip to main content

Conversation flows

A conversation flow greets every new chat visitor with a short, friendly menu and points them in the right direction — to your AI assistant or to a real person — before they even type a word. Instead of a blank chat box, the visitor sees a question and a few buttons and picks the one that fits.

Flows are deterministic: the visitor can only choose the options you set up, so the start of every conversation is predictable and on-brand.

The built-in triage flow​

You do not have to design a flow from scratch. ConnectWiz ships with a ready-made triage flow that asks:

Hi! How can we help you today?

…with three buttons:

  • Sales — hands the conversation to the AI assistant to help with buying questions.
  • Support — hands the conversation to the AI assistant to help with an issue.
  • Talk to a person — sends the conversation straight to your team (the AI steps aside and an agent is notified).

The flow is created in your workspace language, so your visitors see it in the same language as the rest of your widget.

Starting from a template​

Start from a template on the Flows screen offers a handful of ready-made flows: a triage menu, answering questions from your knowledge base, an order lookup against one of your tables, collecting a lead, a two-day follow-up — and three that show off what an empty canvas does not suggest:

  • Channel menu — WhatsApp's own list rather than our buttons, with the row somebody taps arriving as an ordinary branch.
  • Book an appointment — offer the next free times, let them pick one, book it, and both of the ways it does not work out: a week with nothing free, and the slot somebody else takes between your offer and their tap.
  • Wait for another system — hand a payment provider a one-time address and park until they answer, with a path for when nobody does.
  • Appointment confirmation, Appointment cancelled — offer a new time and Missed appointment — follow up — each starts from an appointment change instead of a message.

Each one arrives as a draft — switched off and unpublished — so you can change the words and fill in the blanks before anybody sees it. Where a template needs something only you can choose (which table holds your orders, which approved WhatsApp template to send), the card says so before you pick it.

Starting a new flow​

New flow creates one straight away and drops you on the canvas. It arrives empty — no steps, no name you did not choose — and asks the first question: what starts this flow?

Pick one: someone opening a conversation, someone writing a word you choose, a time you set, or one of your forms coming back. The answer is drawn at the head of the graph, so you can always see what makes the flow run, and you can change or add to it from that card later.

Then add steps from the panel on the left. A flow with no steps saves fine — it is a draft — but it cannot be published until it has at least one.

Turning a flow on​

  1. Open the Flows page in the admin panel (left sidebar).
  2. If you have no flows yet, click Add triage flow. The ready-made flow is created but stays Inactive so nothing changes for your visitors yet.
  3. Review the preview — each step shows the bot's message, its buttons, and where it leads (to the AI, to a person, or to the end).
  4. Click Activate. From now on, every new chat conversation starts with this flow.

Only one flow that greets people can be active at a time — activating one turns the other off. A flow that runs on a schedule is not in that race: it opens its own conversations on its own clock, so switching a campaign on leaves your greeting exactly where it was, and switching your greeting on leaves the campaign running.

Turning a flow off​

Click Deactivate on the active flow. New conversations will then start with a plain chat box (or your AI assistant, if it is enabled) instead of the flow. Conversations that are already in progress finish on the flow they started with.

How flows work with the AI and your agents​

  • Sales / Support buttons hand the conversation to your AI assistant. The next thing the visitor types is answered by the AI — using your knowledge base if you have set one up.
  • Talk to a person is the same as a human takeover: the AI goes quiet for that conversation and it appears in your team's queue, waiting to be picked up.

Because the flow only runs at the very start, it never interrupts a live conversation — once a visitor is chatting with the AI or an agent, the flow's job is done.

Using the visitor's own details in a message​

Anything a flow step writes can be read back later. Wrap a value in double braces and it is replaced with the real thing before the message is sent:

Hi {{ contact.first_name }}, your order is on its way.

Click Insert a value under any message box to see the values available in your workspace — including the custom contact fields you have added yourself.

When the value is empty​

If the person's first name is not known, the braces are replaced with nothing — never with the raw text. So the message above would read "Hi , your order is on its way." To say something better, add a fallback:

Hi {{ contact.first_name | default:"there" }}, your order is on its way.

The other things you can do to a value: upper, lower, trim, and date:"d.m.Y" for reformatting a date. Chain them with |.

Values your flow saved itself​

A Set data step (and a REST call that captures a response) can save a value for later. Read it back with vars:

Thanks — we will send the update to {{ vars.email }}.

Where a saved value goes​

A Set data step asks one question that is worth getting right: Write to.

  • This conversation only — the value is remembered for the rest of this chat and then forgotten. This is what you want for anything the flow needs to carry from one step to the next.
  • The person (permanent) — the value is saved on the contact record. It shows up on their profile, comes back in every future conversation on every channel, and is included when you export your contacts. Use this only for something genuinely true about the person, like their preferred language.

New steps are set to this conversation only, because a value that was only ever meant to get a flow from one step to the next should not become a permanent field on somebody's record.

If you mistype a name​

{{ contct.first_name }} will not save. The editor rejects the flow and tells you which name it did not recognise, so a typo is caught while you are still looking at the screen rather than by a customer three days later.

Seeing what a flow actually did​

Open a flow's Recent runs to see, conversation by conversation, every step it took: what it sent, which way each condition went, what the visitor chose, and where it ended.

Each run shows one of five states:

  • Waiting for the visitor — the flow asked something and is waiting. This is the normal state of a live conversation, not a problem.
  • Finished — it reached an ending you set up.
  • Stopped early — it ran out of steps: a dead end, or a step this workspace cannot run.
  • Failed — it could not continue, for example because a step points at one you deleted.
  • Running — it is mid-step right now.

A condition step shows both sides of the comparison — the field, what it actually held, and what you expected — plus which branch it took. If a condition seems to always go the same way, this is where you find out why.

Runs are kept for 30 days. Nothing sensitive is stored: a step that calls an outside service records the address, the result and which values it saved, never the credentials it sent.

One thing to keep in mind: a run shows what happened at the time. If you have edited the flow since, the steps may no longer match what the flow says now.

Seeing what one step saw​

Run a flow with Try it and then click any step on the canvas: beside its settings there is now Last test run, showing what that step was looking at when it ran — everything the flow had saved so far, and the customer's last message — and what it decided.

That is usually the whole answer to "why did it go down the wrong branch": a condition reading an empty value and one reading the wrong value look exactly the same until you can see the value.

A step the run never reached says so, rather than showing you nothing.

Seeing where people give up​

Open a flow's Runs screen and switch to Funnel. For each step it shows how many conversations reached it, how many stopped there, and where the rest went next.

The "stopped here" column is the one to read first: a step everybody reaches and nobody leaves is usually a question that is unclear, a button nobody wants, or a lookup that came back empty.

Pick the time window at the top — the last day, week or month — so you can see whether a change you made last week actually helped. Runs are kept for 30 days, so the funnel cannot look further back than that.

Test runs from the editor are never counted.

Trying a flow before anyone sees it​

Open a flow's canvas and click Test run. The flow runs for real — with nobody on the other end.

You can say what the visitor's name and email should be, so conditions have something to read, and list their replies in order (separated by commas). The test stops when it runs out of replies and tells you so, which is how you tell "I need to add another reply" from "the flow stopped here".

You get back what it would have said, what it would have done (assigned a department, handed over to a person — recorded, not performed), and the same step-by-step trace you see under Recent runs.

Nothing escapes a test run. No message is sent, no contact or conversation is created, nobody is assigned, and your flow statistics do not move. The one exception is deliberate: a step that calls an outside service really calls it, because that is what you are testing. What it will not do is save the answer onto anybody.

Which channels flows work on​

A flow runs wherever your customers write to you — WhatsApp, Instagram, Messenger, Telegram, SMS, email and the rest — not only in the website chat widget.

The one difference is when it starts. In the chat widget the flow greets the visitor as soon as they open the window, before they type. On every other channel there is no "opened" moment, so the flow starts on the customer's first message.

From then on it behaves the same everywhere: a tapped button moves the flow along, and a typed answer is understood wherever you set a step up to accept one — which matters on Instagram and Messenger, where buttons do not appear at all for someone writing from a desktop browser.

Your assistant will not talk over a flow. While a flow is running it owns the conversation; the assistant takes over at the step where you hand it the conversation, and not before.

A flow also stays quiet for messages that are not really questions: history imported when you connect a channel, forwarded chain mail, a thread another tool currently owns, and messages from other bots.

Going back to a version that worked​

⋯ → Published versions lists every graph that has been live, newest first, with the one your customers are running right now marked. Press Restore on any of them.

Restoring puts that graph back on the canvas. It does not publish it — nothing your customers see changes until you press Publish yourself. A rollback that published itself would push a graph live without anybody looking at it, which is the habit versioning exists to break.

A flow that has never been published has no history yet, which is every flow on its first day.

Saving a flow and publishing it are two different things​

Editing the canvas and pressing Save changes your draft. Your customers carry on with what they had. When the draft is ready, press Publish — that is the moment it reaches them.

While a draft differs from what is live, the flow shows Unpublished changes in the list and a note above the canvas, so a change never sits there looking live when it is not.

Publishing never interrupts a conversation in progress. Anyone already inside the flow finishes on the version they started with, even if you have since deleted the very step they were about to reach. Only conversations that start after you publish get the new version.

You can see every version you have published, who published it and when, and put an older one back on the canvas. Restoring loads the old version into your draft — it does not go live until you publish it, so you always get to look at it first.

A flow you have never published will not run, even if it is switched on. Press Publish once and it starts working.

What a step does when it fails​

A step that reaches outside your workspace — a call to another service — can fail: the other side is down, the address is wrong, it answers with an error. You choose what your flow does about it.

  • Carry on anyway — the flow moves to the next step as if nothing happened. This is what flows did before this setting existed, so nothing you already built has changed.
  • Stop the flow here — for a step whose answer the rest of the flow really needs.
  • Follow the error path — draw a second connection out of the step, label it error, and failures take it. The problem becomes part of your flow instead of a dead end.
  • Use a stand-in value, then carry on — the most useful one in a conversation. Save something like "not available right now", and the next step can say it rather than going silent.

You can also ask a step to try again — up to two extra attempts. The cap is deliberate: somebody is waiting on the other end of the chat, and a long silence is worse than a quick honest answer.

Whatever you choose, the failure is written into the run so you can see it under Recent runs — which step failed, why, and how many tries it took.

Starting a flow on what someone says​

By default a flow greets people at the start of a conversation. You can instead set it to run when the customer says something in particular — give it a few words like pricing, quote, how much and it runs whenever one of them appears.

Keyword flows are checked first, so a specific one wins over your general greeting. They can also run again later in the same conversation, which is the point of a keyword. They never interrupt somebody who is already partway through a flow — that conversation finishes first.

Following up later​

A Wait step pauses the flow for as long as you like — minutes, hours or days — and then carries on by itself. The visitor does not have to be there; the conversation simply continues at the right time.

That is what a follow-up is made of: thank someone, wait three days, ask whether they still need help. Same for a reminder, or a nudge after a quote.

A few things happen automatically so a follow-up never arrives when it should not:

  • If one of your team takes the conversation over while the flow is waiting, the follow-up is cancelled. You can see this on the run, with the reason.
  • Your assistant is not silenced while a flow is waiting. Somebody who writes in during those three days gets answered straight away, and the follow-up still arrives on time.
  • A follow-up is never sent twice, even if something goes wrong behind the scenes.

Waits are capped at 30 days.

Closing a conversation, or marking it urgent​

An actions step can set the conversation's priority and close it when the flow is done — alongside assigning a department or an agent and attaching tags.

Closing is applied when the whole flow finishes, so a goodbye message after that step will not reopen the conversation. A flow that answered the question can therefore tidy up behind itself, which is the work it was built to remove.

Only "close" and "reopen" are offered. Blocking a customer or binning a conversation is a decision about a person, and stays with people.

Looking something up in your own tables​

A table step reads and writes the tables you already keep in the workspace — your orders, your bookings, your price list — without any integration work.

Choose the table and what to do: find a row, add one, or change the row a previous step found. For a lookup, pick the columns to match on and put an expression in each, for example {{ contact.order_no }}. The row you find is saved, so the next step can say {{ vars.row.status }}.

Draw a connection labelled _empty for when no row matches — "no such order" is the most common outcome of a lookup, and without that path a customer whose row is missing is treated exactly like one whose row was found.

A change only ever applies to the row an earlier step in the same conversation found. There is no way to rewrite rows in bulk from a flow, on purpose.

Looking something up in your shop​

A products and orders step reads what you sell and what the person in the conversation has bought — the same catalogue and the same orders the rest of ConnectWiz uses, with no integration work of your own.

Pick one of two things to look up.

Find a product searches your catalogue by name or code. Put an expression in the search box if you want to use what the customer just typed. The item is saved, so the next step can say {{ vars.product.name }} or {{ vars.product.price }} — the amount and its currency are kept apart, so you write the sentence the way your language wants it.

Find this customer's order reads their orders, newest first, from both your own sales and any connected shop. Leave the number empty for their most recent, or narrow to one with an expression. The next step reads {{ vars.order.status }}, {{ vars.order.delivery }} or {{ vars.order.tracking }}.

An order number narrows — it never fetches

The step only ever looks among the orders of the person in this conversation. A number belonging to somebody else finds nothing. This matters because the number is usually an expression fed by whatever the visitor typed, and a step that looked orders up by number would hand a stranger's order to anyone who guessed one.

Draw a connection labelled _empty for when nothing is found. "We do not sell that" and "you have no such order" are the two most common outcomes of a shop conversation, and without that path the flow carries on talking about something it did not find.

If you run two of these steps in one flow, give them different names under Store the result under so the second does not overwrite the first.

Placing an order from a flow​

The same step can also place an order. Add a line for each thing being bought — a product code (or id) and how many — and both fields accept expressions, so a flow can order what the customer chose from a list menu.

The price is your catalogue's, not the flow's

This step cannot set a price or a name. Both are read from your catalogue at the moment of the order and written onto the line, so what the customer agreed to is what they get read back even if you reprice the item tomorrow. A step that could name a price would put a number carried in from the conversation straight into your ledger.

The order is a draft unless you tick "issue it straight away". A flow runs with nobody watching, and an automation that issues a document no one has read is how somebody gets billed for a mis-drawn connection.

An order in two currencies is refused rather than converted — there is no exchange rate this system is entitled to choose on your behalf. Nothing is written when a line names something you no longer sell, or something nobody has priced.

Asking for payment from a flow​

With payment links connected, the same step can make a Payment link for what the person owes on one of their orders. Name the order by its number — leave it empty to use the order this flow just placed ({{ vars.order.number }}). Like every order in this step, the number only ever looks among this person's own orders.

The amount is never yours to type: it is what is still owed, read from your ledger, and read again when the customer opens the link. A flow's link opens without approval — you drew the step, and that is the approval.

This step sends nothing. It leaves the link in the run's values, and the next step sends it:

  • {{ vars.payment.url }} — the address, for a message step or a link button;
  • {{ vars.payment.token }} — the code after /p/, for a WhatsApp template's link button (see below);
  • {{ vars.payment.amount }}, {{ vars.payment.currency }} and {{ vars.payment.expires_at }}.

Draw connections labelled already_paid (nothing is owed), no_provider (no payment service is connected) and refused (the conversation is on a marketplace, a public thread, a phone line or SMS, or the visitor's identity is not proven for an order they did not place in the chat). An outcome with no connection stops the flow rather than send an empty link, and the editor names the ones you have not drawn.

To thank the customer once they have paid, start a second flow with An order changes → Order paid (see below).

Letting the assistant answer one question​

An answer step borrows your assistant for a single question — using your knowledge base and your assistant's own instructions — and then the flow carries on with its next step. This is different from ending a flow by handing the conversation to the assistant: there, the flow is over.

Draw a connection labelled _unanswered for when the assistant has nothing to say. That is a normal outcome, and it is usually where you offer a menu or fetch a colleague.

You can point it at a question of your own instead of the customer's last message, turn the knowledge base off, and save the answer for later steps.

Opening a sales opportunity from the conversation​

An opportunity step creates a deal in your pipeline for the person you are talking to, or moves the one this flow just opened into another stage.

Give it a stage and a name — the name is worth building from the conversation (Quote for {{ contact.first_name }}), because a pipeline of rows all called "New deal" is a pipeline nobody reads. The value can come from something the flow captured earlier.

Choose move it to a stage and the step works on the deal this flow opened, or on the newest one still open for that person. Deals you have already won or lost are left alone. Draw an _empty connection for when there is nothing to move — that is an ordinary outcome, not a mistake.

Starting a flow when a form comes back​

Choose when a form comes back as a trigger and the flow starts for whoever filled it in. Pick which form to watch, or leave it on "any form", and choose the channel to reach them on.

The answers travel with it: your flow can branch on what was filled in with {{ vars.form.budget }} (using your own field names). That means the decision lives in the flow where you can see it, rather than hidden in a setting.

The person has to be somebody you can reach — a form filled in by an anonymous visitor is still saved, and your intake rules still run on it, but there is nobody to open a conversation with.

Like a scheduled flow, this one opens a conversation the customer has not written into, so on WhatsApp it must start with an approved template.

Starting a flow when an order changes​

Choose An order changes as a trigger and the flow starts when an order in one of your connected shops is placed, paid, shipped, delivered, cancelled or returned — or when a return or claim is opened or resolved. Under Order steps pick the steps you care about, and under Shops the shops; leave either empty and every step, or every shop, starts it. Any status change fires on every change of the shop's own status, once per order and status.

The order travels with it: {{ vars.commerce.order_number }}, {{ vars.commerce.status }}, {{ vars.commerce.tracking_url }}, {{ vars.commerce.carrier }} and {{ vars.commerce.total }}, and {{ vars.commerce.event }} says which step it was. Names, addresses and phone numbers are never passed to the flow.

A few rules keep it honest:

  • Only news. Orders that already existed when you connected the shop, and changes that reach us more than three days late, start nothing — connecting a shop does not greet a month of old customers.
  • Once. The same step of the same order starts the flow once, however many times the shop sends it.
  • Only people you know. The flow runs for a customer who is already one of your contacts. An order never creates a contact.

Marketplaces are internal only. Trendyol, Hepsiburada, n11, Çiçeksepeti, Pazarama, idefix, PttAVM, Amazon, Etsy, eBay and the Mirakl marketplaces (Teknosa, Koçtaş, MediaMarkt…) do not let you contact their buyers outside the marketplace, so their shops carry an Internal only badge. A flow one of their orders starts can tag, assign, create a task, notify an agent or write to your CRM, but every step that would message the customer — a message, a template, a form, an AI reply, a call — is skipped, and it never opens a new conversation. The editor warns you about such steps when you save. Orders from your own store — WooCommerce, ikas, Shopify, Ticimax or IdeaSoft — may message the customer, through the usual consent and 24-hour-window rules; on WhatsApp the first message to someone who has not written in must be an approved template.

Payments, too. Orders in ConnectWiz itself become Order paid when their balance reaches zero — through a payment link or a payment recorded by hand — and Order refunded when their payments are all given back. These carry {{ vars.commerce.payment_provider }} (iyzico, paytr, or empty for a hand-typed payment) and {{ vars.commerce.amount_paid }}, and are listed under Shops as Your own orders. A payment that reaches the ledger more than three days late is recorded but starts nothing.

Parcels, too. With Shipment tracking on, the carrier's reports are steps as well: Parcel status changed fires each time a followed parcel reaches a new status ({{ vars.commerce.status }} is then, for example, out_for_delivery or delivered), and the matching Order shipped, Order delivered or Order returned fires once per order. Orders in ConnectWiz itself are listed under Shops as Your own orders, and may message the customer like your own store's.

Starting a flow when a call is missed​

Choose A call is missed as a trigger and the flow starts when a known customer calls your own PBX — Netsantral or Bulutsantralim, see Your own PBX — and nobody answers. It runs once per call, and only for a caller who is already one of your contacts: a PBX call never creates a contact.

The call travels with it: {{ vars.call.number }}, {{ vars.call.line }}, {{ vars.call.extension }}, {{ vars.call.started_at }} and {{ vars.call.provider }}. Like a schedule, the flow opens its own conversation, so choose the channel it writes from; on WhatsApp the first message must be an approved template, and an SMS still goes through the consent and İYS rules.

Starting a flow when an appointment changes​

Choose An appointment changes as a trigger and the flow starts when an appointment is booked, confirmed (marked with your own "confirmed" status word), rescheduled, cancelled or missed — in the ConnectWiz diary, in a connected CRM such as Stella, or in Calendly. Under Appointment steps pick the steps you care about, and under Diaries the diaries; leave either empty and every step, or every diary, starts it.

The appointment travels with it: {{ vars.booking.date }}, {{ vars.booking.time }}, {{ vars.booking.service }}, {{ vars.booking.staff }}, {{ vars.booking.location }} and {{ vars.booking.manage_url }} (Calendly's own reschedule/cancel page), and {{ vars.booking.event }} says which step it was. Notes and anything clinical are never passed to the flow.

A few rules keep it honest:

  • A move is one step. A rescheduled appointment is Appointment rescheduled — never also a cancellation, so a "cancelled" flow does not tell someone their appointment is off when it only moved.
  • Only news. Appointments that were already in a CRM's diary when ConnectWiz first read it start nothing; only what changes after that does.
  • Once. The same step of the same appointment starts the flow once.
  • Only people you know. The flow runs for a customer who is one of your contacts; a booking never creates a contact.

Like a schedule, the flow opens its own conversation, so choose the channel it writes from; on WhatsApp the first message must be an approved template, and an SMS still goes through the consent and İYS rules. Reminders before an appointment are not a trigger — set them under Settings → Reminders, which re-check the appointment just before sending.

Seeing what is wrong before a customer does​

As you draw, the canvas keeps asking the server what is wrong with the flow, and shows the answer on the step it is about: a small red or amber badge in the corner of the card, with the explanation when you hover it.

Red is something that stops the flow being published — a step whose kind this workspace cannot run, a call step that has not said whether it is transactional or marketing. Amber is something that will not stop you saving but will bite somebody: a branch pointing at a step you deleted, two connections sharing a label so the second is dead, a consent gate with no refusal path, a channel step whose channel can no longer send what it was set up to send.

Findings about the flow as a whole — "this flow has no steps yet" — appear in the top-left instead, because there is no card to put them on.

Beside Publish there is a count of everything outstanding. Press it and the canvas goes to the first one. That is the only question worth answering at the moment you reach for Publish: is there something wrong with a step I am not looking at?

None of this blocks you. A half-wired condition is the ordinary middle of building something, and an editor that refused to save there is one you cannot come back to tomorrow. It is shown, not enforced.

Finding a step​

A graph has no reading order. A twenty-step flow is perfectly clear while you are building it and completely opaque three months later, because there is no scrolling down until you find something — only panning around after a card whose name you half remember.

The box at the top-left of the canvas searches steps by name, by kind, and — the one people actually remember — by the words the step says. It searches your notes too, because "the bit with the note about marketing" is exactly the kind of landmark people navigate by. Press a result and the canvas centres on it.

Taking a change back​

Ctrl/⌘ + Z undoes, Ctrl/⌘ + Shift + Z (or Ctrl + Y) redoes, and both are in the ⋯ menu. It goes back fifty steps and it covers everything the canvas does: adding a step, deleting one, renaming it, moving it, relabelling a connection, changing which step is the start, auto-layout, a note's text.

Selecting a step is not a change, so the first Ctrl+Z always takes back something you actually did rather than a highlight.

Ctrl/⌘ + C and Ctrl/⌘ + V copy and paste the selected steps, with fresh names and offset a little so you can see the copy. A pasted step is never the start — two start steps is not a thing, and quietly moving the pointer is not what a paste means.

To select several at once, hold Shift and drag a box around them. Plain dragging still pans the canvas, exactly as before.

Leaving a note on the canvas​

Press ⋯ → Add a note and a sticky note lands in the middle of what you are looking at. Type in it, drag it where it belongs, stretch it to enclose the steps it is about, and give it one of five colours.

A note is not a step. It never runs, the flow never reaches it, and it is not counted in anything — it is there for the next person to read, including you in three months. "Ask marketing before changing this", "this branch is for the Ankara branch only", "left here on purpose, do not tidy".

Sending something only one channel can send​

A plain message step reaches every channel, because every channel carries text. Some channels carry more than text, and those shapes are what the Apps section of the step palette is for.

Press +, open Apps, and you get your channels — by name, so two WhatsApp numbers are told apart. Press one and you get what that number can send right now: a list menu, quick-reply buttons, a link button, a carousel, a request for a location. Press Telegram and you get Telegram's: a phone-number request that Telegram itself verifies. Press your Messenger Page and you get receipts, coupons, image grids and the address form. Press an e-mail channel and you get an e-mail with a subject line — the one thing a message does not have.

The list is the channel's own answer, asked at the moment you open it. A WhatsApp number with no catalogue linked does not offer the product card; a Messenger Page with no privacy policy set does not offer the address form. Link the catalogue later and the entry comes back on its own. This is deliberate: a share the channel cannot complete would compose a message that is dropped without telling anyone, which looks exactly like it worked.

A menu waits for the tap. A statement — a location, a receipt — does not, so with nothing connected after it the flow ends there.

The eight shapes people build most — a list menu, quick-reply buttons, a link button, a location request, a pin, a phone-number request, an e-mail and a call button — have real fields: type the button text, add sections and options, and so on. Every box takes {{ }} expressions, so a menu can say this customer's own order number back to them. Meta's commerce templates (receipts, coupons, image grids, product carousels) are still authored as JSON, with their field names listed under the box.

If the channel loses the ability between saving and sending, the step fails with a reason in the run record rather than sending nothing quietly.

Making an appointment from a flow​

The assistant has been able to book for a while. What it could not do is book the same way twice — and "offer the next three times, take the tap, confirm" is a script most businesses want performed identically for everyone.

Two steps, because between them is the one part a flow cannot do: a person choosing.

Offer free times reads the next free slots into the flow. It says nothing itself — what to say about them is the next step's job — so follow it with a buttons step built from {{ vars.slots }}. Each slot carries a when a person can read and a start the booking step needs.

Book one writes the appointment, pointed at the time the customer chose. It goes through the same funnel as every other booking here, so the double-booking guard, the calendar sync and the notifications all apply.

Two paths are worth connecting. Nothing free (_empty) is an ordinary answer for a busy week. Somebody took it (_taken) is the ordinary consequence of asking a person to choose: between your offer and their tap, another customer can book the same slot — connect it back to the offer step and the flow simply asks again.

If you have more than one kind of appointment, the step has to say which. Booking "the first one" would put somebody in the wrong appointment.

A test run never books. It names what it would have done. A rehearsal that booked would take a slot a real customer then could not have.

Building the form without leaving the flow​

The when a form comes back trigger used to mean a walk: leave the canvas, find the forms page, make a form, add its fields, publish it, and come back knowing its name. Two buttons on the trigger remove that walk.

New form builds one right there. Name it, add fields — the same editor the forms page uses, so a field you add here behaves exactly as one added over there — and publish it. It is selected on the trigger when you are done. A form with no fields cannot be filled in and a draft has no live page at all, so both are said before you leave rather than discovered as a trigger that never fires.

Fill it in opens the real page, at the address a customer would open, so you can submit it and watch the flow run. This is not the canvas's Test run: a test run sends nothing, and this posts for real — a real contact, a real conversation, real messages. That is what makes it a test of the flow rather than of the form, and the dialog says so above the frame.

Waiting for another system​

A flow could already wait for the clock (Wait) and for the customer (a question, a form). It could not wait for a thing — a payment clearing, a parcel scanning, an approval somebody grants elsewhere.

Wait for a callback does that. It hands you a one-time address in {{ vars.callback.url }}; send it to the other system from the next step — in a request, as a template parameter, in a note — and the flow parks. When they post to it, the flow carries on from there, and whatever they posted is readable in the flow.

The address is good for exactly one use and then it is gone. Send the same confirmation twice and the flow runs once, because the second copy of "payment received" is not a second payment.

You have to say how long to wait. There is no default, because a default would be us deciding how long your clinic waits for a payment. Connect the nobody called back path (_timeout) too: systems go down and callbacks get lost, and without it the customer is left with a conversation that simply stopped.

Starting a flow when another system says something happened​

Choose when a webhook arrives as a trigger and this flow gets its own address. Save the flow and the address appears in the trigger, along with a secret and the header to put it in. Paste the address into whatever is going to call it — a payment provider, a shipping tool, your own back office.

The caller signs the body it sends: an HMAC of the raw body, in X-Signature: sha256=<hmac>. Anything unsigned or wrongly signed is refused, and the refusal says nothing more than "forbidden" — a message that explained itself would help somebody guessing at addresses.

The body has to say who it is about. A contact_id of yours, an email, or a phone. Nothing else can start a conversation, because a conversation is with a person.

By default nobody is created: an event about somebody you have never met is accepted and ignored, and you will see no_contact in the reply. If that is the case you actually want — "a new customer paid" usually is — tick create the person when we do not know them yet on the trigger. It still needs a phone or an email in the body: a contact with neither is a row nobody can reach, match or delete.

Everything else in the body is readable in the flow as {{ vars.payload.order }} and so on, so the flow can branch on what happened. It cannot choose a step: the body is data, never instructions.

Send the same event twice and it runs once. Add an X-Event-Id header and we key on that; without one we key on the body itself. Every sender retries, and the second copy of "payment received" is not a second payment.

If the secret ever leaks, press New secret. The address stays the same, so you do not have to find everyone who calls it — only the people who sign.

Letting the agent read your CRM itself​

An Agent step can be given tools it decides for itself when to use. Alongside business data tables, appointments, consent and WhatsApp rich messages, there are now two more.

Read the CRM lets the agent look up this customer's appointments, quotes, orders, balance, notes and documents, or your catalogue, staff and locations — on its own initiative, when the conversation calls for it.

Channel-native messages lets it send what this conversation's channel supports: a native list menu, quick-reply buttons, a link button, a location request, and on Telegram the verified phone-number request. The options it is offered are that channel's own — a Telegram thread is never shown a carousel.

Receipts, coupons and the address form are deliberately not offered to the agent. A receipt asserts that an order exists and a coupon is money nobody authorised; both stay available as a step you draw yourself.

It is read-only, and that is not a temporary limitation. A CRM step can write a note or book an appointment because you drew that step in advance and an admin opened the operation. A tool is a decision the agent makes in the moment, and booking somebody in on the strength of a sentence would route around the gate the whole integration is built on. If you want a flow to write, draw the step.

The workspace-wide assistant is not given it by default either. Attaching it to an agent step is you deciding that this conversation is one where reading somebody's history helps; the assistant answers everyone, including people nobody has matched to a record.

Asking your CRM something, mid-conversation​

If you have connected a CRM, it appears in the Apps section beside your channels. Press it and you get what your CRM can be asked — not what CRMs in general can do.

Reads: find the customer by the number they are writing from, their appointments, quotes, orders, what they owe, their notes, documents and deals; and about your workspace rather than the person, your catalogue, your staff and your locations.

Writes, if an admin has switched them on under Settings → Integrations: write a note, book an appointment, cancel one, create the customer, raise a quote, place an order, record a payment — and, with a CRM that keeps an activity timeline and deals (such as HubSpot), Log this conversation, Open a deal and Move a deal. Logging needs activity sync switched on, with its data-transfer notice accepted; deals need the workspace to have said the CRM keeps them. Both are part of the paid plans. The agent's Read the CRM tool reads deals but never opens or moves one.

Quotes and orders carry lines — what, how many, and the total for the line. The total rather than a unit price, because that is what your CRM's own line holds and two sets of arithmetic would eventually disagree on a row somebody has to reconcile. Every box takes {{ }} expressions, which is the point: a quote whose quantity is fixed at three is a quote you could have written by hand. A line with no item, or a quantity of zero, is dropped rather than guessed at — nothing invented ends up on somebody's invoice.

The answer goes into the flow's own bag under a name you choose — crm by default — so a later step can branch on it and a message can say it back with {{ vars.crm }}. Give two CRM steps different names, or the second quietly overwrites the first. It is deliberately not written into the conversation: somebody's appointment history in the transcript is in front of whoever opens the thread next.

Nothing found is a path, not a failure. Most people who write in have never been matched to a record over there, so connect the step's nothing found branch (_empty) and say something useful there. Without it the flow simply ends for them.

A CRM that is unreachable is a failure, and the step's "what if this goes wrong" setting decides what happens next — the two are different situations and the flow can answer them differently.

A test run never writes to your CRM. It names what it would have done. A rehearsal that put a stranger in a real diary is not a rehearsal.

If you have connected more than one CRM — say your clinic system and your accounting software — each appears in Apps with its own actions, and the step shows a CRM picker. A step reads and writes only the CRM chosen there; a step saved before you connected the second one keeps using the first. The agent's Read the CRM tool reads every connected CRM that keeps that kind of record and labels each answer with where it came from, so a balance held in your accounting software is not missed because your clinic system was asked first. The contact card shows one section per CRM.

Starting a flow yourself, from a conversation​

Some flows should not wait for anything. A returns walkthrough, a payment link, an onboarding sequence — the moment to send them is the moment an agent decides to, while they are reading the conversation.

Choose started by hand as the flow's trigger and publish it. It will never start on its own: it does not compete for arriving conversations, and it does not need to be switched on.

From then on, anyone who can reply in the inbox can send a customer through it. Open the conversation, press Start a flow in the header (or find it under the ⋯ menu on a narrow screen) and pick the flow. The customer receives the first message straight away.

This is not the test run. Test run on the canvas answers "would this work" and sends nothing; this one sends. If the conversation is already inside a flow you are told so rather than starting a second one on top of it, and a flow that has never been published says that too — you have usually just told the customer something is on its way.

Starting a flow on a schedule​

A flow does not have to wait for somebody to write in. Choose on a schedule as its trigger and it runs by itself — every day, or on the weekdays you pick, at a time you set.

A schedule needs three things: which channel it sends on (a workspace can have several numbers, and which one sends is a decision with a bill attached), how often, and who it goes to. The audience is chosen the same way a broadcast's is, with the same rules about blocked contacts and people who asked WhatsApp to stop messaging them.

The editor shows the next run back to you as soon as you save. If it says the schedule is unfinished, the server could not read it — usually a missing channel or time — and it will not run until that is fixed.

On WhatsApp, a scheduled flow must start with an approved template. A conversation you open yourself is outside the 24-hour window, and Meta accepts nothing else there. The editor warns you when a scheduled flow starts with an ordinary message; without a template every recipient would be refused.

The flow itself does the rest. Put a consent check and a "how often" step at the front of it and the schedule inherits both — the limits are steps you can see, move and argue with, rather than settings hidden behind the trigger.

Calling the customer from a flow​

A call step places a real phone call to the person in the conversation. Pick the line it dials from, and say what the call is for.

That second field has no default on purpose. "Answering something they asked for" and "marketing" are different things in law, only you can say which applies, and the marketing rules cannot be applied without it — so a flow with a call step will not publish until it is set. If you choose marketing and your workspace has declared İYS, the step checks that the person consented to being called before anything is dialled. Agreeing to be texted is not the same permission.

Draw a refused connection for when the call cannot be placed — no permission, no credit, a line that is not live. Without it the flow ends there, which is better than telling somebody "we are calling you now" when nobody is.

Testing a flow never rings anybody: a test run records what it would have done.

Not messaging the same person too often​

A how often step limits how many times a flow may reach one person. Give it a name — "promo", "review request" — a number, and a window in hours. Steps sharing a name share the budget, which is how "no more than three marketing messages a week" works across several flows at once.

Draw an over connection for people who have had enough. Without it the flow stops there rather than sending anyway.

It counts its own decisions, not your messages, so a long support conversation never eats into a marketing budget — and testing a flow never spends one.

A consent check step asks whether this person has agreed to hear from you on the channel you are talking to them on, and sends the conversation one way or the other. It is the step to put in front of a follow-up or a marketing template.

Draw a missing connection for people who have not agreed. Without it the flow stops there — which is safe, but it means the flow does nothing at all for anyone who has not opted in.

The step only reads consent. Recording it happens where the wording has been reviewed: your registration form, your keyword replies, or the assistant storing the customer's own words. What somebody agreed to is the sentence they were shown, so that sentence is not something to type into a flow.

Answering differently outside your opening hours​

A business hours step reads the opening hours from your workspace settings and either sends the conversation one way or the other, or holds it until you open.

Draw a connection labelled closed for out of hours; that path is the whole point of the step, and without it the flow simply ends there rather than greeting somebody at midnight as though you were in. The in-hours path is whatever else you drew.

Choose wait for opening instead and nothing is sent while you are shut — the step holds the conversation and carries on the moment you open, including later the same day if you close for lunch.

The hours themselves live in your workspace settings, not in the step, so changing them once changes every flow that reads them. If you have not set any, the step treats you as always open and says so when you check the flow.

Letting an assistant handle a whole stretch of the conversation​

An agent step is the assistant with hands. Where an answer step answers one question and gives the flow straight back, an agent step keeps talking to the customer for as many exchanges as the matter takes — finding out what they want, checking your price list, offering the times that are free, booking one — and only then hands back.

It lives in one box on the canvas. The customer's replies go to that same step; you do not draw the back-and-forth.

Its outcomes are the connections you draw. Label one booked and another no_deal, and those are the two things the agent may finish with — it is told their names and it cannot name anything else. This is why you do not type the outcomes anywhere: the lines on the canvas are the list.

Its tools are ticked, not drawn as steps. Under the step's settings you choose what it may reach for: your business data tables, appointments, marketing consent, WhatsApp rich messages, a payment link (which still waits for a team member's approval before it is sent). They appear on the card as attachments hanging under the step rather than as boxes in the path, because the agent decides when to use them — that is what you hired it for. A tool with nothing behind it yet (no bookable service, no data table) is simply not offered to it.

Give it a turn budget. By default it gets six exchanges. Draw a connection labelled _max_turns for where the conversation goes when it runs out — usually to a colleague. Without that connection, running out is treated as a failure of the step rather than a way to reach a person.

This step uses your assistant, so it counts towards your AI usage like any other reply, and it costs more than an answer step because it may take several turns.

Letting the assistant decide which way to go​

An understand step reads what the customer wrote and picks one of the branches you drew. Label a connection billing and it may answer billing; add a _default connection for "none of these", which is what it is told to answer when nothing fits.

Its choice is saved, so the next steps can use it — {{ vars.category }} — and you can see in the flow's run record exactly what the assistant answered, including when it answered something you did not draw.

This step uses your assistant, so it counts towards your AI usage like any other reply. If your workspace has no credit left, the step stops and says so instead of running up a bill.

Sending a conversation down one of several paths​

A route step looks at one value and follows the connection whose label matches it. Label one connection billing, another delivery, and one _default for everything else.

You can match the whole value or ask whether it merely contains the label — useful when the value is a sentence rather than a single word. Capital letters and spaces around the value never matter.

Without a _default connection, a value that matches nothing stops the conversation there, so the editor warns you.

Asking for something with one of your forms​

A form step sends one of your published forms as a link and waits for it to come back. The answers are saved, so later steps can use them — for example {{ vars.form.order_number }} — and branch on them.

This is different from asking a question in the chat: you get the fields you designed, with their own required rules, instead of one sentence somebody has to read.

Only published forms can be chosen. A draft form's link does not open, so the step refuses to send it.

You can set a number of hours to wait. If you do, draw a second connection labelled _timeout for what should happen when nobody fills it in — otherwise the customer who never answered is treated exactly like the one who did. Leave it empty to wait as long as it takes.

While the form is outstanding the assistant can still answer questions in the chat, and the flow picks up again the moment the form is submitted. The link works once.

Sending a file​

Add your price list, size chart or returns form once, and any flow can send it. In a file step, pick it from your library — or add it right there without leaving the flow.

Sending a file does not make a second copy of it, and removing it from the library later never empties a message somebody already received.

Only files from the library can be sent this way. Documents a customer uploaded into their own conversation stay there.

Following up on WhatsApp after a day or more​

WhatsApp only lets you send a normal message within 24 hours of the customer's last one. After that, the only thing that gets through is a template you have had approved in WhatsApp Manager.

This matters as soon as a flow waits: a reminder three days later is outside that window by definition. Use a WhatsApp template step instead of a message step for anything sent after a long wait. Type the template's name exactly as it is approved, its language code, and a value for each blank in it — the visitor's details work here, so {{ contact.first_name }} fills itself in.

If the template has a link button whose address ends in a blank — for example https://…/p/{{1}} — fill it under Link button values, in the order the buttons appear. This is how a payment link reaches a customer after the 24 hours: use {{ vars.payment.token }} from a Payment link step. The step reads the button's position from your approved template; if the template is not among the ones ConnectWiz has synced for this number, the step fails rather than send a broken button.

If a flow tries to send an ordinary message when the window has closed, the step stops and says so in the flow's run record, rather than appearing to send something the customer never receives.

The editor warns you when a step waits a day or more and then sends a plain message. If that flow only runs on your website's chat, you can ignore the warning — the rule is WhatsApp's.

Offering a list of things to choose from​

When a step fetches something — open orders, upcoming appointments, saved addresses — a buttons step can build its buttons from that list instead of from the ones you typed.

Under Buttons from a list, point it at the saved value holding the list (for example vars.orders), then say what each button should say and what identifies the row when someone presses it. On the canvas, draw one connection labelled _item for what happens after a press, and one labelled _empty for when the list turns out to be empty.

The row the visitor picked is saved, so the next step can talk about it: {{ vars.item.number }}.

At most ten rows are shown — more than that is not a menu anybody can read, and a step that fetched more says so in its run record.

Choosing when a flow runs​

Under When should this flow run? you can add more than one way in. A help menu can open both when a chat starts and when somebody types "help" — one flow, two triggers, no copies to keep in step.

Each trigger can be switched off on its own without deleting it, and without affecting the others.

One of the ways in is on a schedule — the only one that does not wait for somebody to write in. See "Starting a flow on a schedule" below.

Leaving the list empty is a choice, not an omission. A flow with no triggers never starts by itself; it runs only when another flow calls it. That is exactly what you want for something like "collect the address" that several flows share — otherwise it would start itself on somebody's first message.

Reusing one flow inside another​

A connector step hands the conversation to another flow. Under And afterwards you choose what that means:

  • Continue there — the conversation moves to the other flow and stays there. This is what a connector has always done.
  • Come back here when it finishes — the other flow runs, and then this one carries on at the step connected after the connector.

The second option is what makes a flow worth reusing. Build "ask for an address" once, call it from three places, and each caller carries on with its own next question afterwards.

Anything the other flow saved is still there when it comes back, so a flow called to collect something can hand it over simply by saving it.

Two things worth knowing:

  • If nothing is connected after the connector there is nowhere to come back to, so it behaves as "continue there". The editor warns you.
  • A flow can call a flow that calls another, up to five deep. Beyond that the run stops and says so — that depth is almost always a flow that calls itself by accident.

If the other flow ends by putting the customer through to a person, it does not come back. Picking the conversation up again on top of the agent who just took it would be the flow talking over them.

Keys for a step that calls another service​

A Request step that needs a key should not have it typed into the step. Save it once under Settings → Credentials — choosing the "API key for a request" type — and pick it from the step's Sign the request with list.

A saved key is stored encrypted. It is never shown back to you, never returned by the API, and never included when you export a flow. The step's list shows names, not values.

If you have an older flow with a key written into a header, it still works — but you will see a warning telling you to move it, and the value is hidden wherever the flow is displayed or exported.

Good to know​

  • One active flow per workspace. Keep it focused; a short triage menu works better than a long tree.
  • Localized automatically. The built-in flow's text matches your widget language.
  • No setup risk. A newly added flow is always inactive until you choose to turn it on, so you can review it first.