How a screen works
A flow is an ordered set of screens — at most 10. Each screen has an ID, a title, and a single-column stack of components that render top to bottom. Screens don’t advance on their own. The Footer — the button pinned to the bottom of the screen — is what moves things along:- A Footer with a navigate action opens another screen in the same flow, optionally handing it values from this one.
- A Footer with a complete action ends the flow and submits everything to your bot. At least one screen in every flow must end this way.
Conditional rendering
If and Switch let one screen show different things to different people. Both render on the same screen surface — the branches aren’t separate screens, they’re alternative contents of the one screen. That has two consequences worth remembering:
- A field name used in one branch counts as a duplicate if it’s reused in another branch on that screen. See Every input on a screen needs its own name.
- A Footer inside a branch is a real Footer for that render path.
The Footer rule
Exactly one Footer per render path. Not one per screen — one per path a person can actually see.Text
TextHeading
TextHeading
A bold heading displayed at the top of a screen or section. Use it to label each screen clearly. Max 80 characters.
TextSubheading
TextSubheading
A smaller heading. Use it to break a longer screen into labelled sections. Max 80 characters.
TextBody
TextBody
Regular body text for instructions or descriptions. Set
markdown: true for bold, italics, lists, and links. Max 4096 characters.TextCaption
TextCaption
Small print — a disclaimer, a helper note, or a static label sitting above a value. Also supports
markdown: true. Max 4096 characters.RichText
RichText
Full markdown rendering, including tables. Accepted, but not recommended — it currently causes rendering errors in WhatsApp’s flow runtime, so Paige is told to use
TextBody with markdown: true instead. Reach for it only when you need something TextBody genuinely can’t do, such as a markdown table, and expect trouble.Inputs
Each of these registers a field name that appears in the submitted data.TextInput
TextInput
A single-line text field — names, email addresses, reference numbers. Needs a
name and a label of 20 characters or fewer. Set input-type to one of text, number, email, password, passcode, or phone to get the right keyboard and validation. For anything longer than a line, use TextArea.TextArea
TextArea
A multi-line text box for notes, descriptions, and free-form comments. Needs a
name and a label of 20 characters or fewer.Dropdown
Dropdown
A select menu with a list of options. Used for service selection, time slots, categories, and similar choices. Label max 20 characters; up to 200 options, or 100 if any option carries an image.
CheckboxGroup
CheckboxGroup
Pick several from a visible list. Max 20 options — for a longer list, split it across two screens.
ChipsSelector
ChipsSelector
Multi-select shown as tappable tags rather than a list — good for interests and preferences. Between 2 and 20 options, and
max-selected-items caps how many can be chosen.OptIn
OptIn
A consent tick box — marketing permission, terms acceptance. Label max 120 characters, and at most 5 per screen.
Dates
DatePicker
DatePicker
A native date selector. The chosen date comes back as a
YYYY-MM-DD string. Label max 40 characters. min-date, max-date, and unavailable-dates let you fence off dates that can’t be picked.CalendarPicker
CalendarPicker
A full calendar view.
mode: "single" picks one date; mode: "range" picks a start and an end, and the label becomes a pair. Use it for stays and multi-day bookings where seeing the month matters. Label max 40 characters.Media and links
Image
Image
A single image on the screen — a product shot, a map, a logo.
src is either an https URL or raw base64 with no data:image/...;base64, prefix. Max 3 per screen, and keep each under about 300 KB.ImageCarousel
ImageCarousel
Between 1 and 3 swipeable images in one block. Use it to show variants of the same thing without spending three separate screens.
EmbeddedLink
EmbeddedLink
A tappable line of text that acts like a link. Text max 25 characters, at most 2 per screen, and it needs an action saying what tapping it does.
PhotoPicker
PhotoPicker
Lets someone attach photos from their camera or gallery — proof of damage, a meter reading, a receipt. Needs a
name and a label. Only one per screen, and it can’t share a screen with a DocumentPicker.DocumentPicker
DocumentPicker
The same idea for files — a signed contract, a PDF quote.
allowed-mime-types restricts what can be attached. Needs a name and a label, one per screen, and no PhotoPicker alongside it.Structure and logic
Form
Form
A container that groups a screen’s inputs together with the Footer that submits them. It’s plumbing rather than something people see — Paige adds it where it’s needed.
If
If
Shows one set of components when a condition is true and another when it isn’t — for example, only asking for a company name if someone said they’re a business. The condition has to resolve to a true/false answer.
Switch
Switch
The same idea for more than two outcomes: one case per value, plus an optional
default. This is how a single screen replaces several near-identical ones, and how a screen sends different people to different next screens — each case carries its own Footer.