WhatsApp Post-Visit Review Flow Template

A two-screen review request: three 1 to 5 ratings (service, staff member, cleanliness and ambience) plus a would-recommend question, then a comment, a Google review link shown to everyone and permission to quote the client as a testimonial.

2 screens 6 fields returned Flow JSON 7.2 Survey Clinics, Salons, Spas, Studios

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

post-visit-review.json Open in Flow Builder
{
  "version": "7.2",
  "screens": [
    {
      "id": "RATINGS",
      "title": "Rate your visit",
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_ratings",
            "children": [
              {
                "type": "TextHeading",
                "text": "How was your visit today?"
              },
              {
                "type": "TextBody",
                "text": "5 is excellent, 1 is very poor."
              },
              {
                "type": "RadioButtonsGroup",
                "name": "service_rating",
                "label": "The service",
                "data-source": [
                  {
                    "id": "service_5",
                    "title": "5 - Excellent"
                  },
                  {
                    "id": "service_4",
                    "title": "4 - Good"
                  },
                  {
                    "id": "service_3",
                    "title": "3 - Okay"
                  },
                  {
                    "id": "service_2",
                    "title": "2 - Poor"
                  },
                  {
                    "id": "service_1",
                    "title": "1 - Very poor"
                  }
                ],
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "staff_rating",
                "label": "Your team member",
                "data-source": [
                  {
                    "id": "staff_5",
                    "title": "5 - Excellent"
                  },
                  {
                    "id": "staff_4",
                    "title": "4 - Good"
                  },
                  {
                    "id": "staff_3",
                    "title": "3 - Okay"
                  },
                  {
                    "id": "staff_2",
                    "title": "2 - Poor"
                  },
                  {
                    "id": "staff_1",
                    "title": "1 - Very poor"
                  }
                ],
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "ambience_rating",
                "label": "Cleanliness & ambience",
                "data-source": [
                  {
                    "id": "ambience_5",
                    "title": "5 - Excellent"
                  },
                  {
                    "id": "ambience_4",
                    "title": "4 - Good"
                  },
                  {
                    "id": "ambience_3",
                    "title": "3 - Okay"
                  },
                  {
                    "id": "ambience_2",
                    "title": "2 - Poor"
                  },
                  {
                    "id": "ambience_1",
                    "title": "1 - Very poor"
                  }
                ],
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "would_recommend",
                "label": "Would you recommend us?",
                "data-source": [
                  {
                    "id": "recommend_yes",
                    "title": "Yes"
                  },
                  {
                    "id": "recommend_maybe",
                    "title": "Maybe"
                  },
                  {
                    "id": "recommend_no",
                    "title": "No"
                  }
                ],
                "required": true
              },
              {
                "type": "Footer",
                "label": "Continue",
                "on-click-action": {
                  "name": "navigate",
                  "next": {
                    "type": "screen",
                    "name": "REVIEW"
                  },
                  "payload": {}
                }
              }
            ]
          }
        ]
      }
    },
    {
      "id": "REVIEW",
      "title": "Share your thoughts",
      "terminal": true,
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_review",
            "children": [
              {
                "type": "TextSubheading",
                "text": "Anything you would like to add?"
              },
              {
                "type": "TextArea",
                "name": "review_comment",
                "label": "Your comments",
                "helper-text": "What stood out, good or bad",
                "max-length": 600
              },
              {
                "type": "TextBody",
                "text": "Reviews help other people find us. If you have a moment, we would value an honest review on Google."
              },
              {
                "type": "EmbeddedLink",
                "text": "Leave a Google review",
                "on-click-action": {
                  "name": "open_url",
                  "url": "https://g.page/r/YOUR_PLACE_ID/review"
                }
              },
              {
                "type": "OptIn",
                "name": "testimonial_ok",
                "label": "You may feature my comments as a testimonial, with my first name only"
              },
              {
                "type": "Footer",
                "label": "Send review",
                "on-click-action": {
                  "name": "complete",
                  "payload": {
                    "service_rating": "${screen.RATINGS.form.service_rating}",
                    "staff_rating": "${screen.RATINGS.form.staff_rating}",
                    "ambience_rating": "${screen.RATINGS.form.ambience_rating}",
                    "would_recommend": "${screen.RATINGS.form.would_recommend}",
                    "review_comment": "${form.review_comment}",
                    "testimonial_ok": "${form.testimonial_ok}"
                  }
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Raw JSON for scripts: curl -s https://whautomate.com/whatsapp-flow-templates/post-visit-review.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 post-visit review flow

A single overall score tells you something went wrong; it does not tell you whether it was the treatment, the person who delivered it or the room it happened in. This flow splits the visit into three ratings so a salon can see that colour results score 5 while the waiting area scores 3, or a clinic can spot one team member whose ratings trail the rest.

Screen two turns private feedback into public proof. The client can leave a comment, tap through to your Google review page, and tick a box allowing you to use their words as a testimonial. The review link sits on the final screen for every respondent, whatever they scored. That is deliberate: Google's review policy prohibits selectively soliciting reviews from happy customers, often called review gating, and profiles caught doing it risk having reviews removed.

Because the ratings arrive as structured ids (service_4, staff_5), you can alert a manager the moment any rating comes in at 1 or 2 and reply personally while the client is still in the chat. That fast private response is the legitimate way to handle an unhappy client, rather than hiding the review link from them.

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_rating
service_5, service_4, service_3, service_2, service_1
RadioButtonsGroup RATINGS Yes item id "service_5"
staff_rating
staff_5, staff_4, staff_3, staff_2, staff_1
RadioButtonsGroup RATINGS Yes item id "staff_5"
ambience_rating
ambience_5, ambience_4, ambience_3, ambience_2, ambience_1
RadioButtonsGroup RATINGS Yes item id "ambience_4"
would_recommend
recommend_yes, recommend_maybe, recommend_no
RadioButtonsGroup RATINGS Yes item id "recommend_yes"
review_comment TextArea REVIEW No string "Maya took real care with my colour and explained the aftercare."
testimonial_ok OptIn REVIEW No 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 Post-Visit Review 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_rating": "service_5",
  "staff_rating": "staff_5",
  "ambience_rating": "ambience_4",
  "would_recommend": "recommend_yes",
  "review_comment": "Maya took real care with my colour and explained the aftercare.",
  "testimonial_ok": 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\",\"service_rating\":\"service_5\",\"staff_rating\":\"staff_5\",\"ambience_rating\":\"ambience_4\",\"would_recommend\":\"recommend_yes\",\"review_comment\":\"Maya took real care with my colour and explained the aftercare.\",\"testimonial_ok\":true}"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ]
}

Deploy with the WhatsApp Cloud API

Prefer code over WhatsApp Manager? Save the template as post-visit-review.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": "post_visit_review", "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-post-visit-review.json
{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "14155550123",
  "type": "interactive",
  "interactive": {
    "type": "flow",
    "header": {
      "type": "text",
      "text": "Thanks for visiting"
    },
    "body": {
      "text": "We hope you enjoyed your visit today. Would you rate it for us? It takes under a minute."
    },
    "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": "Review your visit",
        "flow_action": "navigate",
        "flow_action_payload": {
          "screen": "RATINGS"
        }
      }
    }
  }
}
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-post-visit-review.json

