Flow JSON#

Here you will find all the components that make up a Flow JSON object.

class pywa.types.flows.FlowJSON#

Represents a WhatsApp Flow JSON.

Variables:
  • screens (Iterable[pywa.types.flows.Screen]) –

    The screens of the flow (Read more at developers.facebook.com).

  • version (str | float | Literal[<Version.FLOW_JSON: '5.1'>]) –

    The Flow JSON version. (Read more at developers.facebook.com).

  • data_api_version (str | float | Literal[<Version.FLOW_DATA_API: '3.0'>] | None) – The version to use during communication with the WhatsApp Flows Data Endpoint. Use utils.Version.FLOW_DATA_API to get the latest version

  • routing_model (dict[str, Iterable[str]] | None) –

    Defines the rules for the screen by limiting the possible state transition. (Read more at developers.facebook.com).

  • data_channel_uri (str | None) – The endpoint to use to communicate with your server (When using v3.0 or higher, this field need to be set via WhatsApp.update_flow_metadata()).

class pywa.types.flows.Screen#

Represents a screen (page) in a WhatsApp flow.

Example

>>> Screen(
...     id='START',
...     title='Welcome',
...     data=[ScreenData(key='welcome', example='Welcome to my store!')],
...     terminal=True,
...     layout=Layout(children=[Form(children=[...])]),
...     refresh_on_back=True
... )
Variables:
  • id (str) – Unique identifier of the screen for navigation purposes. SUCCESS is a reserved keyword and should not be used as a screen id.

  • title (str | None) – Screen level attribute that is rendered in the top navigation bar.

  • data (Iterable[pywa.types.flows.ScreenData] | dict[str, dict] | None) – Declaration of dynamic data that this screen should get from the previous screen or from the data endpoint. In the screen children and in Action .payload, you can use the .data_key or DataKey to reference this data.

  • terminal (bool | None) – 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 on the terminal screen.

  • refresh_on_back (bool | None) –

    Whether to trigger a data exchange request with the data endpoint when the user presses the back button while on this screen (Read more at developers.facebook.com).

  • layout (pywa.types.flows.Layout) –

    Associated screen UI Layout that is shown to the user (Read more at developers.facebook.com).

  • success (bool | None) – To indicate whether terminating on that screen results in a successful flow completion.

  • sensitive (Iterable[str] | None) – This array contains the names of the fields in the screen that contain sensitive data, and should be hidden in the response summary displayed to the user. (added in v5.1)

class pywa.types.flows.ScreenData#

Represents a screen data that a screen should get from the previous screen or from the data endpoint.

  • You can use the .data_key property or the DataKey to reference this data in the screen children or in the action payloads.

  • Read more at developers.facebook.com.

Example

>>> Screen(
...     id='START',
...     data=[
...         dynamic_welcome := ScreenData(key='welcome', example='Welcome to my store!')
...         is_email_required := ScreenData(key='is_email_required', example=False)
...     ],
...     layout=Layout(children=[Form(children=[
...         TextHeading(text=dynamic_welcome.data_key, ...),
...         TextInput(required=is_email_required.data_key, input_type=InputType.EMAIL, ...)
...     ])])
... )
Variables:
class pywa.types.flows.Layout#

Layout is the top level component that holds the other components.

Variables:
class pywa.types.flows.LayoutType#
The type of layout that is used to display the components.
  • Currently, only LayoutType.SINGLE_COLUMN is supported.

Variables:

SINGLE_COLUMN – A single column layout.

class pywa.types.flows.Form#

The form component is a container for other components that collects user input.

Variables:
class pywa.types.flows.TextHeading#

Represents text that is displayed as a heading.

Example

>>> TextHeading(text='Heading', visible=True)
Variables:
class pywa.types.flows.TextSubheading#

Represents text that is displayed as a subheading.

Example

>>> TextSubheading(text='Subheading', visible=True)
Variables:
class pywa.types.flows.TextBody#

Represents text that is displayed as a body.

