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.
| Key | Component | Screen | Required | Returns | Example |
|---|---|---|---|---|---|
service_ratingservice_5, service_4, service_3, service_2, service_1 |
RadioButtonsGroup | RATINGS | Yes | item id | "service_5" |
staff_ratingstaff_5, staff_4, staff_3, staff_2, staff_1 |
RadioButtonsGroup | RATINGS | Yes | item id | "staff_5" |
ambience_ratingambience_5, ambience_4, ambience_3, ambience_2, ambience_1 |
RadioButtonsGroup | RATINGS | Yes | item id | "ambience_4" |
would_recommendrecommend_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.
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.
Connect your number
Log in with Facebook and connect your WhatsApp number in a few minutes. No API keys or servers to set up.
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.
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.
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.
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.
{
"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
}
{
"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
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
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
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.
{
"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"
}
}
}
}
}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.jsonWhen 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.