When to send it

Same day, after checkout

Two to three hours after the appointment ends is the sweet spot: the client is home, the visit is fresh, and they have not yet formed a story about it.

After a first visit

New clients decide whether to come back within days. A review request after visit one surfaces problems before you lose them silently.

After a staff change

When a new team member joins, send the flow for their appointments for the first month to benchmark their staff rating against the team.

After a refurbishment

Compare cleanliness and ambience ratings before and after a renovation or a move to measure whether the spend changed how clients feel.

How to customise this template

  • Replace YOUR_PLACE_ID in the review link with your Google Business Profile short link. Find it in your profile under "Ask for reviews" and paste the full https URL.
  • If you want to know which staff member the rating is about, include the appointment id in the flow_token and look the staff member up server-side. A static flow cannot show the name.
  • Swap "Cleanliness & ambience" for the third factor that matters most to you: "Treatment room comfort" for a spa, "Equipment" for a studio, "Waiting time" for a clinic.
  • Keep the testimonial OptIn separate from any marketing consent. Permission to quote someone is not permission to message them with offers.

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

  • Never show the Google link only to people who rated 4 or 5. Beyond breaking Google policy, some regions treat suppressing negative reviews as a deceptive practice.
  • Do not offer a discount or gift in exchange for a Google review. Incentivised reviews are also against Google policy, even when the review is honest.
  • EmbeddedLink with open_url needs Flow JSON 6.0 or newer. This template uses 7.2; do not downgrade the version when you edit it.
  • Publishing a testimonial with the client's full name or photo needs clear consent. The OptIn wording says first name only; stick to what they agreed to.

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

Google does not allow businesses to discourage or selectively solicit reviews from customers, and filtering unhappy clients away from the link is exactly that. Showing it to everyone keeps your profile compliant while the separate private ratings still tell you where to improve.
No. The EmbeddedLink opens the browser and the flow does not learn what happened next. The ratings, comment and testimonial consent are what come back in the nfm_reply response_json.
Check service_rating, staff_rating and ambience_rating in your webhook handler. If any is service_1, staff_2 or similar, notify a manager and reply in the chat within the hour, while the 24-hour window from their submission is still open.
service_rating, staff_rating and ambience_rating (item ids ending in 1 to 5), would_recommend (recommend_yes, recommend_maybe or recommend_no), review_comment (string) and testimonial_ok (boolean), plus your flow_token.

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.