Example

>>> TextBody(
...     text='Body',
...     font_weight=FontWeight.BOLD,
...     strikethrough=True,
...     visible=True
... )
Variables:
class pywa.types.flows.TextCaption#

Represents text that is displayed as a caption.

Example

>>> TextCaption(
...     text='Caption',
...     font_weight=FontWeight.ITALIC,
...     strikethrough=True,
... )
Variables:
class pywa.types.flows.RichText#

Represents text that is displayed as a rich text.

  • Read more at developers.facebook.com.

  • The goal of the component is to provide a rich formatting capabilities and introduce the way to render large texts (Terms of Condition, Policy Documents, User Agreement and etc) without facing limitations of basic text components (TextHeading, TextSubheading, TextBody and etc)

  • RichText component utilizes a select subset of the Markdown specification. It adheres strictly to standard Markdown syntax without introducing any custom modifications. Content created for the RichText component is fully compatible with standard Markdown documents.

  • Added in v5.1.

Example

>>> RichText(
...     text=[
...         "# Heading 1",
...         "## Heading 2",
...         "Let’s make a **bold** statement",
...         "Let's make this text *italic*",
...         "Let's make this text ~~Strikethrough~~",
...         "This text is ~~***really important***~~",
...         "This is a [pywa docs](https://pywa.readthedocs.io/)",
...         "This is a ordered list:",
...         "1. Item 1",
...         "2. Item 2",
...         "This is a unordered list:",
...         "- Item 1",
...         "- Item 2",
...         "![image](data:image/png;base64,<base64 content>)",
...         "| Tables        | Are           | Cool  |",
...         "| ------------- | ------------- | ----- |",
...         "| col 3 is      | right-aligned | $1600 |",
...         "| col 2 is      | centered      |   $12 |",
...     ],
... )
Variables:
class pywa.types.flows.FontWeight#

The text weight

Variables:
  • BOLD – Bold text

  • ITALIC – Italic text

  • BOLD_ITALIC – Bold and italic text

  • NORMAL – Normal text

class pywa.types.flows.TextInput#

Represents a text entry component that allows for a single line of text.

Example

>>> TextInput(
...     name='email',
...     label='Email',
...     input_type=InputType.EMAIL,
...     required=True,
...     min_chars=5,
...     max_chars=50,
...     helper_text='Enter your email address',
... )
Variables:
class pywa.types.flows.InputType#

The input type of the text entry component.

  • This is used by the WhatsApp client to determine the keyboard layout and validation rules.

Variables:
  • TEXT – A single line of text (for multi-line text use TextArea).

  • NUMBER – A number (keyboard layout is numeric, with a decimal separator).

  • EMAIL – An email address (keyboard layout is alphanumeric, with a special character for the @ symbol).

  • PASSWORD – A password (the input is masked).

  • PASSCODE – A passcode (keyboard layout is numeric, the input is masked).

  • PHONE – A phone number (keyboard layout is numeric, with a special character for the + symbol).

class pywa.types.flows.TextArea#

Represents a text entry component that allows for multiple lines of text.

Example

>>> TextArea(
...     name='description',
...     label='Description',
...     required=True,
...     max_length=100,
...     helper_text='Enter your description',
... )
Variables:
class pywa.types.flows.CheckboxGroup#

CheckboxGroup component allows users to pick multiple selections from a list of options.

Example

>>> CheckboxGroup(
...     name='options',
...     data_source=[
...         DataSource(id='1', title='Option 1'),
...         DataSource(id='2', title='Option 2'),
...         DataSource(id='3', title='Option 3'),
...     ],
...     label='Options',
...     min_selected_items=1,
...     max_selected_items=2,
...     required=True,
...     init_value=['1', '2']
... )
Variables:
class pywa.types.flows.RadioButtonsGroup#

RadioButtonsGroup component allows users to pick a single selection from a list of options.

Example

