WhatsApp Callback Request Flow Template

A single-screen flow that lets a customer ask for a phone call on their terms: what it is about, which day, which time window, which language and how urgent it is, plus a short note. Your call team gets a queue they can schedule, not a list of "please call me" messages.

1 screen 6 fields returned Flow JSON 7.2 Contact us Clinics, Consultants, Insurance and finance, Real estate, Education

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

callback-request.json Open in Flow Builder
{
  "version": "7.2",
  "screens": [
    {
      "id": "CALLBACK",
      "title": "Request a callback",
      "terminal": true,
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_callback",
            "children": [
              {
                "type": "TextHeading",
                "text": "When should we call you?"
              },
              {
                "type": "TextBody",
                "text": "We will call the number you are messaging from, within the time window you choose."
              },
              {
                "type": "RadioButtonsGroup",
                "name": "call_topic",
                "label": "What is the call about?",
                "data-source": [
                  {
                    "id": "topic_new_enquiry",
                    "title": "New enquiry"
                  },
                  {
                    "id": "topic_existing_booking",
                    "title": "An existing booking"
                  },
                  {
                    "id": "topic_billing",
                    "title": "Billing or payments"
                  },
                  {
                    "id": "topic_complaint",
                    "title": "A problem or complaint"
                  },
                  {
                    "id": "topic_other",
                    "title": "Something else"
                  }
                ],
                "required": true
              },
              {
                "type": "DatePicker",
                "name": "callback_date",
                "label": "Best day for the call",
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "time_window",
                "label": "Best time",
                "data-source": [
                  {
                    "id": "window_morning",
                    "title": "Morning (9am - 12pm)"
                  },
                  {
                    "id": "window_lunch",
                    "title": "Lunchtime (12pm - 2pm)"
                  },
                  {
                    "id": "window_afternoon",
                    "title": "Afternoon (2pm - 5pm)"
                  },
                  {
                    "id": "window_evening",
                    "title": "Early evening (5pm - 7pm)"
                  }
                ],
                "required": true
              },
              {
                "type": "Dropdown",
                "name": "call_language",
                "label": "Language",
                "data-source": [
                  {
                    "id": "lang_english",
                    "title": "English"
                  },
                  {
                    "id": "lang_spanish",
                    "title": "Espanol"
                  },
                  {
                    "id": "lang_arabic",
                    "title": "Arabic"
                  },
                  {
                    "id": "lang_french",
                    "title": "Francais"
                  },
                  {
                    "id": "lang_portuguese",
                    "title": "Portugues"
                  }
                ],
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "urgency",
                "label": "How urgent is it?",
                "data-source": [
                  {
                    "id": "urgency_today",
                    "title": "Today if possible"
                  },
                  {
                    "id": "urgency_this_week",
                    "title": "This week"
                  },
                  {
                    "id": "urgency_no_rush",
                    "title": "No rush"
                  }
                ],
                "required": true
              },
              {
                "type": "TextArea",
                "name": "callback_note",
                "label": "Short note",
                "helper-text": "Anything that helps us prepare for the call",
                "max-length": 300
              },
              {
                "type": "Footer",
                "label": "Request callback",
                "on-click-action": {
                  "name": "complete",
                  "payload": {
                    "call_topic": "${form.call_topic}",
                    "callback_date": "${form.callback_date}",
                    "time_window": "${form.time_window}",
                    "call_language": "${form.call_language}",
                    "urgency": "${form.urgency}",
                    "callback_note": "${form.callback_note}"
                  }
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Raw JSON for scripts: curl -s https://whautomate.com/whatsapp-flow-templates/callback-request.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 Contact us 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 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.

KeyComponentScreenRequiredReturnsExample
call_topic
topic_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_window
window_morning, window_lunch, window_afternoon, window_evening
RadioButtonsGroup CALLBACK Yes item id "window_lunch"
call_language
lang_english, lang_spanish, lang_arabic, lang_french, lang_portuguese
Dropdown CALLBACK Yes item id "lang_spanish"
urgency
urgency_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.

No developer needed

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.

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",
  "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."
}
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\",\"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

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": "callback_request", "categories": ["CONTACT_US"]}'
# => {"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-callback-request.json
{
  "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"
        }
      }
    }
  }
}
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-callback-request.json

When 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.

Frequently asked questions

Not as a static flow. Offering real free slots requires a data_exchange endpoint that returns availability for the chosen date. This template captures a day and a window, which is enough for most call teams to schedule manually.
A callback request has few fields and a clear purpose. One screen means one tap to submit, which keeps completion high on mobile. Multi-screen flows make sense when the second half depends on context the first half provides.
CONTACT_US fits best, since the customer is asking to be contacted rather than signing up or booking a service. The category is informational and does not change how the flow behaves.
An nfm_reply message whose response_json holds flow_token, call_topic, callback_date as YYYY-MM-DD, time_window, call_language, urgency and callback_note. The customer's number is in messages[0].from.

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.