A flow can be saved as a JSON file and imported again. This is useful for:
- Backups before a big change.
- Moving a flow between websites (workspaces).
- Starting from a ready-made flow, like the sample below.
Export a flow
Open Chatbot, open the flow's menu and choose Export. You'll get a file named like welcome-triage.retrochat-flow.json.
Import a flow
- Open Chatbot and click Import.
- Choose a
.jsonfile and give the flow a name. - RetroChat checks the file before importing. Anything it can't use is left out, and any problems are listed so you can fix them in the builder.
- Review the flow, press Test, then Activate it when you're ready.
Importing never replaces your existing flows: it always creates a new one.
Sample flow
This is a complete, working flow for a fictional bike shop, Northwind Bikes:
- It greets the visitor and offers four choices.
- Buying a bike: it asks for a budget. Big budgets go to a specialist (after taking an email); everyone else gets a tip that repeats their budget back.
- Booking a service: it takes an email and ends with a confirmation.
- A quick question: an AI answer step replies from your knowledge base, and hands off if it isn't sure.
- Talk to a person: it checks
agents_online, so it only promises a quick reply when someone is actually online.
Download the sample flow, or copy it from here:
{
"format": "retrochat-flow",
"version": 1,
"name": "Northwind Bikes: sales and service",
"exported_at": "2026-10-06T09:00:00.000Z",
"graph": {
"start": "welcome",
"steps": [
{
"id": "welcome",
"type": "message",
"text": "Hi! 👋 Welcome to Northwind Bikes.",
"next": "topic"
},
{
"id": "topic",
"type": "question",
"text": "What can we help you with today?",
"input": "choice",
"variable": "topic",
"options": [
{ "id": "o_buy", "label": "Buying a bike", "next": "budget" },
{ "id": "o_service", "label": "Booking a service", "next": "service_email" },
{ "id": "o_question", "label": "A quick question", "next": "ask_ai" },
{ "id": "o_person", "label": "Talk to a person", "next": "who_is_online" }
],
"next": null
},
{
"id": "budget",
"type": "question",
"text": "Great choice! Roughly what's your budget in US dollars?",
"input": "number",
"variable": "budget",
"options": [],
"next": "budget_check"
},
{
"id": "budget_check",
"type": "condition",
"rules": [
{ "id": "r_premium", "variable": "budget", "op": "gt", "value": "1500", "next": "premium_email" }
],
"else_next": "starter_tip"
},
{
"id": "premium_email",
"type": "question",
"text": "Our specialists will help you choose the right model. What's the best email to reach you?",
"input": "email",
"variable": "email",
"options": [],
"next": "who_is_online"
},
{
"id": "starter_tip",
"type": "message",
"text": "Good news: plenty of our city and hybrid bikes fit a budget of ${{budget}}, and every bike comes with a free first service.",
"next": "anything_else"
},
{
"id": "service_email",
"type": "question",
"text": "Happy to book you in. What's your email so we can confirm a time?",
"input": "email",
"variable": "email",
"options": [],
"next": "service_done"
},
{
"id": "service_done",
"type": "end",
"text": "Thanks! We'll email {{email}} with the next free service slots."
},
{
"id": "ask_ai",
"type": "ai",
"text": "Ask me anything about our bikes, delivery or servicing.",
"instructions": "Keep answers short and friendly. Suggest a test ride when it fits.",
"max_turns": 3,
"on_unsure": "handoff",
"next": "anything_else"
},
{
"id": "anything_else",
"type": "question",
"text": "Is there anything else I can help with?",
"input": "choice",
"variable": "more",
"options": [
{ "id": "o_yes", "label": "Yes, talk to a person", "next": "who_is_online" },
{ "id": "o_no", "label": "No, that's all", "next": "bye" }
],
"next": null
},
{
"id": "who_is_online",
"type": "condition",
"rules": [
{ "id": "r_online", "variable": "agents_online", "op": "equals", "value": "true", "next": "to_team" }
],
"else_next": "offline"
},
{
"id": "to_team",
"type": "handoff",
"text": "Connecting you with our team now. It usually takes a minute or two."
},
{
"id": "offline",
"type": "handoff",
"text": "Our team is offline right now. Leave your question here and we'll reply by email first thing tomorrow."
},
{
"id": "bye",
"type": "end",
"text": "Thanks for stopping by. Ride safe! 🚲"
}
]
}
}
The AI answer step needs the Autopilot plan, or AI replies left in your trial. Without them, the step hands the visitor to your team instead.
File format
A flow file is a JSON object:
| Field | Meaning |
|---|---|
format |
Always "retrochat-flow" |
version |
File format version, currently 1 |
name |
The flow's name |
exported_at |
When it was exported (ISO date) |
graph.start |
The id of the first step |
graph.steps |
The list of steps |
Every step has a unique id and a type. Steps link to each other by id, and null means "nowhere": the flow stops there.
type |
Fields |
|---|---|
message |
text, next |
question |
text, input (choice, text, email, phone or number), variable, options (for choice: id, label, next), next |
condition |
rules (each: id, variable, op, value, next), else_next |
ai |
text, instructions, max_turns (1–20), on_unsure (handoff or next), next |
handoff |
text |
end |
text |
The op values are listed in Variables and conditions. In any text, {{variable}} is replaced with the visitor's answer.
RetroChat also accepts a bare { "start": …, "steps": [ … ] } object without the outer wrapper.