>>> RadioButtonsGroup(
...     name='options',
...     data_source=[
...         DataSource(id='1', title='Option 1'),
...         DataSource(id='2', title='Option 2'),
...         DataSource(id='3', title='Option 3'),
...     ],
...     label='Options',
...     required=True,
...     init_value='1'
... )
Variables:
class pywa.types.flows.Footer#

Footer component allows users to navigate to other screens or submit the flow.

Example

  • Exchange data with your server (@wa.on_flow_request(…))

>>> Footer(
...     label='Sign up',
...     on_click_action=Action(
...         name=FlowActionType.DATA_EXCHANGE,
...         payload={'email': '...', 'phone': '...'}
...     )
... )
  • Go to the next screen:

>>> Footer(
...     label='Next',
...     on_click_action=Action(
...         name=FlowActionType.NAVIGATE,
...         next=ActionNext(name='NEXT_SCREEN')
...     )
... )
  • Complete the flow when the user clicks the footer:

>>> Footer(
...     label='Submit',
...     on_click_action=Action(
...         name=FlowActionType.COMPLETE,
...         payload={'email': '...', 'phone': '...'}
...     )
... )
Variables:
class pywa.types.flows.OptIn#

OptIn component allows users to check a box to opt in for a specific purpose.

  • This component must be inside a Form (if FlowJSON version is below 4.0).

  • Max number of Opt-Ins Per Screen is 5.

  • Read more at developers.facebook.com.

Example

>>> OptIn(
...     name='opt_in',
...     label='I agree to the terms and conditions',
...     required=True,
...     init_value=True
... )
Variables:
class pywa.types.flows.Dropdown#

Dropdown component allows users to pick a single selection from a list of options.

Example

>>> Dropdown(
...     name='options',
...     data_source=[
...         DataSource(id='1', title='Option 1'),
...         DataSource(id='2', title='Option 2'),
...         DataSource(id='3', title='Option 3'),
...     ],
...     label='Options',
...     required=True,
...     init_value='1'
... )
Variables:

EmbeddedLink component allows users to navigate to another screen.

  • Max Number of Embedded Links Per Screen is 2.

  • Empty or Blank value is not accepted for the text field.

  • Read more at developers.facebook.com.

Example

>>> EmbeddedLink(
...     text='Sign up',
...     on_click_action=Action(
...         name=FlowActionType.NAVIGATE,
...         next=ActionNext(name='SIGNUP_SCREEN'),
...         payload={'data': 'value'}
...     )
... )
Variables:
class pywa.types.flows.DatePicker#

DatePicker component allows users to select a date

  • This component must be inside a Form (if FlowJSON version is below 4.0).

  • Starting from FlowJSON version 5.0, you can use date/datetime python objects or a formatted date string in the format β€œYYYY-MM-DD”, such as β€œ2024-10-21” or

  • Read more at developers.facebook.com.

Example

>>> DatePicker(
...     name='date',
...     label='Appointment Date',
...     min_date=datetime.date(2024, 7, 21),
...     max_date=datetime.date(2024, 10, 21),
...     unavailable_dates=[
...         datetime.date(2024, 7, 25),
...         datetime.date(2024, 7, 26),
...     ],
...     helper_text='Select a date',
...     required=True
... )
Variables:
class pywa.types.flows.Image#

Image component that displays an image.

  • Read more at developers.facebook.com.

  • Supported images formats are JPEG PNG

  • Recommended image size is up to 300kb

  • Max number of images per screen is 3

Example

>>> Image(
...     src='iVBORw0KGgoAAAANSUhEUgAAAlgAAAM...',
...     width=100,
...     height=100,
...     scale_type=ScaleType.CONTAIN,
...     aspect_ratio=1,
...     alt_text='Image of a cat'
... )
Variables:
class pywa.types.flows.ScaleType#

The scale type of the image.

Variables:
  • COVER – Image is clipped to fit the image container.

  • CONTAIN – Image is contained within the image container with the original aspect ratio.

class pywa.types.flows.PhotoPicker#

