| name | whatsapp-flows |
| description | Authoring WhatsApp Business Flows with validation, component guidance, and server integration patterns. Use when building conversational experiences, collecting user data, implementing conditional logic, or integrating with backend endpoints. |
WhatsApp Flows Skill
Build conversational WhatsApp experiences with dynamic forms, conditional logic, and server integration.
Quick Start
What are WhatsApp Flows?
WhatsApp Flows are structured conversations that collect user input through a series of screens. Use them to:
- Collect information (forms, surveys)
- Implement conditional logic (eligibility checks, branching)
- Display dynamic data (products, prices, inventory)
- Validate user input server-side
- Complete multi-step processes
5 Key Concepts
- Screens - Individual steps in your flow. Each has a unique ID and layout.
- Components - Building blocks (TextInput, Dropdown, Footer, If, etc.)
- Form Data - User input via
${form.field_name}binding - Server Data - Dynamic data via
${data.field_name}binding - Actions - What happens: navigate, data_exchange, complete, update_data, open_url
Minimal Example
{
"version": "7.1",
"screens": [
{
"id": "GREETING",
"title": "Greeting",
"layout": {
"type": "SingleColumnLayout",
"children": [
{
"type": "TextHeading",
"text": "Welcome!"
},
{
"type": "TextBody",
"text": "Please tell us your name to proceed.",
"markdown": true
},
{
"type": "TextInput",
"name": "name",
"label": "What's your name?",
"required": true
},
{
"type": "Footer",
"label": "Continue",
"on-click-action": {
"name": "navigate",
"next": {
"type": "screen",
"name": "CONFIRMATION"
}
}
}
]
}
},
{
"id": "CONFIRMATION",
"title": "Confirmation",
"terminal": true,
"success": true,
"layout": {
"type": "SingleColumnLayout",
"children": [
{
"type": "TextHeading",
"text": "Hello ${screen.GREETING.form.name}!"
},
{
"type": "Footer",
"label": "Done",
"on-click-action": {
"name": "complete",
"payload": {
"name": "${screen.GREETING.form.name}"
}
}
}
]
}
}
]
}
Business 3.0 API Requirements:
- Every screen MUST have a
titleproperty - Action properties use
name(notaction) with nested structure
When to add data_api_version:
- Only include
"data_api_version": "3.0"if your flow needs server integration (data validation, dynamic data, form submission to backend) - If your flow is client-side only with no backend endpoints, omit this property
- See server-integration.md for details on setting up endpoints
Business 3.0 API Requirements
WhatsApp Flows uses the Business 3.0 API which has specific requirements:
Every screen MUST have:
id(required) - Unique screen identifiertitle(required) - Screen title for display and navigation
Markdown formatting:
- Only TextBody and TextCaption support markdown
- Set
"markdown": trueto enable formatting - TextHeading does NOT support markdown (will cause validation error)
- Markdown is disabled by default if property omitted
Optional server integration:
data_api_version: "3.0"- Only required if your flow calls backend endpointsrouting_model- Only required withdata_api_versionfor dynamic routing
Minimal structure (no backend needed):
{
"version": "7.1",
"screens": [
{
"id": "SCREEN_ID",
"title": "Screen Title",
"layout": { ... }
}
]
}
With server integration (backend endpoints):
{
"version": "7.1",
"data_api_version": "3.0",
"routing_model": { ... },
"screens": [
{
"id": "SCREEN_ID",
"title": "Screen Title",
"layout": { ... }
}
]
}
See constraints.md for complete validation rules and server-integration.md for endpoint setup.
Essential Constraints
| Item | Limit | Impact |
|---|---|---|
| Components per screen | 50 | Split into multiple screens if exceeded |
| Nesting depth (If/Switch) | 3 levels | Simplify logic or use separate screens |
| Flow JSON size | 10MB | Compress or split large flows |
| Text heading length | 80 chars | Be concise with titles (NO markdown) |
| Text body length | 4096 chars | Supports markdown v5.1+ (set markdown: true) |
| Dropdown options | 200 (static) | Use dynamic data for more options |
| Image max size | 300KB | Optimize images before including |
| Image count per screen | 3 | Limit media usage per screen |
| Screen title | Required | Business 3.0 API requirement |
See constraints.md for complete reference.
Core Reference Files
Navigate to these for detailed guidance:
Components
reference/components.md - All 22 components with syntax and examples
- Text: TextHeading, TextSubheading, TextBody, TextCaption, RichText
- Input: TextInput (7 types), TextArea, DatePicker
- Selection: Dropdown, CheckboxGroup, RadioButtonsGroup, OptIn, ChipsSelector, NavigationList
- Media: Image, ImageCarousel
- Actions: Footer, EmbeddedLink
- Logic: If, Switch
Actions
reference/actions.md - Control flow progression
navigate- Move to next screendata_exchange- Send to server, receive next screencomplete- End flow with responseupdate_data- Update screen state (v6.0+)open_url- Open external link (v6.0+)
Data Binding
reference/data-binding.md - How to reference data
- Form data:
${form.field_name} - Server data:
${data.field_name} - Global references:
${screen.SCREEN_ID.form.field} - Nested expressions:
${...}(v6.0+)
Conditional Logic
reference/conditional-logic.md - If and Switch components
- Boolean conditions with If
- Multi-way branching with Switch
- Nested conditionals (max 3 levels)
- Conditional navigation and inputs
Server Integration
reference/server-integration.md - Backend integration
- Routing models for flow control
- Data endpoints (request/response format)
- Dynamic data from server
- Error handling and validation
Constraints & Validation
reference/constraints.md - Limits and rules
- Character limits per component
- Component counts per screen
- Validation checklist
- Common errors and fixes
Security & Best Practices
reference/security.md - Secure flows
- Sensitive data handling
- HTTPS requirements
- Input validation patterns
- GDPR compliance
Versions & Features
reference/versions.md - Feature matrix v4.0-7.1
- Component availability by version
- Breaking changes between versions
- Migration guide
- Version recommendations
Navigation
reference/TABLE_OF_CONTENTS.md - Find what you need
- By topic, use case, component type
- Quick reference guides
Examples
See examples.md for 4 complete, working flows:
- Simple Multi-Screen Survey - Basic form with navigation
- Conditional Age Verification - If/Switch with routing decisions
- E-Commerce Product Selection - Dynamic data from server
- Server Validation Flow - Email validation with error handling
Common Tasks
I need to add formatted text (bold, lists, emphasis)
- Use TextBody or TextCaption components (not TextHeading)
- Add
"markdown": trueproperty to enable formatting - Use markdown syntax:
**bold**,*italic*,\nfor line breaks,• itemfor lists - Without
markdown: true, markdown syntax displays as plain text - For rich formatting with headers/tables, use RichText instead
- See components.md text components section
Example:
{
"type": "TextBody",
"text": "**Important:** Please read the following carefully.\n\n• First item\n• Second item",
"markdown": true
}
I need to collect user information
- Create a screen with TextInput, TextArea, DatePicker components
- Add Footer with navigate action to next screen
- On confirmation screen, use global reference
${screen.FIRST_SCREEN.form.field_name} - Make sure every screen has a
titleproperty (Business 3.0 requirement) - See components.md input section
I need conditional branching
- Use If component for true/false decisions
- Use Switch component for multiple options
- Reference form data:
${form.field_name}or${screen.X.form.field} - Maximum 3 levels of nesting allowed
- See conditional-logic.md
I need to validate with a backend
- Add
data_api_version: "3.0"androuting_modelto flow - Add
data_exchangeaction to Footer/DatePicker/selection component - Server receives form data in payload
- Server validates and responds with next screen or errors
- See server-integration.md
I need to display dynamic data
- Declare data schema on screen with
__example__values - Use data_exchange action to fetch from server
- Reference with
${data.field_name}in Dropdown, NavigationList, text - See data-binding.md
I need to validate my Flow JSON
# Full validation
python scripts/validate_flow.py your-flow.json
# Component-specific validation
python scripts/validate_components.py your-flow.json
Validators check:
- JSON syntax
- Required properties
- Component counts
- Character limits
- Field name matching
Best Practices
Form Design
- Keep screens focused - one question per screen is ideal
- Use clear, concise labels
- Provide helpful validation messages
- Show progress through multi-step flows
- Make required fields obvious
Data Handling
- Always validate on server (never trust client)
- Use global references
${screen.X.form.field}instead of payloads - Mark sensitive fields with
sensitive: true - Never expose sensitive data in error messages
- Use HTTPS for all external URLs
Conditional Logic
- Keep conditions simple (one or two checks)
- Use Switch instead of nested If for many options
- Test all branches thoroughly
- Provide feedback for conditional content
- Document complex logic with comments
Performance
- Keep JSON under 1MB when possible
- Optimize image sizes (max 300KB)
- Limit components per screen (max 50)
- Use server pagination for large datasets
- Cache dynamic data when appropriate
Mobile Considerations
- Design for small screens (320px width)
- Keep text concise and readable
- Test on actual devices
- Use larger touch targets (buttons)
- Minimize scrolling
Troubleshooting
"condition is always false"
- Check field name matches component
nameproperty (case-sensitive) - Verify field exists before referencing
- Use
${form.field}not${form.Field}
"Field validation errors don't appear"
- Ensure server returns errors with matching field names
- Check response format includes
errorsobject - Verify field names match input component
nameproperties
"Dynamic data not showing"
- Check data schema includes
__example__for all properties - Verify server response includes the data
- Use correct binding syntax:
${data.field_name} - Check component supports dynamic data (Dropdown, NavigationList)
"Navigation not working"
- Verify next_screen exists in screens array
- Check screen IDs are unique (case-sensitive)
- For data_exchange, ensure routing_model includes path
- Verify action is in correct component (Footer, EmbeddedLink, etc.)
"JSON validation fails"
- Run
python scripts/validate_flow.pyfor error details - Check required properties present (version, screens, layout)
- Verify no undefined component types
- Check screen ID and field name rules (alphanumeric + underscore)
See constraints.md for complete validation rules and common errors.
Version Information
Currently supports WhatsApp Flow JSON v4.0 - v7.1.
For new flows, use v7.1 with data_api_version: "3.0".
Key features by version:
- v4.0: Core flows, components, basic validation
- v5.0: RichText component
- v6.0: Nested expressions, update_data, open_url actions
- v6.2: NavigationList component
- v6.3: ChipsSelector, ImageCarousel
- v7.0+: Performance improvements
See versions.md for complete feature matrix and migration guide.
Security Checklist
Before deploying flows with sensitive data:
- All URLs use HTTPS (no HTTP)
- Sensitive fields marked with
sensitive: true - All user input validated server-side
- Errors don't leak information
- Sensitive data not in logs
- Rate limiting enabled on endpoints
- Flow token validation implemented
- GDPR compliance verified
See security.md for detailed security practices.
Getting Help
- Check reference/TABLE_OF_CONTENTS.md for navigation by topic or use case
- See examples.md for working flows you can adapt
- Run validation tools:
python scripts/validate_flow.py - Review constraints.md for limits and rules
- Check versions.md if using older Flow versions
Next Steps
- Read examples - See examples.md for working flows
- Choose your components - See components.md
- Plan your actions - See actions.md
- Design data flow - See data-binding.md
- Validate your flow - Run
python scripts/validate_flow.py your-flow.json - Test thoroughly - All screens, all navigation paths, all conditions
- Deploy - Upload to WhatsApp Business API