WhatsApp Appointment Booking Flow Template

A two-screen flow that captures the service, preferred date, time window and staff preference, then the client's name, email and notes. It is the fastest way to replace "What time works for you?" back-and-forth with one structured request.

2 screens 7 fields returned Flow JSON 7.2 Appointment booking Clinics, Salons, Spas, Consultants

Use Try it to fill the flow and see the exact response_json it returns.

appointment-booking-request.json Open in Flow Builder
{
  "version": "7.2",
  "screens": [
    {
      "id": "BOOKING",
      "title": "Book an appointment",
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_booking",
            "children": [
              {
                "type": "TextHeading",
                "text": "What would you like to book?"
              },
              {
                "type": "TextBody",
                "text": "Choose a service and a time that suits you. We will confirm your appointment by message."
              },
              {
                "type": "RadioButtonsGroup",
                "name": "service",
                "label": "Service",
                "data-source": [
                  {
                    "id": "haircut",
                    "title": "Haircut & styling",
                    "description": "45 min"
                  },
                  {
                    "id": "colour",
                    "title": "Colour treatment",
                    "description": "2 hrs, includes consultation"
                  },
                  {
                    "id": "facial",
                    "title": "Signature facial",
                    "description": "60 min"
                  },
                  {
                    "id": "massage",
                    "title": "Massage therapy",
                    "description": "60 or 90 min"
                  },
                  {
                    "id": "consultation",
                    "title": "Consultation",
                    "description": "20 min, free"
                  }
                ],
                "required": true
              },
              {
                "type": "DatePicker",
                "name": "preferred_date",
                "label": "Preferred date",
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "time_window",
                "label": "Preferred time",
                "data-source": [
                  {
                    "id": "morning",
                    "title": "Morning (9am - 12pm)"
                  },
                  {
                    "id": "afternoon",
                    "title": "Afternoon (12pm - 5pm)"
                  },
                  {
                    "id": "evening",
                    "title": "Evening (5pm - 8pm)"
                  }
                ],
                "required": true
              },
              {
                "type": "Dropdown",
                "name": "staff_preference",
                "label": "Staff preference",
                "data-source": [
                  {
                    "id": "no_preference",
                    "title": "No preference"
                  },
                  {
                    "id": "staff_1",
                    "title": "Sarah"
                  },
                  {
                    "id": "staff_2",
                    "title": "James"
                  },
                  {
                    "id": "staff_3",
                    "title": "Priya"
                  }
                ]
              },
              {
                "type": "Footer",
                "label": "Continue",
                "on-click-action": {
                  "name": "navigate",
                  "next": {
                    "type": "screen",
                    "name": "DETAILS"
                  },
                  "payload": {}
                }
              }
            ]
          }
        ]
      }
    },
    {
      "id": "DETAILS",
      "title": "Your details",
      "terminal": true,
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_details",
            "children": [
              {
                "type": "TextSubheading",
                "text": "Almost done"
              },
              {
                "type": "TextInput",
                "name": "full_name",
                "label": "Full name",
                "input-type": "text",
                "required": true
              },
              {
                "type": "TextInput",
                "name": "email",
                "label": "Email",
                "input-type": "email",
                "helper-text": "For your confirmation and receipt"
              },
              {
                "type": "TextArea",
                "name": "notes",
                "label": "Notes",
                "helper-text": "Allergies, access needs or anything we should know"
              },
              {
                "type": "TextCaption",
                "text": "We will reply on WhatsApp to confirm your slot."
              },
              {
                "type": "Footer",
                "label": "Send request",
                "on-click-action": {
                  "name": "complete",
                  "payload": {
                    "service": "${screen.BOOKING.form.service}",
                    "preferred_date": "${screen.BOOKING.form.preferred_date}",
                    "time_window": "${screen.BOOKING.form.time_window}",
                    "staff_preference": "${screen.BOOKING.form.staff_preference}",
                    "full_name": "${form.full_name}",
                    "email": "${form.email}",
                    "notes": "${form.notes}"
                  }
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Raw JSON for scripts: curl -s https://whautomate.com/whatsapp-flow-templates/appointment-booking-request.json

Import in 60 seconds
  1. Copy the JSON above (or edit it first in the Flow Builder).
  2. In WhatsApp Manager, open Account tools > Flows, create a flow and choose Appointment booking as the category.
  3. Paste into the JSON editor, check the preview, then Publish.
  4. Send it with the Flow ID, as an interactive message or through a template's Flow button.

Not technical? Skip the JSON and send it from Whautomate with a drag-and-drop editor.

About this appointment booking request flow

Most booking conversations on WhatsApp take five to eight messages: which service, which day, morning or afternoon, which staff member, and a name for the booking. This flow collects all of it in one form the client fills out without leaving the chat, and your team gets a single structured request to confirm.

Screen one handles the booking itself. Services are a radio list with short descriptions, so clients choose the right treatment instead of typing a vague "a haircut". Screen two captures contact details and notes, and ends the flow. Because the phone number already comes with the WhatsApp message, the form does not ask for it again.

This is a static flow: it records a request rather than checking live availability. That keeps it free to run with no server, and it works well for businesses that confirm bookings manually or have flexible calendars.

Fields this flow returns

When the customer taps the final button, the complete action sends these keys back in response_json. Fields from earlier screens are pulled in with global references (${screen.SCREEN_ID.form.field}), so nothing is lost between screens.

KeyComponentScreenRequiredReturnsExample
service
haircut, colour, facial, massage, consultation
RadioButtonsGroup BOOKING Yes item id "facial"
preferred_date DatePicker BOOKING Yes YYYY-MM-DD "2026-10-14"
time_window
morning, afternoon, evening
RadioButtonsGroup BOOKING Yes item id "afternoon"
staff_preference
no_preference, staff_1, staff_2, staff_3
Dropdown BOOKING No item id "no_preference"
full_name TextInput DETAILS Yes string "Alex Morgan"
email TextInput (email) DETAILS No string "[email protected]"
notes TextArea DETAILS No string "Sensitive skin, please use fragrance-free products."

Optional fields the customer leaves empty may be missing from response_json or arrive empty. Treat every optional key as nullable in your handler.

No developer needed

Send the Appointment Booking Request flow without touching code

You do not need to be technical to use WhatsApp Flows. Connect your WhatsApp number, set the flow up in our drag-and-drop editor and send it to customers in a few clicks. No JSON, no API calls, no WhatsApp Manager.

1

Connect your number

Log in with Facebook and connect your WhatsApp number in a few minutes. No API keys or servers to set up.

2

Set up the flow

Start from a ready-made form or import this one, then drag fields in, change the wording and try it on a live phone preview. Click Publish when it looks right.

3

Send it anywhere

Send it from any chat in the Team Inbox, on web or mobile, send it automatically from an automation, or broadcast it to a list.

4

Get the answers

Every answer is saved on the customer's profile and chat, and your team can be notified the moment a form comes in.

7-day free trial, no credit card required.

Sample webhook payload (nfm_reply)

This is what your webhook receives when a customer submits the flow. response_json is a JSON string: parse it, then match flow_token to the record you created when you sent the message. The customer's WhatsApp number is in messages[0].from.

response_json (parsed)
{
  "flow_token": "bk_8f2c41",
  "service": "facial",
  "preferred_date": "2026-10-14",
  "time_window": "afternoon",
  "staff_preference": "no_preference",
  "full_name": "Alex Morgan",
  "email": "[email protected]",
  "notes": "Sensitive skin, please use fragrance-free products."
}
POST your-webhook (full event)
{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "WHATSAPP_BUSINESS_ACCOUNT_ID",
      "changes": [
        {
          "field": "messages",
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "15550001234",
              "phone_number_id": "PHONE_NUMBER_ID"
            },
            "contacts": [
              {
                "profile": {
                  "name": "Alex Morgan"
                },
                "wa_id": "14155550123"
              }
            ],
            "messages": [
              {
                "context": {
                  "from": "15550001234",
                  "id": "wamid.SENT_FLOW_MESSAGE_ID"
                },
                "from": "14155550123",
                "id": "wamid.INCOMING_MESSAGE_ID",
                "timestamp": "1760000000",
                "type": "interactive",
                "interactive": {
                  "type": "nfm_reply",
                  "nfm_reply": {
                    "name": "flow",
                    "body": "Sent",
                    "response_json": "{\"flow_token\":\"bk_8f2c41\",\"service\":\"facial\",\"preferred_date\":\"2026-10-14\",\"time_window\":\"afternoon\",\"staff_preference\":\"no_preference\",\"full_name\":\"Alex Morgan\",\"email\":\"[email protected]\",\"notes\":\"Sensitive skin, please use fragrance-free products.\"}"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ]
}

Deploy with the WhatsApp Cloud API

Prefer code over WhatsApp Manager? Save the template as appointment-booking-request.json and run these calls with a system user token that has whatsapp_business_management and whatsapp_business_messaging permissions.

1. Create the flow

bash
curl -X POST 'https://graph.facebook.com/v23.0/{WABA_ID}/flows' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{"name": "appointment_booking_request", "categories": ["APPOINTMENT_BOOKING"]}'
# => {"id": "{FLOW_ID}"}

2. Upload the Flow JSON

bash
curl -X POST 'https://graph.facebook.com/v23.0/{FLOW_ID}/assets' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -F '[email protected];type=application/json' \
  -F 'name=flow.json' \
  -F 'asset_type=FLOW_JSON'
# => {"success": true, "validation_errors": []}

3. Publish it

bash
curl -X POST 'https://graph.facebook.com/v23.0/{FLOW_ID}/publish' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}'

Publishing is permanent: a published flow cannot be edited. To change it later, create a new flow (or clone it with clone_flow_id) and publish the new version.

4. Send it to a customer

Inside the 24-hour customer service window, send an interactive flow message. Outside it, create a message template with a Flow button that points to this flow, and send the template instead.

send-appointment-booking-request.json
{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "14155550123",
  "type": "interactive",
  "interactive": {
    "type": "flow",
    "header": {
      "type": "text",
      "text": "Book your next visit"
    },
    "body": {
      "text": "Pick a service and a time that suits you. It takes less than a minute and we will confirm your slot by message."
    },
    "footer": {
      "text": "Reply STOP to opt out"
    },
    "action": {
      "name": "flow",
      "parameters": {
        "flow_message_version": "3",
        "flow_token": "bk_8f2c41",
        "flow_id": "YOUR_FLOW_ID",
        "flow_cta": "Request appointment",
        "flow_action": "navigate",
        "flow_action_payload": {
          "screen": "BOOKING"
        }
      }
    }
  }
}
bash
curl -X POST 'https://graph.facebook.com/v23.0/{PHONE_NUMBER_ID}/messages' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d @send-appointment-booking-request.json

When to send it

Keyword reply

Send it when a customer messages "book", "appointment" or "available?", so the first reply is the booking form rather than a question.

Click-to-WhatsApp ads

Ad traffic converts better when the first message is something to tap. Send the flow as the opening reply to ad conversations.

Rebooking broadcast

Attach it to a marketing template's Flow button and send it to clients whose last visit was six to eight weeks ago.

Missed-call follow-up

If you log missed calls, follow up with the flow instead of a callback so the client can book on their own schedule.

How to customise this template

  • Replace the service ids (haircut, colour, facial...) with your own. Keep ids stable once live, because your webhook handler maps on them.
  • Use the item description to show duration and starting price, for example "45 min, from $40". Clients pick faster when price is visible.
  • If you have one staff member, delete the staff Dropdown. If you have more than 20, keep it a Dropdown: RadioButtonsGroup is capped at 20 items.
  • Change the time windows to match your opening hours, or replace them with specific slots if your schedule is fixed.

Open this template in the Flow Builder to make these changes visually. The builder keeps field names unique and regenerates the completion payload for you.

Common mistakes to avoid

  • Do not promise a confirmed slot in the TextBody. A static flow cannot check availability, so say "we will confirm by message".
  • TextInput labels are limited to 20 characters. "Your full name as on ID" will fail validation in Meta; "Full name" will not.
  • DatePicker returns YYYY-MM-DD from Flow JSON 5.0 onwards. Parse it as a date without time zone conversion, or it can shift by a day.
  • Keep the flow_token unique per send (for example the booking or contact id). It is the only way to match a submission to the message you sent.

Need live availability instead of a "preferred time"?

A static flow can only collect a requested time, so your team still has to confirm it by hand. Whautomate ships a built-in appointment booking flow that reads your real services, staff and open slots, books the appointment directly and sends the confirmation. It is created and published in your WhatsApp account from an automation template, and it runs on an encrypted endpoint Whautomate hosts. There is no endpoint code for you to write.

  • Live services, staff and time slots from your calendar
  • Books directly, with no manual confirmation step
  • Multi-location version picks the branch first

7-day free trial, no credit card required.

Frequently asked questions

Not as a static flow. Showing live slots needs a data_exchange endpoint that returns availability for the chosen date. This template records a preferred date and time window instead, which your team confirms. Whautomate's built-in booking flow handles live slots for you.
An interactive message of type nfm_reply. Its response_json string contains the flow_token plus every field: service, preferred_date, time_window, staff_preference, full_name, email and notes. Radio and dropdown fields return the item id, not the title.
The submission arrives as a WhatsApp message, so the sender's number is already in the webhook (messages[0].from). Asking for it again adds friction and invites typos.
Only inside an approved message template with a Flow button. Interactive flow messages can be sent freely only within the 24-hour customer service window.

The Complete Omnichannel Customer Engagement Platform

Go beyond free tools. Automate conversations, build AI chatbots, send broadcast campaigns, book appointments, sell products, and manage every messaging channel from one powerful platform. Trusted by thousands of businesses worldwide.

  • WhatsApp, Instagram, Messenger, Telegram & Live Chat
  • AI chatbots & no-code automation
  • Broadcast campaigns & analytics
  • Appointment & class booking
  • E-commerce, Shopify & WooCommerce integration
  • CRM, invoicing & payment collection

No credit card required. Free 7-day trial. Visit our pricing page for plans.