Leverage Flow JSON to build your user experience.
To visualize the complete user experience, use the Builder. The Builder emulates the entire Flow experience and can be updated on the fly. To navigate to the Builder:
See this list of templates you can build with Flow JSON.
Flow JSON enables businesses to create workflows in WhatsApp by accessing the features of WhatsApp Flows using a custom JSON object developed by Meta.
These workflows are initiated, run, and managed entirely inside WhatsApp. It can include multiple screens, data flows, and response messages.
Flow JSON consists of the following sections:
Flow JSON Section | Description |
---|---|
Screen Data Model | Commands to define static types that power the screen. |
Screens | Used to compose layouts using standard UI library components. |
Components | Individual building blocks that make up a screen (text fields, buttons, and so on). |
Routing Model | Defines the rules for the screen by limiting the possible state transition. For example, developers can define that from Screen 1 you can only transition to Screen 2 and 3, but not Screens 4 and 5. These rules are used during server / client side payload validations. |
Actions | Special type of syntax to invoke pre-defined logic on the client. All actions are either "navigate" or "complete." |
Flow JSON to defines the following:
Flow JSON has several required and optional properties that are used in the process of compilation and validation of the Flow.
version
- represents the version of Flow JSON to use during the compilation. Please refer to the list of versions for more details.
screens
- represents an array or screen as part of the user experience. This is like a set of different pages on your website.
data_api_version
- represents the version to use during communication with the WhatsApp Flows Data Endpoint. Currently, it is 3.0.
If flow uses the data-channel capability, the validation system will ask to provide this property. data_api_version: 100
is now out of support. Please follow these instructions to upgrade to data_api_version: "3.0".
{ "version": "3.1", "data_api_version": "3.0", "routing_model": {"MY_FIRST_SCREEN": ["MY_SECOND_SCREEN"] }, "screens": [...] }
Screens are the main unit of a Flow. Each screen represents a single node in the state machine you define. These properties then make up the Flows screen property model:
"screen" : { "id": string, "terminal": ?boolean, "success": ?boolean, "title": ?string, "refresh_on_back": ?boolean, "data": ?object, "layout": object }
id
- unique identifier of the screen which works as a page url. SUCCESS is a reserved keyword and should not be used as a screen id.
layout
- associated screen UI Layout that is shown to the user. Layout can be predefined or it can represent a container with fully customizable content built using WhatsApp Flows Library.
terminal
(optional) - the business flow is the end state machine. It means that each Flow should have a terminal state where we terminate the experience and have the Flow completed. Multiple screens can be marked as terminal. It's mandatory to have a Footer component on the terminal screen.
data
(optional) - declaration of dynamic data that fills the components field in the Flow JSON. It uses JSON Schema to define the structure and type of the properties. Below you can find the simple example.
{ "data": { "first_name": { "type": "string", "__example__": "John" } } }
title
(optional) - screen level attribute that is rendered in the top navigation bar.success
- (optional, only applicable on terminal screens) - Defaults to true
. A Flow can have multiple terminal screens with different business outcomes. This property marks whether terminating on a terminal screen should be considered a successful business outcome.refresh_on_back
(optional, and only applicable for Flows with a Data Endpoint) - Defaults to false
. This property defines whether to trigger a data exchange request with the WhatsApp Flows Data Endpoint when using the back button while on this screen. The property is useful when you need to reevaluate the screen data when returning to the previous screen (example below).refresh_on_back
Given a simple Flow example with the following screens:
Appointment Type
.Appointment Time
.Confirms
an appoinment.The user may navigate back from the confirmation page to re-select an appointment time. By using the refresh_on_back
property in the Confirmation
screen's definition, you can control whether to refresh the list of available times, or to reload the previously shown list.
If refresh_on_back=false
, when the user goes back to the Appointment Time
screen the Flow will not request the Flow Data Endpoint and the screen will be loaded with the previously provided data, and the user's prior input. This is the preferred behavior in most cases, given it avoids a roundtrip to the Flow Data Endpoint and provides a snappier experience for the user.
If, however, you need to revalidate or update the data for the screen, set refresh_on_back=true
on the screen from which the back action is triggered (the Confirmation
screen in this example). Once the user navigates back to the Appointment Time
screen, the Flow will send a request to the Flow Data Endpoint and display the screen with the data from the response.
refresh_on_back=true
The complete payload structure is defined here - in this case the action
field will be BACK
, and the screen
will be set to the name of the Confirmation
screen.
Layout represents screen UI Content. It can be predefined by the WhatsApp Flows team, or the business can use empty containers and build custom experience using the WhatsApp Flows Library.
Layout has the following properties:
type
- the layout identifier that’s used in the template. In the current version of Flow JSON, there is only one layout available - "SingleColumnLayout"
which represents a vertical flexbox container.
children
- represents an array of components from the WhatsApp Flows Library.
Routing model configuration is needed only when you use an Endpoint to power your flow.
You can define the routing model, which is a directed graph, as each screen can go to multiple other screens. There can be up to a maximum of 10 "branches", or connections, within the routing model.
Consider the following flow:
The following routing model can be built:
Item Catalog => [Item Details Page]
Item Details Page => [Item Catalog, Checkout]
Checkout => []
If you don't use an Endpoint, you don't need to define a routing model, it will be generated automatically.
However, if you want to use a server to power your Flow, you'll have to provide a routing_model
in your Flow JSON.
Routes are defined per screen via the routing_model
property. It is a map of screen ids to an array of other screen ids it can transition to. The terminal screen is defined with terminal=true
.
Route cannot be the current screen, but the route can be "refreshed" for validation purposes.
If there is an edge between two screens, then the user can go back and forth between them using the BACK button.
Only forward routes should be specified in the routing model. For example, if you have specified an edge from Screen_A to Screen_B then you shouldn't specify another edge from Screen_B to Screen_A.
Routes can be empty for a screen if there is no forward route from it.
There should be an entry screen in the routing model. A screen is eligible to be an entry screen if has no inbound edge.
For example, Item Catalog is the entry screen in the following routing model : Item Catalog => [Checkout]
.
If your Flow is not using a Data Endpoint then an entry screen will be the one which is not set as the "next" screen in any of the "navigate" actions defined in the Flow.
All routes must end at the terminal screen.
In the example below, there is a simple 3-screen Flow that uses an Endpoint. It is expected that the server will return the next screen with a response to data_exchange
action. The server has to comply with defined routing_model
in the Flow JSON:
{ "version": "3.1", "data_api_version": "3.0", "routing_model": { "MY_FIRST_SCREEN": [ "MY_SECOND_SCREEN" ], "MY_SECOND_SCREEN": [ "MY_THIRD_SCREEN" ] }, "screens": [ { "id": "MY_FIRST_SCREEN", "title": "First Screen", "layout": { "type": "SingleColumnLayout", "children": [ { "type": "Footer", "label": "Continue", "on-click-action": { "name": "data_exchange", "payload": {} } } ] } }, { "id": "MY_SECOND_SCREEN", "title": "Second Screen", "data": {}, "layout": { "type": "SingleColumnLayout", "children": [ { "type": "Footer", "label": "Continue", "on-click-action": { "name": "data_exchange", "payload": {} } } ] } }, { "id": "MY_THIRD_SCREEN", "title": "Third Screen", "terminal": true, "success": true, "data": {}, "layout": { "type": "SingleColumnLayout", "children": [ { "type": "Footer", "label": "Continue", "on-click-action": { "name": "data_exchange", "payload": {} } } ] } } ] }
Properties can be static
or dynamic
. In Flow JSON the property is static if it is not a type binded to a data
or form
object.
Static properties are simple. You set static properties once and they never change.
Here is an example (see text
and label
properties of TextHeading
and Footer
components). Static properties is the simplest way to start building your Flow. You can always replace them later with dynamic content.
Dynamic properties enables you to set the content dynamically based on the server / screen data via the dynamic data reference mechanism, like so: "${data.username}"
. If you attempt to use the dynamic and static variant of the property together, you will get a compilation error. The dynamic data reference mechanism works with the following data types:
You can dynamically reference these data types in all the components of Flow JSON. There are two types of dynamic properties:
"${form.field_name}"
(data entered by the user in input fields). This is used to provide access to information that the user entered on the screen. "${data.field_name}"
(data provided for the screen). This is used to provide access to information that is passed down by the server or the navigate
action from the previous screen.If a screen expects dynamic data, declare it inside the data
property. Data declaration uses the standart JSON Schema. A simple Flow example would replace text
with dynamic data coming from the message payload:
A few things have been added:
Inside MY_FIRST_SCREEN
we declared a data field
Inside the data field we declared hello_world_text
. This is the data that we expect to receive for screen.
hello_world_text
follows the JSON Schema specification to declare the expected type, in this example it is a string.__example__
field serves as mock data for the template, which is useful while you’re developing your template without WhatsApp Flows Data Endpoint integration. This field is mandatory.In TextHeading
we’ve referenced the data via dynamic data reference syntax. ${data} represents an object that came from the WhatsApp Flows Data Endpoint or navigate
actions in case of Flow without endpoint. You can treat it as a screen state that was set after the response is received.
Property of the state can be accessed using the following pattern - "${data.property_name}"
If you want to power the screen by endpoint data, the example above will slightly change.
We've added data_api_version
, routing_model
and data_channel_uri
to indicate that the flow is connected to server.
We've added data_api_version
and routing_model
to indicate that the flow is connected to server. data_channel_uri
should also be added if the Flow JSON version is less than 3.0
.
Flow expects to receive a payload from flow data server containing hello_world_text
field.
The use of the Form component is optional starting from Flow JSON versions 4.0
[Early Release]. This means that you can submit user-entered data without the need to wrap your components inside a Form component any more.
To get and submit the data entered from users, Flow JSON uses a straightforward concept from HTML - Forms.
HTML Form example:
<form> <label for="first_name">First name</label><br> <input type="text" id="first_name" name="first_name"><br> <label for="last_name">Last name</label><br> <input type="text" id="last_name" name="last_name"> <input type="radio" id="html" name="fav_language" value="HTML"> <label for="html">HTML</label><br> <input type="radio" id="css" name="fav_language" value="CSS"> <label for="css">CSS</label><br> <input type="radio" id="javascript" name="fav_language" value="JavaScript"> <label for="javascript">JavaScript</label> </form>
This form can also be implemented in Flow JSON as follows:
Alternative way to implement form starting from Flow JSON versions 4.0
[Early Release] as follows:
Using exampple above, we can reference form properties using a "${form.field_name}"
binding. This type of binding uses name
property of the interactive inputs to reference its value. You can use form values to submut the data to a flow data server or pass it another screen.
{ "type": "Footer", "label": "Submit data", "on-click-action": { "name": "navigate", "next": { "type": "screen", "name": "NEXT_SCREEN" }, "payload": { "name": "${form.first_name}", "lang": "${form.favourite_language}" } } }
{ "type": "Footer", "label": "Submit data", "on-click-action": { "name": "data_exchange", "payload": { "name": "${form.first_name}", "lang": "${form.favourite_language}" } } }
In order to build Forms in Flow JSON you need to use Form components then provide the name
and children
properties
Children properties must be an array of Form components
Each Form component has its own property model, however the name
property is required in all of them
Interactive components can not be used outside forms.
Component | Can Be Used Outside Forms? (Before Flow JSON 4.0) | Can Be Used Outside Forms? (Flow JSON 4.0+) |
---|---|---|
Text (TextHeading, TextSubheading, TextCaption, TextBody) | ✅ | ✅ |
TextInput | ❌ | ✅ |
TextArea | ❌ | ✅ |
CheckboxGroup | ❌ | ✅ |
RadioButtonsGroup | ❌ | ✅ |
Footer | ✅ | ✅ |
OptIn | ❌ | ✅ |
Dropdown | ❌ | ✅ |
EmbeddedLink | ✅ | ✅ |
DatePicker | ❌ | ✅ |
Initial values of inputs can be initiased using init-values
property. error-messages
property allows you to set custom error for input. This is useful when you use Flow Data Endpoint to receive user data and you want to indicate that certain fields are incorrect.
Attribute | Description |
---|---|
init-values | <key, value> object where key - Field Name in Component value - Field Initial Value type - String, Array< String > or Dynamic |
| <key, value> object where key - Field Name in Component value - Error Message type - String or Dynamic |
You set init-values
by specifying the field name in the respective component, then mapping it to your desired value.
The data type for init-values
must match that of the component as outlined below.
Component | init-values data type
|
---|---|
CheckboxGroup | Array of Strings |
RadioButtonsGroup | String |
Text Entry | String |
Dropdown | String |
For example, if you have the field first_name
in one TextInput
component, the field second_name
in another TextInput
component you would set the init-values
like so:
Starting from Flow JSON versions 4.0
[Early Release], the utilization of the Form component has become optional. In the event that you opt not to use the Form component, you can still initialize the initial values of inputs by employing the init-value
property, and set custom errors for each input with error-message
property. Here is an example showcasing how to initialize values without utilizing the Form component:
Supported starting with Flow JSON version 4.0
Starting from Flow JSON Version 4.0
, you can use Global Dynamic Referencing
feature. It has the following syntax:
${screen.<screen_name>.(form | data).<field-name>}
screen
- global variable that gives access to screen storagescreen_name
- name of the screen to refer(form | data)
- type of storage you want to reference - Form / Dynamic data field-name
- name of the field you want to referencedynamic
dataBefore Flow JSON Version 4.0
, to transfer data from one screen to another you would need to use navigate
action. For instance to transfer the data from SCREEN_ONE
to SCREEN_TWO
, you would write the
following:
"on-click-action": { "name": "navigate", "next": { "type": "screen", "name": "SCREEN_TWO" }, "payload": { "field1": "${data.field_one}", "field2": "${form.field_two}" } }
In Flow JSON V4.0 you don't need to transfer the data via navigate
since all data now is globally accessable, so instead you can keep payload
as empty {}
"on-click-action": { "name": "navigate", "next": { "type": "screen", "name": "SCREEN_TWO" }, "payload": {} }
And on SCREEN_TWO
you can reference it as:
{ "type": "TextBody", "text": "${screen.SCREEN_ONE.data.field1}" }
data
declaration for global fieldsWhen you use global fields on the screen, you don't need to specify them in the data
model. Global fields utilise data-model of the parent screens.
See example below, we use ${screen.SCREEN_ONE.form.field1}
and ${screen.SCREEN_ONE.data.field2}
on SCREEN_TWO
, since the data comes from SCREEN_ONE
, we keep
data
model as empty on SCREEN_TWO
When you use global fields on the screen, you can also reference "future" screens. The only caveat is that you need to handle empty values. This can be done with Conditional Rendering
components.
See example below:
SELECT_SERVICES
screen references the data from SELECT_INSURANCE
SELECT_INSURANCE
screen is empty - we display You haven't selected any insurance type
Switch
statementFlow JSON provides a generic way to trigger asynchronous actions handled by a client through interactive UI elements. The following actions are supported:
Flow JSON Reference | Description | Payload Type |
---|---|---|
| Sending Data to WhatsApp Flows Data Endpoint | Customizable JSON payload on data exchanges { [key:string]: any } |
| Triggers the next screen with the payload as its input. The CTA button will be disabled until the payload with data required for the next screen is supplied. | Static JSON payload |
| Triggers the termination of the Flow with the provided payload. | Static JSON payload |
navigate
actionThis action is a primary way to navigate between the screens of the flow. The data that's passed as payload
of this action will be available on the next screen through dynamic data referencing - ${data.field_name}
. You shouldn't use it on the Footer of a terminal screen because that will prevent the flow from terminating.
Use this action when you need to transition to another screen.
{ "type": "Footer", "label": "Continue", "on-click-action": { "name": "navigate", "next": { "type": "screen", "name": "NEXT_SCREEN" }, "payload": { "name": "${form.first_name}", "lang": "${form.favourite_language}" } } }
complete
actionTerminates the flow and sends the response message to the chat thread. The business will receive the termination message bubble on the webhook, together with the flow_token and all of the other parameters from the payload. More information can be found here.
Use this action on terminal
screen as a last interaction of the user. Once triggered, the flow will be terminated and entered data will be submitted via webhook.
{ "type": "Footer", "label": "Submit data", "on-click-action": { "name": "complete", "payload": { "discount_code": "${data.discount_code}", "items": "${form.selected_items}" } } }
navigate
and complete
actionsdata_exchange
actionSends data to WhatsApp Flows Data Endpoint.
Use can only use this action if your Flow is powered by a Data Endpoint. Use this action when you need to submit data to your server before transitioning to the next screen or terminating the flow. Your server could then decide on the next step and provide the input for it.
{ "type": "Footer", "label": "Submit data", "on-click-action": { "name": "data_exchange", "payload": { "discount_code": "${data.discount_code}", "items": "${form.selected_items}" } } }
A comprehensive list of components with code examples is available here.
The Flow JSON code of your flow is validated against a set of validation rules. The following table outlines the different validation errors you might see, and what you can do to fix the problem. Please refer to the "Error Example" column for an example of this error with the placeholders replaced by actual data.
Error | Error Example | Solution |
---|---|---|
Flow JSON version is not specified. | You need to add the version property. | |
Invalid Flow JSON version. | You need to specify one the supported Flow JSON versions against the version property. | |
The property {property} cannot be specified at {data_pointer}. | The property "text-align-invalid" cannot be specified at "$root/screens/0/layout/children/0". | You need to remove the text-align-invalid property from the path $root/screens/0/layout/children/0. |
The required property {property} is missing at {data_pointer}. | The required property "name" is missing at "$root/screens/0/layout/children/0/children/0". | You need to add the property name at path $root/screens/0/layout/children/0/children/0. |
The property {data_pointer} should have atleast 1 character. | The property "$root/screens/0/layout/children/0/children/0/name" should have atleast 1 character. | You need to provide a non-empty value for property name at path $root/screens/0/layout/children/0/children/0. |
Expected the property {data_pointer} to be of type {expected_data_type}, but found type {actual_data_type}. | Expected the property "$root/screens/0/layout/children/0/children/0/name" to be of type string, but found type number. | You need to change the value of the name property at path $root/screens/0/layout/children/0/children/0. The new value should be of the type string. |
The property {data_pointer} should have at least 1 items. | The property "$root/screens/0/layout/children/0/children/0/data-source" should have at least 1 items. | You need to add at least one item in the array property data-source at the path $root/screens/0/layout/children/0/children/0. |
{data_pointer} should have dynamic data format as it's type matches with the dynamic data type: string. | "$root/screens/0/layout/children/0/children/0/data-source" should have dynamic data format as it's type matches with the dynamic data type: string. | You need to define a dynamic data reference in the value of the property data-source at the path $root/screens/0/layout/children/0/children/0. Read more about the dynamic data reference here |
{data_pointer} should only consist of alphabets and underscore. | "$root/screens/0/id" should only consist of alphabets and underscore. | You need to remove all characters that are not letters or underscores from the property id at path $root/screens/0. |
The required parent property Form is missing for {component_name} at {data_pointer} | The required parent property Form is missing for "TextInput" at "$root/screens/0/layout/children/0" | You need to wrap the TextInput component at path $root/screens/0/layout/children/0 in a Form component. |
Invalid data model schema found at {data_pointer}. 'type' keyword contains unknown value: {unknown_data_type}. | Invalid data model schema found at "$root/screens/0/data/label". 'type' keyword contains unknown value: strings. | You need to provide a valid JSON data type for the value of the type property at $root/screens/0/data/label path. |
example metadata is allowed only as a top level property of data model. Invalid entry: {data_pointer}. | example metadata is allowed only as a top level property of data model. Invalid entry: "$root/screens/0/data/intro_data/properties/fields/items/properties/example" | You need to remove the example property from the path $root/screens/0/data/intro_data/properties/fields/items/properties. |
Invalid data model schema found at {data_pointer}. Expected the property "items" to be of type boolean or object. | Invalid data model schema found at "$root/screens/0/data/products/items". Expected the property "items" to be of type boolean or object. | You need to change the type of the items in the schema defined at "$root/screens/0/data/products/items". The new type should be either "boolean" or "object". |
The property "$root/data_channel_uri" should be in uri format. | You need to change the value of the data_channel_uri property so that it is in the correct format for a URI. A URI typically starts with "http" or "https" and includes other information such as the domain name and path. | |
Invalid value found for property "type" at {data_pointer}. | Invalid value found for property "type" at "$root/screens/0/layout/children/0". | You need to provide a valid component in the value of the type property at $root/screens/0/layout/children/0. Please refer this for the list of supported components. |
The properties ["left-caption","center-caption"] at {data_pointer} must present exclusively. | The properties ["left-caption","center-caption"] at "$root/screens/0/layout/children/0" must present exclusively | You need to either remove the property left-caption or center-caption from the path $root/screens/0/layout/children/0. |
Invalid value found at {data_pointer}. Value can be one of: {allowed_values}. | Invalid value found at $root/screens/0/layout/children/0/children/0/on-click-action/name. Value can be one of: ["data_exchange","navigate"]. | You need to change the value of the property name at path $root/screens/0/layout/children/0/children/0/on-click-action/. The new value must be either data_exchange or navigate. |
Invalid value found for property {data_pointer}. Expected: {allowed_value}. | Invalid value found for property "$root/data_api_version". Expected: "3.0". | You need to change the value of the property data_api_version to 3.0. |
{data_pointer} should not be an empty or blank string. | "$root/screens/0/layout/children/0/children/0/name" should not be an empty or blank string. | You need to change the value of the name property at path $root/screens/0/layout/children/0/children/0. The value must be a string that is not empty or blank. |
Invalid data model schema found at {data_pointer}. Missing the schema for array items. | Invalid data model schema found at "$root/screens/0/data/products". Missing the schema for array items. | You need to provide more information about the items in the products array at $root/screens/0/data. Specifically, you need to provide a schema that describes the structure of each item in the array. |
Invalid data model schema found at {data_pointer}. Missing the definition of property "type". | Invalid data model schema found at "$root/screens/0/data/products". Missing the definition of property "type". | The data type of the property products needs to be specified by defining a type property at the path $root/screens/0/data/products. |
The property "data_channel_uri" is no longer supported in Flow JSON as of version "3.0". Please configure your endpoint URI using Flows API or Builder. For more information, refer to our documentation at "https://developers.facebook.com/docs/whatsapp/flows" . | You need to remove data_channel_uri property. | |
The property "refresh_on_back" can only be set to true if the "data_api_version" property is set. Invalid value found at {data_pointer}. | The property "refresh_on_back" can only be set to true if the "data_api_version" property is set. Invalid value found at "$root/screens/1/refresh_on_back". | You need to either set the data_api_version property or change the value of the property efresh_on_back at path "$root/screens/1 to false. |
You've reached the maximum number of screens in the flow {max_screens}. | You need to remove any screens that exceed the maximum number allowed as specified in the {max_screens} placeholder. | |
You have not provided a terminal screen. | You need to have atleast one screen with terminal property set to true. | |
Found screens with duplicate id. | You need to ensure that the id property of each screen in your Flow JSON document is unique. | |
'SUCCESS' is a reserved keyword. Please use another id for your screen. | You need to change the id property, for the screen whose current id is "SUCCESS", to a different value. | |
Duplicate names found for form components in screen: {screen_id}. | Duplicate names found for form components in screen: ORDER. | You need to make sure that the name property of each form component in screen ORDER is unique. |
Missing dynamic data {dynamic_data_reference} in the data model for screen: {screen_id}, {component} property: {component_property}. | Missing dynamic data "${data.intro_text}" in the data model for screen: ORDER, TextBody property: text. | You need to provide definition for the dynamic data reference intro_text, in the data model of the ORDER screen. |
{dynamic_data_reference} for screen: {screen_id}, {component} property: {component_property} is invalid as items is defined in an array schema in the data model. | ${data.products.items.properties.title} for screen: ROOT, TextSubheading property: text is invalid as items is defined in an array schema in the data model. | The Flow JSON does not allow referencing the properties of an array object using a dynamic data reference. You need to change the dynamic data reference in the text property of the TextSubheading component in the ROOT screen. |
Data model schema is invalid for dynamic data {dynamic_data_reference} defined for property: {component_property} of component: {component} in screen: {screen_id}, expected the type to be {expected_data_type}. | Data model schema is invalid for dynamic data "${data.intro_text}" defined for property: text of component: TextSubheading in screen: ROOT, expected the type to be string. | You need to change the type of dynamic data reference intro_text to be of type string. Make this change in the data model of the ROOT screen. |
Data model schema is invalid for dynamic data {dynamic_data_reference} defined for property: {component_property} of component: {component} in screen: {screen_id}, missing schema for {object_property}. | Data model schema is invalid for dynamic data "${data.products}" defined for property: data-source of component: Dropdown in screen: ROOT, missing schema for title. | You need to define the schema of the property title in the schema of the dynamic data reference products. Make this change in the data model of the ROOT screen. |
Dynamic data {dynamic_data_reference} defined for screen: {screen_id}, {component} property: {component_property} is invalid as its schema is missing in the data model. | Dynamic data "${data.promo_product.id}" defined for screen: ROOT, TextHeading property: text is invalid as its schema is missing in the data model. | You need to define the schema of the dynamic data reference promo_product.id. Make this change in the data model of the ROOT screen. |
Unknown screen id found at {data_pointer}. | Unknown screen id found at "$root/screens/1/layout/children/0/on-click-action/next/name". | You need to change the value at path $root/screens/1/layout/children/0/on-click-action/next/name with a screen id that exists in your flow. |
Same screen navigation is not allowed. Loop detected at {data_pointer}. | Same screen navigation is not allowed. Loop detected at "$root/screens/1/layout/children/0/on-click-action/next/name". | You need to provide a different screen id at path $root/screens/1/layout/children/0/on-click-action/next/name. |
You can only have 2 Embedded Links per screen. | You need to ensure that each screen has maximum of 2 EmbeddedLink components. | |
Screen exceeds the limit of 50 components. | You need to ensure that each screen has maximum of 50 components. | |
"min-selected-items" cannot be greater than "max-selected-items" for CheckboxGroup component | You need to ensure that the value for **CheckboxGroup"" property "min-selected-items" is less than or equal to the value of the "max-selected-items" property. |
Flow JSON content string is limited and cannot exceed 10 MB.