WhatsApp Course Enrollment Flow Template

A two-screen flow for academies and schools. It captures the course, the student's level, the schedules that work, their age group and a start date, then the student and parent or guardian details and agreement to your enrolment policy.

2 screens 9 fields returned Flow JSON 7.2 Sign up Tutoring centres, Language schools, Music academies, Dance schools

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

course-enrollment.json Open in Flow Builder
{
  "version": "7.2",
  "screens": [
    {
      "id": "COURSE",
      "title": "Choose your course",
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_course",
            "children": [
              {
                "type": "TextHeading",
                "text": "Which course would you like?"
              },
              {
                "type": "TextBody",
                "text": "Tell us the course, level and times that suit you. We will place the student in the best group with space."
              },
              {
                "type": "Dropdown",
                "name": "course",
                "label": "Course",
                "data-source": [
                  {
                    "id": "english_group",
                    "title": "English, small group"
                  },
                  {
                    "id": "spanish_group",
                    "title": "Spanish, small group"
                  },
                  {
                    "id": "maths_tutoring",
                    "title": "Maths tutoring"
                  },
                  {
                    "id": "piano_private",
                    "title": "Piano, private lessons"
                  },
                  {
                    "id": "guitar_group",
                    "title": "Guitar, small group"
                  },
                  {
                    "id": "ballet_class",
                    "title": "Ballet"
                  },
                  {
                    "id": "hip_hop_class",
                    "title": "Hip hop dance"
                  }
                ],
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "student_level",
                "label": "Current level",
                "data-source": [
                  {
                    "id": "level_new",
                    "title": "Complete beginner",
                    "description": "Has not studied this before"
                  },
                  {
                    "id": "level_beginner_plus",
                    "title": "Some basics",
                    "description": "Knows the fundamentals, for example simple phrases or a few pieces"
                  },
                  {
                    "id": "level_intermediate",
                    "title": "Intermediate",
                    "description": "Comfortable with the basics and ready for more challenge"
                  },
                  {
                    "id": "level_advanced",
                    "title": "Advanced",
                    "description": "Preparing for exams, performances or fluency"
                  },
                  {
                    "id": "level_assess",
                    "title": "Not sure, please assess",
                    "description": "We will arrange a short placement check"
                  }
                ],
                "required": true
              },
              {
                "type": "CheckboxGroup",
                "name": "schedule_preference",
                "label": "Times that work",
                "data-source": [
                  {
                    "id": "sched_weekday_afternoon",
                    "title": "Weekday afternoons"
                  },
                  {
                    "id": "sched_weekday_evening",
                    "title": "Weekday evenings"
                  },
                  {
                    "id": "sched_saturday_morning",
                    "title": "Saturday mornings"
                  },
                  {
                    "id": "sched_saturday_afternoon",
                    "title": "Saturday afternoons"
                  },
                  {
                    "id": "sched_sunday",
                    "title": "Sundays"
                  },
                  {
                    "id": "sched_online",
                    "title": "Online lessons"
                  }
                ],
                "required": true,
                "min-selected-items": 1
              },
              {
                "type": "RadioButtonsGroup",
                "name": "age_group",
                "label": "Student age",
                "data-source": [
                  {
                    "id": "age_under_7",
                    "title": "Under 7"
                  },
                  {
                    "id": "age_7_12",
                    "title": "7 to 12"
                  },
                  {
                    "id": "age_13_17",
                    "title": "13 to 17"
                  },
                  {
                    "id": "age_adult",
                    "title": "18 or over"
                  }
                ],
                "required": true
              },
              {
                "type": "DatePicker",
                "name": "start_date",
                "label": "Preferred start date",
                "required": true
              },
              {
                "type": "Footer",
                "label": "Continue",
                "on-click-action": {
                  "name": "navigate",
                  "next": {
                    "type": "screen",
                    "name": "STUDENT_DETAILS"
                  },
                  "payload": {}
                }
              }
            ]
          }
        ]
      }
    },
    {
      "id": "STUDENT_DETAILS",
      "title": "Student details",
      "terminal": true,
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_student_details",
            "children": [
              {
                "type": "TextSubheading",
                "text": "Who is enrolling?"
              },
              {
                "type": "TextInput",
                "name": "student_name",
                "label": "Student name",
                "input-type": "text",
                "required": true
              },
              {
                "type": "TextInput",
                "name": "guardian_name",
                "label": "Parent or guardian",
                "input-type": "text",
                "helper-text": "Required if the student is under 18"
              },
              {
                "type": "TextInput",
                "name": "guardian_email",
                "label": "Contact email",
                "input-type": "email",
                "required": true,
                "helper-text": "Timetables, invoices and term updates go here"
              },
              {
                "type": "EmbeddedLink",
                "text": "Read enrolment policy",
                "on-click-action": {
                  "name": "open_url",
                  "url": "https://example.com/enrolment-policy"
                }
              },
              {
                "type": "OptIn",
                "name": "policy_agreement",
                "label": "I accept the enrolment policy, including term fees, the 4-week notice period and missed-lesson rules.",
                "required": true
              },
              {
                "type": "Footer",
                "label": "Submit enrolment",
                "on-click-action": {
                  "name": "complete",
                  "payload": {
                    "course": "${screen.COURSE.form.course}",
                    "student_level": "${screen.COURSE.form.student_level}",
                    "schedule_preference": "${screen.COURSE.form.schedule_preference}",
                    "age_group": "${screen.COURSE.form.age_group}",
                    "start_date": "${screen.COURSE.form.start_date}",
                    "student_name": "${form.student_name}",
                    "guardian_name": "${form.guardian_name}",
                    "guardian_email": "${form.guardian_email}",
                    "policy_agreement": "${form.policy_agreement}"
                  }
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Raw JSON for scripts: curl -s https://whautomate.com/whatsapp-flow-templates/course-enrollment.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 Sign up 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 course enrollment flow

Placing a student in a group needs four things: the course, the level, the times they can attend and their age. Parents usually send these across several messages over several days, and the admin team pieces them together by scrolling. This flow collects them in one submission you can sort into groups directly.

Screen one is about the course. A Dropdown handles long course lists, the level radio uses descriptions so parents can self-assess ("can hold a simple conversation" rather than "A2"), the schedule CheckboxGroup lets families tick every slot that works, and the age group and start date complete the placement data. Screen two collects the student's name and the parent or guardian's name and email, and ends with an OptIn confirming they accept your enrolment and cancellation policy.

Asking for all workable schedules, not just one, is the detail that makes this useful. A student who can do weekday evenings or Saturday mornings can be placed in whichever group has space, which fills classes more evenly and cuts waitlists.

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
course
english_group, spanish_group, maths_tutoring, piano_private, guitar_group, ballet_class, hip_hop_class
Dropdown COURSE Yes item id "spanish_group"
student_level
level_new, level_beginner_plus, level_intermediate, level_advanced, level_assess
RadioButtonsGroup COURSE Yes item id "level_beginner_plus"
schedule_preference
sched_weekday_afternoon, sched_weekday_evening, sched_saturday_morning, sched_saturday_afternoon, sched_sunday, sched_online
CheckboxGroup COURSE Yes array of ids ["sched_weekday_evening","sched_saturday_morning"]
age_group
age_under_7, age_7_12, age_13_17, age_adult
RadioButtonsGroup COURSE Yes item id "age_13_17"
start_date DatePicker COURSE Yes YYYY-MM-DD "2026-10-05"
student_name TextInput STUDENT_DETAILS Yes string "Lucas Ferreira"
guardian_name TextInput STUDENT_DETAILS No string "Ana Ferreira"
guardian_email TextInput (email) STUDENT_DETAILS Yes string "[email protected]"
policy_agreement OptIn STUDENT_DETAILS Yes boolean true

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 Course Enrollment 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",
  "course": "spanish_group",
  "student_level": "level_beginner_plus",
  "schedule_preference": [
    "sched_weekday_evening",
    "sched_saturday_morning"
  ],
  "age_group": "age_13_17",
  "start_date": "2026-10-05",
  "student_name": "Lucas Ferreira",
  "guardian_name": "Ana Ferreira",
  "guardian_email": "[email protected]",
  "policy_agreement": true
}
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\",\"course\":\"spanish_group\",\"student_level\":\"level_beginner_plus\",\"schedule_preference\":[\"sched_weekday_evening\",\"sched_saturday_morning\"],\"age_group\":\"age_13_17\",\"start_date\":\"2026-10-05\",\"student_name\":\"Lucas Ferreira\",\"guardian_name\":\"Ana Ferreira\",\"guardian_email\":\"[email protected]\",\"policy_agreement\":true}"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ]
}

Deploy with the WhatsApp Cloud API

Prefer code over WhatsApp Manager? Save the template as course-enrollment.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": "course_enrollment", "categories": ["SIGN_UP"]}'
# => {"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-course-enrollment.json
{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "14155550123",
  "type": "interactive",
  "interactive": {
    "type": "flow",
    "header": {
      "type": "text",
      "text": "Enrolment is open"
    },
    "body": {
      "text": "Choose a course and level, tell us which times suit you and we will place you in the right group. It takes about two minutes."
    },
    "footer": {
      "text": "Places are limited per group"
    },
    "action": {
      "name": "flow",
      "parameters": {
        "flow_message_version": "3",
        "flow_token": "bk_8f2c41",
        "flow_id": "YOUR_FLOW_ID",
        "flow_cta": "Enrol now",
        "flow_action": "navigate",
        "flow_action_payload": {
          "screen": "COURSE"
        }
      }
    }
  }
}
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-course-enrollment.json

When to send it

Term enrolment campaigns

Broadcast a Flow-button template to current and past families three to four weeks before term starts, so group sizes are known before timetables are fixed.

Trial lesson follow-up

Send the flow the evening after a trial lesson, when the student and parent are most likely to commit.

Course enquiries

Reply with the flow when someone asks about a course, levels or timetables. It answers "which group?" by collecting what you need to decide.

Level progression

At the end of term, send it to students finishing a level to enrol them into the next one before their spot is offered to new students.

How to customise this template

  • Use a Dropdown for courses so you can list many (Dropdowns take up to 200 items) and keep course ids tied to your timetable system, for example spanish_group or piano_private.
  • Describe each level in outcomes, not codes. Parents rarely know what "Grade 3" or "B1" means but can recognise "reads simple music" or "can order in a restaurant".
  • Replace the schedule options with your real teaching blocks. If groups run only at fixed times, name the exact slot, like "Tue & Thu 5pm - 6:30pm".
  • Point the policy EmbeddedLink at your real terms page, and name the essentials in the OptIn label: fees per term, notice period and missed-lesson rules.
  • For adult-only schools, remove the guardian name field and the under-12 age group.

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 make the guardian name required for adult learners. Either keep it optional, as here, or send a separate adult flow, or students over 18 will abandon the form.
  • An OptIn marked required blocks submission until ticked. Make sure the linked policy is reachable on mobile; a broken link means nobody can enrol.
  • The student_name and guardian_name fields must stay distinct names. Field names are payload keys, and a duplicate "name" field fails Meta validation.
  • Collecting data about minors carries extra obligations in many countries. Ask only what you need for placement and keep medical or safeguarding details for your formal registration form.

Sell memberships and packages in chat

When the enquiry turns into a purchase, Whautomate has a built-in buy-plan flow. Clients pick a plan, see a summary and subscribe inside WhatsApp. It is published in your account automatically and reads your live plans.

  • Your real plans and pricing
  • Subscription created on submit
  • Single and multi-location versions

7-day free trial, no credit card required.

Frequently asked questions

Not as a static flow. Live places need a data_exchange endpoint that returns groups with capacity for the chosen course and level. This template collects schedule preferences so your team places the student manually.
A boolean in response_json. Because the OptIn is required, a submitted flow will always carry true, and you can store it with the flow_token and timestamp as your record of acceptance.
Send the flow once per student, each with its own flow_token. Trying to add a second student to one submission makes the form long and the data hard to split later.
Enrolment is a sign-up to a course rather than a single appointment or a general lead. SIGN_UP describes the purpose to Meta, but it does not change how the flow renders or behaves.
Not with this static template. If you sell courses as packages, Whautomate's built-in buy-plan flow lets a client choose a plan and subscribe inside WhatsApp, using your live plans.

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.