WhatsApp CSAT Survey Flow Template

A single-screen customer satisfaction survey: a labelled 1 to 5 score, two tick lists for what went well and what needs work, and an optional comment. Short enough that people finish it, structured enough that you can count the answers.

1 screen 4 fields returned Flow JSON 7.2 Survey Clinics, Salons, Spas, Stores, Consultants

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

csat-survey.json Open in Flow Builder
{
  "version": "7.2",
  "screens": [
    {
      "id": "CSAT",
      "title": "How did we do?",
      "terminal": true,
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_csat",
            "children": [
              {
                "type": "TextHeading",
                "text": "Rate your experience"
              },
              {
                "type": "TextBody",
                "text": "It takes about 30 seconds. Your answers go straight to our team."
              },
              {
                "type": "RadioButtonsGroup",
                "name": "satisfaction",
                "label": "Overall satisfaction",
                "data-source": [
                  {
                    "id": "csat_5",
                    "title": "5 - Very satisfied"
                  },
                  {
                    "id": "csat_4",
                    "title": "4 - Satisfied"
                  },
                  {
                    "id": "csat_3",
                    "title": "3 - Neutral"
                  },
                  {
                    "id": "csat_2",
                    "title": "2 - Dissatisfied"
                  },
                  {
                    "id": "csat_1",
                    "title": "1 - Very dissatisfied"
                  }
                ],
                "required": true
              },
              {
                "type": "CheckboxGroup",
                "name": "went_well",
                "label": "What went well?",
                "data-source": [
                  {
                    "id": "staff_friendly",
                    "title": "Friendly, helpful staff"
                  },
                  {
                    "id": "on_time",
                    "title": "Started on time"
                  },
                  {
                    "id": "quality",
                    "title": "Quality of the service"
                  },
                  {
                    "id": "value",
                    "title": "Good value for money"
                  },
                  {
                    "id": "easy_booking",
                    "title": "Easy to book"
                  },
                  {
                    "id": "clean_space",
                    "title": "Clean, comfortable space"
                  }
                ]
              },
              {
                "type": "CheckboxGroup",
                "name": "improve_areas",
                "label": "What should we improve?",
                "data-source": [
                  {
                    "id": "wait_time",
                    "title": "Waiting time"
                  },
                  {
                    "id": "communication",
                    "title": "Communication"
                  },
                  {
                    "id": "price",
                    "title": "Price"
                  },
                  {
                    "id": "booking_process",
                    "title": "Booking process"
                  },
                  {
                    "id": "service_quality",
                    "title": "Quality of the service"
                  },
                  {
                    "id": "facilities",
                    "title": "Facilities"
                  },
                  {
                    "id": "nothing",
                    "title": "Nothing, all good"
                  }
                ]
              },
              {
                "type": "TextArea",
                "name": "comments",
                "label": "Anything else?",
                "helper-text": "Optional. Tell us in your own words",
                "max-length": 600
              },
              {
                "type": "Footer",
                "label": "Send feedback",
                "on-click-action": {
                  "name": "complete",
                  "payload": {
                    "satisfaction": "${form.satisfaction}",
                    "went_well": "${form.went_well}",
                    "improve_areas": "${form.improve_areas}",
                    "comments": "${form.comments}"
                  }
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Raw JSON for scripts: curl -s https://whautomate.com/whatsapp-flow-templates/csat-survey.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 Survey 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 csat survey flow

Customer satisfaction (CSAT) asks one direct question about a specific interaction: how satisfied were you? Sent by WhatsApp a few hours after a visit, order or support chat, it gets far higher response rates than an emailed survey link, because the client answers inside the conversation they already have open.

This template keeps everything on one screen. The score is a radio list where every option carries its own words ("4 - Satisfied", "2 - Dissatisfied"), so nobody has to guess whether 1 or 5 is the good end. Two checkbox lists then turn a bare number into something you can act on: which strengths to keep, and which problems to fix first. A free-text box catches anything the lists miss.

The standard CSAT figure is the share of responses scoring 4 or 5, divided by all responses, times 100. Because the flow returns item ids like csat_4, your handler strips the prefix to get the number, and the checkbox arrays let you rank the most common complaints across a week or a location.

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
satisfaction
csat_5, csat_4, csat_3, csat_2, csat_1
RadioButtonsGroup CSAT Yes item id "csat_4"
went_well
staff_friendly, on_time, quality, value, easy_booking, clean_space
CheckboxGroup CSAT No array of ids ["staff_friendly","on_time"]
improve_areas
wait_time, communication, price, booking_process, service_quality, facilities, nothing
CheckboxGroup CSAT No array of ids ["wait_time"]
comments TextArea CSAT No string "Great result, but I waited about 15 minutes past my booking time."

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 CSAT Survey 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",
  "satisfaction": "csat_4",
  "went_well": [
    "staff_friendly",
    "on_time"
  ],
  "improve_areas": [
    "wait_time"
  ],
  "comments": "Great result, but I waited about 15 minutes past my booking time."
}
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\",\"satisfaction\":\"csat_4\",\"went_well\":[\"staff_friendly\",\"on_time\"],\"improve_areas\":[\"wait_time\"],\"comments\":\"Great result, but I waited about 15 minutes past my booking time.\"}"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ]
}

Deploy with the WhatsApp Cloud API

Prefer code over WhatsApp Manager? Save the template as csat-survey.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": "csat_survey", "categories": ["SURVEY"]}'
# => {"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-csat-survey.json
{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "14155550123",
  "type": "interactive",
  "interactive": {
    "type": "flow",
    "header": {
      "type": "text",
      "text": "How did we do?"
    },
    "body": {
      "text": "Thanks for choosing us today. Could you rate your experience? It is one short screen and helps us get better every week."
    },
    "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": "Rate your experience",
        "flow_action": "navigate",
        "flow_action_payload": {
          "screen": "CSAT"
        }
      }
    }
  }
}
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-csat-survey.json

When to send it

After a completed appointment

Send it two to four hours after the visit ends, while the experience is fresh but the client has left the building and has a minute to reply.

After a support chat closes

When an agent marks a conversation resolved, the CSAT flow measures that agent and that resolution, not the brand in general.

After delivery or pickup

For store orders, trigger it once the order is marked delivered or collected, not at payment, so the score reflects the product in hand.

Monthly pulse for regulars

Members or retainer clients can get it once a month to catch slow declines in satisfaction before they turn into cancellations.

How to customise this template

  • Rename the "went well" and "improve" options to the moments that matter in your business: a clinic might list "Explained clearly" and "Waiting room time", a store "Packaging" and "Delivery speed".
  • Keep the score ids as csat_1 to csat_5 even if you change the titles. Your reporting code then works across every location and language version of the flow.
  • If you run the survey in several languages, publish one flow per language and keep the same field names and item ids in each, so all responses land in one dataset.
  • Add a max-length to the comment box if you push answers into a system with a character limit. The template uses 600, which is plenty for a real comment.

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 reverse the scale between surveys. If one flow puts "Very satisfied" first and another puts it last, clients mis-tap and your averages drift.
  • Send once per interaction. Two CSAT requests for the same visit (for example one from a booking automation and one from a manual broadcast) annoy people and double-count scores.
  • Radio fields return the item id, not the number. Parse "csat_4" to 4 in your handler, and never average the raw strings.
  • A static flow cannot personalise the question with the staff name or service. Put that context in the message body that carries the flow button instead.

Send it automatically after every visit

In Whautomate, import this flow into the built-in flow editor and click Publish. Attach it to a message template's Flow button and send it from an automation when an appointment is created or updated, or as a broadcast to a segment. Every response is saved on the client's profile, and a "WhatsApp Flow form is submitted" automation can alert your team the moment a low score comes in.

  • Automations on appointment, class and order updates
  • Alert staff on low scores automatically
  • Responses saved to the client profile and exportable

7-day free trial, no credit card required.

Frequently asked questions

Count responses where satisfaction is csat_4 or csat_5, divide by all responses in the period, and multiply by 100. Many teams also track the average of the 1 to 5 values, but the top-two-box percentage is the figure most benchmarks use.
An interactive message of type nfm_reply whose response_json contains the flow_token, satisfaction (an item id), went_well and improve_areas (arrays of item ids, possibly empty) and comments (a string, missing or empty if skipped).
Put the visit, order or ticket id in the flow_token when you send the flow, for example "csat_visit_48213". It comes back unchanged in response_json, so you can attach the score to the right record and staff member.
Only through an approved message template with a Flow button, because the 24-hour customer service window has usually closed by then. Meta decides the template category on review; a feedback request is often classed as marketing, so plan for that pricing.
Attach the published flow to a template's Flow button and add a send-template step to an automation that runs when an appointment is updated. Each response then shows on the client's chat in the shared team inbox, where your team can follow up on a low score.

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.