About this callback request flow
Some conversations do not fit in chat: a treatment plan with medical history, a mortgage with several options, a complaint that needs a human voice. When a customer types "can someone call me?", the useful reply is not "sure, when?" but a form that captures when, about what and in which language, so the call is booked with the right person the first time.
Everything sits on one screen because callback requests are short by nature and every extra tap lowers completion. The topic radio routes the call to a team, the DatePicker and time window give a slot to aim for, the language Dropdown matters for multilingual teams, and the urgency radio lets you pull same-day calls to the top of the queue. A TextArea with a 300-character limit keeps the note brief.
The flow deliberately has no phone number field. The request arrives from the customer's WhatsApp number, which is the number you will call. If someone wants a call on a different line, they can say so in the note.
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 |
|---|---|---|---|---|---|
call_topictopic_new_enquiry, topic_existing_booking, topic_billing, topic_complaint, topic_other |
RadioButtonsGroup | CALLBACK | Yes | item id | "topic_existing_booking" |
callback_date |
DatePicker | CALLBACK | Yes | YYYY-MM-DD | "2026-10-08" |
time_windowwindow_morning, window_lunch, window_afternoon, window_evening |
RadioButtonsGroup | CALLBACK | Yes | item id | "window_lunch" |
call_languagelang_english, lang_spanish, lang_arabic, lang_french, lang_portuguese |
Dropdown | CALLBACK | Yes | item id | "lang_spanish" |
urgencyurgency_today, urgency_this_week, urgency_no_rush |
RadioButtonsGroup | CALLBACK | Yes | item id | "urgency_this_week" |
callback_note |
TextArea | CALLBACK | No | string | "Want to move my treatment plan to fortnightly sessions." |
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 Callback 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.
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",
"call_topic": "topic_existing_booking",
"callback_date": "2026-10-08",
"time_window": "window_lunch",
"call_language": "lang_spanish",
"urgency": "urgency_this_week",
"callback_note": "Want to move my treatment plan to fortnightly sessions."
}
{
"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\",\"call_topic\":\"topic_existing_booking\",\"callback_date\":\"2026-10-08\",\"time_window\":\"window_lunch\",\"call_language\":\"lang_spanish\",\"urgency\":\"urgency_this_week\",\"callback_note\":\"Want to move my treatment plan to fortnightly sessions.\"}"
}
}
}
]
}
}
]
}
]
}
Deploy with the WhatsApp Cloud API
Prefer code over WhatsApp Manager? Save the template as callback-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
curl -X POST 'https://graph.facebook.com/v23.0/{WABA_ID}/flows' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"name": "callback_request", "categories": ["CONTACT_US"]}'
# => {"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": "Prefer to talk it through?"
},
"body": {
"text": "Choose a day and time that suits you and tell us what the call is about. The right person will ring you then."
},
"footer": {
"text": "We call from our main business line"
},
"action": {
"name": "flow",
"parameters": {
"flow_message_version": "3",
"flow_token": "bk_8f2c41",
"flow_id": "YOUR_FLOW_ID",
"flow_cta": "Request a call",
"flow_action": "navigate",
"flow_action_payload": {
"screen": "CALLBACK"
}
}
}
}
}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-callback-request.jsonWhen to send it
"Call me" keywords
Trigger the flow when a message contains "call me", "phone" or "ring", and let the customer choose the slot instead of waiting for an agent to negotiate one.
Outside business hours
When messages arrive after hours, reply with the flow so the customer leaves with a scheduled callback rather than an away message.
Complex chat threads
Agents can send it manually when a chat has gone back and forth more than a few times and a two-minute call would settle it.
After a missed inbound call
If your phone system logs missed calls from numbers you already talk to on WhatsApp, follow up with the flow so the customer picks a time that works.
How to customise this template
- Map each topic id to a team or queue in your webhook, for example topic_billing to accounts and topic_new_enquiry to sales. Keep ids stable so routing rules do not break.
- Trim the language list to the languages your team actually speaks. Offering a language nobody can cover creates a worse experience than not offering it.
- Change the time windows to your real call-centre hours and time zone, and state the zone in the TextBody if you serve customers across regions.
- If you do not triage by urgency, delete that radio. If you do, make sure "Today" callbacks are actually monitored, or change the option to "As soon as possible".
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
- The DatePicker lets customers pick weekends and holidays unless your team works them. Handle closed days in the webhook and suggest the next open day in your confirmation.
- Time windows mean nothing without a time zone. Store the customer's window alongside your business zone, and do not convert it through a date library that assumes UTC.
- Do not promise an exact time on the flow. Say "within your chosen window" so a busy queue does not turn every callback into a broken promise.
- Send a confirmation message after submission. Without one, customers are not sure the request went through and message again, creating duplicate callbacks.
Turn submissions into conversations your team can close
In Whautomate, import this flow into the built-in flow editor, adjust it with drag and drop and click Publish. Send it from any open chat in the Team Inbox, from an automation, or as a broadcast with a Flow-button template. Each submission is saved as a response, creates or updates the client, and can trigger an automation that tags the lead, assigns the chat and notifies the right person.
- Build and publish in the app, no JSON or API calls
- Send from the Team Inbox, automations or broadcasts
- Submissions notify, tag and assign automatically
7-day free trial, no credit card required.