WhatsApp Marketing Opt-In & Preferences Flow Template

A one-screen preference centre that asks which topics a contact wants, how often and at what time of day, then records an explicit, unticked opt-in to receive marketing messages from your business on WhatsApp, with a link to your privacy policy.

1 screen 4 fields returned Flow JSON 7.2 Sign up Online stores, Salons, Gyms, Restaurants

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

marketing-preferences.json Open in Flow Builder
{
  "version": "7.2",
  "screens": [
    {
      "id": "MESSAGE_PREFERENCES",
      "title": "Message preferences",
      "terminal": true,
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "Form",
            "name": "form_message_preferences",
            "children": [
              {
                "type": "TextHeading",
                "text": "What would you like to hear about?"
              },
              {
                "type": "TextBody",
                "text": "Choose your topics and how often we message you. We only send marketing messages if you tick the box below."
              },
              {
                "type": "CheckboxGroup",
                "name": "topics",
                "label": "Topics",
                "data-source": [
                  {
                    "id": "offers",
                    "title": "Offers and discounts"
                  },
                  {
                    "id": "new_services",
                    "title": "New services and products"
                  },
                  {
                    "id": "events",
                    "title": "Events and workshops"
                  },
                  {
                    "id": "tips",
                    "title": "Tips and how-to guides"
                  },
                  {
                    "id": "loyalty_rewards",
                    "title": "Loyalty rewards and points"
                  }
                ]
              },
              {
                "type": "RadioButtonsGroup",
                "name": "message_frequency",
                "label": "How often?",
                "data-source": [
                  {
                    "id": "weekly",
                    "title": "Up to once a week"
                  },
                  {
                    "id": "twice_monthly",
                    "title": "Twice a month"
                  },
                  {
                    "id": "monthly",
                    "title": "Once a month"
                  },
                  {
                    "id": "major_only",
                    "title": "Only big announcements"
                  }
                ],
                "required": true
              },
              {
                "type": "RadioButtonsGroup",
                "name": "preferred_time",
                "label": "Best time to message you",
                "data-source": [
                  {
                    "id": "morning",
                    "title": "Morning"
                  },
                  {
                    "id": "afternoon",
                    "title": "Afternoon"
                  },
                  {
                    "id": "evening",
                    "title": "Evening"
                  },
                  {
                    "id": "no_preference",
                    "title": "No preference"
                  }
                ]
              },
              {
                "type": "EmbeddedLink",
                "text": "Read our privacy policy",
                "on-click-action": {
                  "name": "open_url",
                  "url": "https://example.com/privacy"
                }
              },
              {
                "type": "OptIn",
                "name": "marketing_consent",
                "label": "Yes, I want to receive offers and updates from Your Business on WhatsApp. I can reply STOP at any time."
              },
              {
                "type": "TextCaption",
                "text": "Leaving the box unticked means we will not send you marketing messages. Order and booking updates are not affected."
              },
              {
                "type": "Footer",
                "label": "Save preferences",
                "on-click-action": {
                  "name": "complete",
                  "payload": {
                    "topics": "${form.topics}",
                    "message_frequency": "${form.message_frequency}",
                    "preferred_time": "${form.preferred_time}",
                    "marketing_consent": "${form.marketing_consent}"
                  }
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Raw JSON for scripts: curl -s https://whautomate.com/whatsapp-flow-templates/marketing-preferences.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 Sign up 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 marketing preferences & opt-in flow

Meta's WhatsApp Business Messaging Policy requires an opt-in before you send marketing messages, and it expects that opt-in to be clear: the person should understand they are agreeing to receive messages on WhatsApp, and from which business. A vague checkbox buried in a checkout page is a weak basis for a broadcast list. This flow records the opt-in inside WhatsApp itself, in the contact's own words and taps, with a timestamp you get from the webhook.

It also collects preferences that make the opt-in worth having. Topics tell you which segment a contact belongs to, so a customer who only wants event news does not get every discount blast. Frequency and preferred time of day give you a ceiling and a send window per contact. Contacts who get fewer, more relevant messages block and report less often, which protects your number's quality rating and messaging limits.

The consent checkbox is deliberately optional and unticked. A contact can submit their preferences and still say no, and your handler should treat anything other than an explicit true as no consent. That way the form never pressures anyone into opting in just to finish it.

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
topics
offers, new_services, events, tips, loyalty_rewards
CheckboxGroup MESSAGE_PREFERENCES No array of ids ["offers","events"]
message_frequency
weekly, twice_monthly, monthly, major_only
RadioButtonsGroup MESSAGE_PREFERENCES Yes item id "monthly"
preferred_time
morning, afternoon, evening, no_preference
RadioButtonsGroup MESSAGE_PREFERENCES No item id "evening"
marketing_consent OptIn MESSAGE_PREFERENCES 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 Marketing Preferences & Opt-In 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",
  "topics": [
    "offers",
    "events"
  ],
  "message_frequency": "monthly",
  "preferred_time": "evening",
  "marketing_consent": 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\",\"topics\":[\"offers\",\"events\"],\"message_frequency\":\"monthly\",\"preferred_time\":\"evening\",\"marketing_consent\":true}"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ]
}

Deploy with the WhatsApp Cloud API

Prefer code over WhatsApp Manager? Save the template as marketing-preferences.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": "marketing_preferences", "categories": ["SIGN_UP"]}'
# => {"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-marketing-preferences.json
{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "14155550123",
  "type": "interactive",
  "interactive": {
    "type": "flow",
    "header": {
      "type": "text",
      "text": "Choose what you hear from us"
    },
    "body": {
      "text": "Pick the updates you actually want and how often. You can change your mind at any time by replying STOP."
    },
    "footer": {
      "text": "You can opt out at any time"
    },
    "action": {
      "name": "flow",
      "parameters": {
        "flow_message_version": "3",
        "flow_token": "bk_8f2c41",
        "flow_id": "YOUR_FLOW_ID",
        "flow_cta": "Set my preferences",
        "flow_action": "navigate",
        "flow_action_payload": {
          "screen": "MESSAGE_PREFERENCES"
        }
      }
    }
  }
}
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-marketing-preferences.json

When to send it

After a first purchase or visit

Inside the 24-hour window after a service conversation, ask whether the customer would like offers and updates, instead of silently adding them to a broadcast list.

Before relaunching an old list

If numbers were collected on paper or at a till without a clear WhatsApp opt-in, send the form when each contact next messages you, and broadcast only to those who tick the box.

When someone replies "too many messages"

Offer the preference form instead of an all-or-nothing unsubscribe. Many contacts would rather drop to monthly than leave completely.

New branch or product line

When you add a service, let existing opted-in contacts add the new topic rather than assuming everyone wants to hear about it.

How to customise this template

  • Replace "Your Business" in the OptIn label with your actual business name as customers know it. The opt-in should name the business that will be messaging them.
  • Keep the topic ids aligned with the tags or segments you broadcast to, for example offers, events and tips. Then a submission can be turned into tags without a lookup table.
  • Point the EmbeddedLink at your real privacy policy, and make sure that page explains how you use WhatsApp numbers and how to opt out.
  • If you only send one kind of message, remove the topics CheckboxGroup and keep frequency and time. A single-topic list does not need a preference question.

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 pre-tick or require the marketing OptIn. Consent that cannot be refused is not meaningful, and a required checkbox forces people who only wanted to set preferences to either lie or abandon the form.
  • Store the evidence: keep the flow_token, the submission timestamp, the contact's number and the exact OptIn wording at the time. If you edit the label later, older consents were given against the old text.
  • Opt-outs must be honoured wherever they come from. A "STOP" typed in chat, a block, or an unticked box on a later submission should all remove the contact from marketing sends, whatever this form said before.
  • Frequency is a promise. If a contact chooses "Monthly" and receives three broadcasts that week, expect blocks and reports, which lower your number's quality rating.

Keep consent and contact data in one place

In Whautomate, import this flow into the built-in flow editor, click Publish and send it from the Team Inbox, an automation or a Flow-button template. Answers are saved on the client's profile, tags are added on submit, and automations can manage your suppression list so opted-out contacts stop receiving broadcasts.

  • Tags added automatically on submit
  • Suppression list for opt-outs
  • Every answer kept on the client profile

7-day free trial, no credit card required.

Frequently asked questions

It helps you collect a clear, recorded opt-in, which Meta requires before marketing messages, but it is not legal advice. Local privacy and marketing laws can add their own requirements, so check the rules for the countries you message and keep your privacy policy consistent with what the form says.
marketing_consent is an OptIn, so it arrives in response_json as a boolean. Treat only true as consent. The topics field returns an array of item ids such as ["offers", "events"], and message_frequency and preferred_time return single ids.
Outside the 24-hour window you can only send an approved message template, and the Flow button would sit on that template. Promotional templates to people who have not opted in are exactly what the policy is meant to prevent, so use this flow inside active conversations or with contacts you already have a service relationship with.
Remove them from marketing sends immediately and keep a record. In Whautomate, automations can add a contact to the suppression list, and Whautomate stops sending template messages, including broadcasts, to suppressed contacts.

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.