Follow Avox Docs on Google
Pick Avox Docs as a preferred source and Google shows these pages more often when you search for help with Avox.
Follow Avox Docs on Google
Pick Avox Docs as a preferred source and Google shows these pages more often when you search for help with Avox.
A Flow is described by one Flow JSON document: a list of screens, the fields on each screen, and what the button at the bottom of each screen does. Avox's editor takes that JSON as it is, so any AI chat tool can write it for you if you give it the right rules.
This page gives you a prompt with those rules built in, a worked example, and the steps to put the result into Avox. You don't need to know JSON to use it.
There are two kinds of Flow. The prompt below writes the first kind; Live Flows with an AI covers the second.
If you're not sure which you need, start plain. Most lead forms, surveys, feedback and support forms don't need live data, and you can start from a premade live Flow when you do.
Copy this prompt into ChatGPT, Claude, Gemini or any other AI chat. Fill in the five lines under "About my business" first; leave everything under "Rules" exactly as it is.
You write WhatsApp Flow JSON for a business. Reply with ONLY the JSON:
no explanation before or after, no markdown code fences, no comments.
About my business:
- Business: [what you do and where, e.g. "a dental clinic in Pune"]
- What to collect: [e.g. name, phone number, which treatment, preferred day]
- Screens: [e.g. "screen 1: contact details, screen 2: what they need",
or "you decide, at most 3 screens"]
- Button on the last screen: [e.g. "Send"]
- Language for all text: [e.g. English]
Rules (follow every one):
1. The top level has exactly two keys: "version": "6.0" and "screens".
This Flow has no server, so never add "data_api_version",
"routing_model", "data_endpoint_uri", or any "data_exchange" action.
2. Every screen has:
- "id": capital letters and underscores only (e.g. CONTACT_DETAILS),
unique in the Flow, and never the word SUCCESS
- "title": a short title shown at the top of the screen
- "data": {}
- "layout": {"type": "SingleColumnLayout", "children": [...]}
3. A screen's layout "children" may start with a "TextHeading" and a
"TextBody" (each with a "text"), followed by exactly one
{"type": "Form", "name": "form", "children": [...]}.
The Form holds every input on that screen and ends with exactly one
"Footer" (the button).
4. Inputs you may use: "TextInput" (with "input-type": "text", "number",
"email" or "phone"), "TextArea", "Dropdown", "RadioButtonsGroup",
"CheckboxGroup", "DatePicker". Never ask for a password: every
answer is shown to the business team.
Every input has:
- "name": lowercase letters and underscores, unique in the whole Flow
- "label": the question shown to the customer
- "required": true or false
"Dropdown", "RadioButtonsGroup" and "CheckboxGroup" also have
"data-source": a list of {"id": "...", "title": "..."}.
5. Keep text short: labels of "TextInput", "TextArea" and "Dropdown"
20 characters or fewer, of "RadioButtonsGroup" and "CheckboxGroup"
30 or fewer, of "DatePicker" 40 or fewer; choice titles 30 or fewer,
Footer labels 35 or fewer, headings 80 or fewer. Put a longer
question in the input's "helper-text" (80 or fewer).
6. On every screen except the last, the Footer is:
{"type": "Footer", "label": "Next", "on-click-action":
{"name": "navigate", "next": {"type": "screen", "name": "<ID OF THE NEXT SCREEN>"}, "payload": {}}}
7. The last screen has "terminal": true and "success": true. Its Footer's
"on-click-action" is {"name": "complete", "payload": {...}}, and the
payload MUST list EVERY input in the whole Flow, on every screen, one
key per input, the key being the input's name. Only what is in this
payload is sent back; an input left out is lost. Use:
- "${form.<name>}" for inputs on the last screen
- "${screen.<SCREEN_ID>.form.<name>}" for inputs on earlier screens
Before you reply, check every input name appears in this payload.
8. Output must be valid JSON: double quotes only, no trailing commas.
When the AI replies, check that the answer starts with { and ends with }. If it added a
sentence or wrapped the JSON in a code block, copy only the part from the first { to the last
}.
Each rule matches something Avox or Meta checks:
Filled in for a small business that wants call-back requests:
- Business: a home cleaning company in Leeds
- What to collect: full name, phone, email (optional), which service,
best time to call, anything else they want to tell us
- Screens: screen 1: contact details, screen 2: what they need
- Button on the last screen: Send
- Language for all text: English
A good answer looks like this:
{
"version": "6.0",
"screens": [
{
"id": "CONTACT_DETAILS",
"title": "Request a call",
"data": {},
"layout": {
"type": "SingleColumnLayout",
"children": [
{ "type": "TextHeading", "text": "How can we reach you?" },
{ "type": "TextBody", "text": "We call back within one working day." },
{
"type": "Form",
"name": "form",
"children": [
{ "type": "TextInput", "name": "full_name", "label": "Full name", "input-type": "text", "required": true },
{ "type": "TextInput", "name": "phone", "label": "Phone number", "input-type": "phone", "required": true },
{ "type": "TextInput", "name": "email", "label": "Email", "input-type": "email", "required": false },
{
"type": "Footer",
"label": "Next",
"on-click-action": {
"name": "navigate",
"next": { "type": "screen", "name": "SERVICE_DETAILS" },
"payload": {}
}
}
]
}
]
}
},
{
"id": "SERVICE_DETAILS",
"title": "What you need",
"terminal": true,
"success": true,
"data": {},
"layout": {
"type": "SingleColumnLayout",
"children": [
{ "type": "TextHeading", "text": "What can we help with?" },
{
"type": "Form",
"name": "form",
"children": [
{
"type": "Dropdown",
"name": "service",
"label": "Service",
"required": true,
"data-source": [
{ "id": "regular", "title": "Regular cleaning" },
{ "id": "deep", "title": "Deep cleaning" },
{ "id": "end_of_tenancy", "title": "End of tenancy" }
]
},
{
"type": "RadioButtonsGroup",
"name": "best_time",
"label": "Best time to call",
"required": true,
"data-source": [
{ "id": "morning", "title": "Morning" },
{ "id": "afternoon", "title": "Afternoon" },
{ "id": "evening", "title": "Evening" }
]
},
{ "type": "TextArea", "name": "details", "label": "Anything else?", "required": false },
{
"type": "Footer",
"label": "Send",
"on-click-action": {
"name": "complete",
"payload": {
"full_name": "${screen.CONTACT_DETAILS.form.full_name}",
"phone": "${screen.CONTACT_DETAILS.form.phone}",
"email": "${screen.CONTACT_DETAILS.form.email}",
"service": "${form.service}",
"best_time": "${form.best_time}",
"details": "${form.details}"
}
}
}
]
}
]
}
}
]
}
And this is how it looks on a phone. It's the same preview the Flow editor shows next to your JSON; tap the button to move between the two screens:
Leeds Home Cleaning
Request a call
Fill in the fields marked * to continue
When a customer taps Send, WhatsApp sends Avox one reply holding full_name, phone,
email, service, best_time and details. WhatsApp sends the id of each choice (for
example deep); Avox shows it under its question with the choice's title ("Deep cleaning") in
the Inbox, on the contact's page and in the Flow's Responses.
Open the Flow wizard
Go to Flows and click Create Flow.
Start from scratch
Under Start from scratch, pick the category that fits best (for the example above, Lead generation) and click Continue.
Name it
Enter a Flow name and check the Categories, then click Next.
Paste the JSON
Click inside the Flow content Editor (JSON), select everything in it (Ctrl+A, or Cmd+A on a Mac) and paste the AI's answer over it. Leave Live data off.
Run
Click Run (or press Ctrl+Enter, Cmd+Enter on a Mac). It's an instant check in your browser: the phone preview redraws from your JSON, and Previewing above the phone lets you look at each screen. "Invalid JSON" means the text isn't JSON yet; see the table below.
Validate
Click Validate to run Meta's own check. It needs a connected WhatsApp number and doesn't publish anything.
Fix anything in Errors
Open Errors in the footer. It lists every problem in one numbered list: Avox's own checks and Meta's findings, then warnings in amber. If it says an answer is never sent back, click Send all answers. When it says "No errors - Meta's happy with this JSON." you're ready.
Create and publish
Click Create & publish. The Flow goes to Meta and shows as Published on the Flows page. From there, an automation's Use Flows action sends it (see Actions).
The fastest fix for anything in Errors: copy the whole list, paste it back into the same AI chat, and write "Fix these errors and reply with the full corrected JSON only." Paste the new answer over the old one and click Run and Validate again.
Changing a Flow later works the same way: ask the AI for the change ("add a question about budget to the second screen, keep all the rules"), then paste, Run and Validate again.
If Create & publish fails with "Meta rejected the Flow's content", nothing was published: click Validate, fix what Errors shows, and publish again. See Publishing.
You don't need the AI for the live parts. Ask it for a plain Flow with the screens you want, then let Avox make it live:
Ask for the screens
Use the prompt above, and add under "What to collect" which screen shows a list from your data,
for example: "screen 2: a Dropdown named slot whose choices come from my data". The AI may then
write "data-source": "${data.slots}"; that's fine.
Paste it and turn on Live data
Paste the JSON, open Live data, and turn on This Flow uses live data.
Connect tables
On each screen that needs data, click Connect a table: for example Show rows from your
Time slots table into slots when SLOT opens, and Book a slot or seat when it's submitted.
Add live parts
Click Add live parts. Avox adds data_api_version, the routing_model, the data each screen
declares (with examples from your rows), turns the buttons that need data into data_exchange,
and sends every answer along. Then Run, Validate and publish.
Last updated