PhotoPicker component allows uploading media from camera or gallery

Example

>>> PhotoPicker(
...     name='photo',
...     label='Take a photo',
...     description='We need your photo for verification',
...     photo_source=PhotoSource.CAMERA,
...     max_file_size_kb=10_000,  # 10MB
...     min_uploaded_photos=1,
...     max_uploaded_photos=3,
)
Variables:
class pywa.types.flows.PhotoSource#

The source where the image can be selected from.

Variables:
  • CAMERA_GALLERY – User can select from gallery or take a photo

  • CAMERA – User can select only from gallery

  • GALLERY – User can only take a photo

class pywa.types.flows.DocumentPicker#

DocumentPicker component allows uploading files from the device

  • Read more at developers.facebook.com.

  • Added in v4.0

  • Only 1 DocumentPicker is allowed per screen

  • Using both PhotoPicker and DocumentPicker components on a single screen is not allowed.

  • Note: some old Android and iOS OS versions don’t understand all mime types above. As a result, a user might be able to select a file with a different mime type to the ones specified.

Example

>>> DocumentPicker(
...     name='document',
...     label='Upload your Driving License',
...     description='We need your document for verification',
...     max_file_size_kb=5_000,  # 5MB
...     min_uploaded_documents=1,
...     max_uploaded_documents=1,
...     allowed_mime_types=['application/pdf', 'image/jpeg', 'image/png'],
)
Variables:
class pywa.types.flows.If#

If component allows users to add components based on a condition.

  • Read more at developers.facebook.com.

  • It is allowed to nest up to 3 If components.

  • Should have at least one dynamic value (e.g. screen_data.data_key / form_comp.form_ref) in the condition.

  • Should always be resolved into a boolean (i.e. no strings or number values).

  • Can be used with literals but should not only contain literals.

  • Footer can be added within If only in the first level, not inside a nested If.

  • If there is a Footer within If, it should exist in both branches (i.e. then and else). This means that else becomes mandatory.

  • If there is a Footer within If it cannot exist a footer outside, because the max count of Footer is 1 per screen.

Example

>>> age = ScreenData(key="age", example=20)
>>> opt_in = OptIn(name="opt_in", ...)
>>> If(
...     condition=f"{age.data_key} > 21 && {opt_in.form_ref}",
...     then=[
...         TextHeading(text="Welcome to the club!"),
...         TextInput(
...             name='email',
...             label='Email',
...         ),
...     ],
...     else_=[
...         TextHeading(text="You are not eligible!"),
...     ]
... )
Variables:
class pywa.types.flows.Switch#

Switch component allows users to add components based on a value of a data key / form ref.

Example

