Quick Reply Payload Mapping
Quick Reply Payload Mapping lets you attach a hidden, per-contact value to each quick-reply button in a WhatsApp Campaign. When a contact taps the button, Exotel returns that value to your chatbot or webhook as the button payload. The contact never sees it.
Use it when a button tap needs to carry a business key, such as a Ticket ID, Order ID or Customer ID, so the conversation that follows can be tied back to the right record.
How it works
- Your contact list includes a column with the key you want to pass, for example TicketId.
- While creating the campaign, you map that column to a quick-reply button.
- Every contact receives the same message with the same button labels. Only the hidden payload differs per contact.
- When a contact taps the button, the inbound message contains both the button label and that contact's mapped value.
- Your chatbot reads the payload, stores it in the session and continues the flow, for example a survey tagged with the Ticket ID.
Example
Contact | Button shown | Payload received on tap |
|---|---|---|
9198XXXXXX01 | Yes | TCK-48213 |
9198XXXXXX02 | Yes | TCK-48214 |
Before you begin
- You need an approved WhatsApp template that has at least one Quick Reply button.
- To send a different value to each contact, use a Dynamic List (CSV upload) that includes a column for the value.
- Each payload value can be at most 128 characters, which is Meta's limit.
Note: You don't need to enable anything. The Quick Reply Payload Mapping section appears automatically whenever the selected template has quick-reply buttons.
Prepare your contact list
Add one extra column to the CSV you upload as a Dynamic List, alongside your usual columns:
number | Name | TicketId |
|---|---|---|
919800000001 | Riya | TCK-48213 |
919800000002 | Arjun | TCK-48214 |
The column name can be anything. You'll select it from a dropdown in the next step.
Map a payload to a quick-reply button
- Go to Tools → Campaigns → WhatsApp and click Create Campaign.
- Fill in the campaign details, select your sender number and select your Dynamic List.
- Select a template that has quick-reply buttons.
- Map the Body variables (and header or URL-button variables, if any) as usual.
- Under Buttons, find the Quick Reply Payload Mapping section. Its helper text reads: "Map a list column per button. Sent as payload on tap; not shown on the button."
- Each quick-reply button is listed by its label, for example {{Yes}} or {{No}}. For each button you need:
- Open the Select CSV column dropdown and choose a column, for example TicketId. It's saved as @@TicketId and resolved separately for each contact at send time.
- Or type a fixed value in the field, for example survey_yes. The same value is sent for every contact.
- Leave any button you don't need blank. Blank buttons are valid and won't block campaign creation.
- (Optional) Click Send Test to send a test message. The test dialog shows the same payload fields so you can enter sample values.
- Schedule or launch the campaign.
Tip: For carousel templates, every card that has quick-reply buttons gets its own payload fields, which work the same way as top-level buttons.
Note: When you copy or edit a campaign, the saved payload mappings are restored automatically.
What your chatbot or webhook receives (for developers)
Outbound (what Exotel sends to WhatsApp)
For each mapped button, the template message includes a quick_reply button component with the resolved value:
JSON
{
"type": "button",
"sub_type": "quick_reply",
"index": "0",
"parameters": [
{ "type": "payload", "payload": "TCK-48213" }
]
}
index is the button's 0-based position in the template. Unmapped buttons are not included and use the platform default payload, which is typically the button text.
Inbound (when the contact taps the button)
JSON {
"whatsapp": {
"messages": [
{
"callback_type": "incoming_message",
"from": "+919800000001",
"to": "+919282210101",
"content": {
"type": "button",
"context": { "sid": "<sid of the campaign message>" },
"button": {
"payload": "TCK-48213",
"text": "Yes"
}
}
}
]
}
}
Field | Meaning |
|---|---|
content.type | Always button for a quick-reply tap |
content.button.payload | The value you mapped for this contact (for example, the Ticket ID) |
content.button.text | The button label the contact tapped |
content.context.sid | The SID of the original campaign message |
In your chatbot, read content.button.payload into a session variable to tag the rest of the conversation with it.
Validation rules
Situation | Result |
|---|---|
Template has no quick-reply buttons | The section is hidden |
Button left blank | Allowed; the default payload is sent |
Value longer than 128 characters | Rejected with: "Quick reply payload must be at most 128 characters" |
A column (@@…) is mapped while a Static List is selected | Blocked with: "Templates with dynamic variables are only supported with dynamic lists. Please switch to a dynamic list or choose a template without variables." |
URL, Phone Number, Copy Code buttons | Unchanged by this feature |
FAQs and troubleshooting
Will the contact see the payload? No. The contact sees only the approved button label. The payload is delivered only in the inbound webhook.
Can I change the button label? No. Button labels come from the Meta-approved template. This feature controls only the hidden payload.
Is mapping mandatory? No. The fields have no red asterisk (*). Map only the buttons you need.
My chatbot receives the button text instead of my value. Why? Check that:
- The button was mapped in the campaign. Open the campaign with Copy or Edit to confirm the mapping.
- The mapped CSV column has a value for that contact. An empty cell means there's no custom payload.
- Your bot reads content.button.payload, not content.button.text.
I get a "dynamic lists" error when creating the campaign. You've mapped a CSV column while a Static List is selected. Switch to a Dynamic List with that column, or enter a fixed value instead.
My value is longer than 128 characters. Meta caps the payload at 128 characters, and Exotel rejects longer values instead of cutting them short. Use a shorter key, such as an ID, and look up the full details in your own system.
Does this work for regular chat (session) messages? No. It applies only to template messages sent through WhatsApp Campaigns.
Can I use different columns for different buttons? Yes. Map each button independently, for example Yes → TicketId and No → CustomerId.
Related articles
- WhatsApp Campaign
- Manage Lists and Contacts