>>> age = TextInput(name='age', label='Age')
>>> switch = Switch(
...     value=age.form_ref,
...     cases={
...         '10': [TextHeading(text='Under 18')],
...         ...
...         '20': [TextInput(name='email', label='Email')],
...     }
Variables:
class pywa.types.flows.DataSource#

The data source of a component.

Example

>>> option_1 = DataSource(id='1', title='Option 1')
>>> option_2 = DataSource(id='2', title='Option 2')
>>> checkbox_group = CheckboxGroup(data_source=[option_1, option_2], ...)
Variables:
  • id (str) – The ID of the data source.

  • title (str) – The title of the data source. Limited to 30 characters.

  • description (str | None) – The description of the data source. Limited to 300 characters.

  • metadata (str | None) – The metadata of the data source. Limited to 20 characters.

  • enabled (bool | None) – Whether the data source is enabled or not. Default to True.

  • image (str | None) – The base64 encoded image of the data source. Limited to 1MB (added in v5.0).

  • alt_text (str | None) – The alt text of the image. (added in v5.0).

  • color (str | None) – 6-digit hex color code. (added in v5.0).

class pywa.types.flows.Action#

Action component allows users to trigger asynchronous actions that are handled by a client through interactive UI elements.

Example

>>> complete_action = Action(
...     name=FlowActionType.COMPLETE,
...     payload={'data': 'value'}
... )
>>> data_exchange_action = Action(
...     name=FlowActionType.DATA_EXCHANGE,
...     payload={'data': 'value'}
... )
>>> navigate_action = Action(
...     name=FlowActionType.NAVIGATE,
...     next=ActionNext(name='NEXT_SCREEN'),
...     payload={'data': 'value'}
... )
Variables:
class pywa.types.flows.FlowActionType#

Flow JSON provides a generic way to trigger asynchronous actions handled by a client through interactive UI elements.

Variables:
  • COMPLETE –

    Triggers the termination of the Flow with the provided payload (Read more at developers.facebook.com).

  • DATA_EXCHANGE –

    Sending Data to WhatsApp Flows Data Endpoint (Read more at developers.facebook.com).

  • NAVIGATE –

    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. (Read more at developers.facebook.com).

class pywa.types.flows.ActionNext#

The next action

Variables:
class pywa.types.flows.ActionNextType#

The type of the next action

Variables:
  • SCREEN – Navigate to the next screen

  • PLUGIN – Trigger a plugin

class pywa.types.flows.DataKey#

Represents a data key (converts to ${data.<key>} | ${screen.<screen>.data.<key>}).

Example

  • Hint: use the .data_key property of ScreenData to get the data key of a screen data.

  • Hint: use the .data_key_of(screen) method of ScreenData to get the data key from another screen.

>>> FlowJSON(
...     screens=[
...         other := Screen(id='OTHER', data=[is_visible := ScreenData(key='is_visible', example=True)]),
...         Screen(
...             id='START',
...             data=[welcome := ScreenData(key='welcome', example='Welcome to my store!')],
...             layout=Layout(children=[
...                 TextHeading(
...                     text=welcome.data_key, # data in the same screen
...                     visible=is_visible.data_key_of(other) # data from other screen
...                 )
...             ])
...         )
...     ]
... )
  • Or if you want to use DataKey directly:

>>> FlowJSON(
...     screens=[
...         Screen(id='OTHER', data=[ScreenData(key='welcome', example='Welcome to my store!')])
...         Screen(id='START', layout=Layout(children=[TextHeading(text=DataKey(key='welcome', screen='OTHER'))]))
...     ]
... )
Parameters:
  • key – The key to get from the Screen .data attribute.

  • screen – The screen that contains the data (needed if the data is from another screen). Added in v4.0.

class pywa.types.flows.FormRef#

Represents a form reference variable (converts to ${form.<child>} | ${screen.<screen>.form.<child>}).

Example

  • Hint: use the .form_ref property of each component to get the form reference variable of that component.

  • Hint: use the .form_ref_of(screen) method of each component to get the form reference variable of that component with the given screen name.

>>> FlowJSON(
...     screens=[
...         other := Screen(
...             id='OTHER',
...             layout=Layout(children=[Form(children=[email := TextInput(name='email', ...), ...])])
...         ),
...         Screen(
...             id='START',
...             layout=Layout(children=[
...                 phone := TextInput(name='phone', ...),
...                 TextBody(text=phone.form_ref, ...),  # form reference from the same screen
...                 TextCaption(text=email.form_ref_of(other), ...)  # form reference from another screen
...             ])
...         )
...     ]
... )
  • Or if you want to use FormRef directly:

>>> FlowJSON(
...     screens=[
...         Screen(
...             id='OTHER',
...             layout=Layout(children=[Form(children=[email := TextInput(name='email', ...), ...])])
...         ),
...         Screen(
...             id='START',
...             layout=Layout(children=[
...                 phone := TextInput(name='phone', ...),
...                 TextBody(text=FormRef('phone')),
...                 TextCaption(text=FormRef('email', screen='OTHER'))
...             ])
...         )
...     ]
... )
Parameters:
  • child_name – The name of the Form child to get the value from.

  • screen – The name of the screen that contains the form. Added in v4.0.