Skip to main content

Interactive Message Patterns

Interactive messages — quick-reply buttons, list pickers, and call-to-action buttons — turn open-ended chat into tap-to-respond flows. They reduce typing errors and speed up resolution.

🚀 Quick Start​

curl -X POST https://api.afriroute.ai/api/v1/whatsapp/send \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+254712345678",
"type": "interactive",
"interactive": {
"type": "button",
"body": "How can we help today?",
"buttons": [
{"id": "track", "title": "Track order"},
{"id": "support", "title": "Talk to agent"}
]
}
}'

🧩 Choosing the Right Control​

ControlMax optionsBest for
Quick-reply buttons3Yes/no, top 2–3 actions
List message10 (sections)Menus, categories, FAQs
CTA URL button1Open a link, pay, view docs

Use buttons for the primary path and a list when there are too many options for buttons.

📋 List Messages​

await sendWhatsApp({
to: '+234803000000',
type: 'interactive',
interactive: {
type: 'list',
body: 'Pick a service',
button: 'View services',
sections: [{
title: 'Banking',
rows: [
{ id: 'balance', title: 'Check balance' },
{ id: 'transfer', title: 'Send money' },
{ id: 'statement', title: 'Statement' }
]
}]
}
});

🔗 CTA Buttons​

send_whatsapp(
to='+254712345678',
type='interactive',
interactive={
'type': 'cta_url',
'body': 'Your invoice is ready.',
'action': {'name': 'View invoice', 'url': 'https://pay.example.com/inv/123'}
}
)

🎯 UX Patterns​

  • Lead with the common path. Put the 1–2 most-likely actions as buttons.
  • Label by outcome, not jargon. "Track order" beats "Logistics".
  • Keep titles short. Buttons truncate around 20 characters.
  • Always offer an escape. Include "Talk to agent" or "Main menu".
  • Echo the choice. Confirm the selection before acting on it.

🔁 Handling Responses​

Replies arrive on your webhook with the option id you set.

app.post('/webhooks/whatsapp', (req, res) => {
const reply = req.body.interactive?.button_reply || req.body.interactive?.list_reply;
if (reply?.id === 'support') routeToHuman(req.body.from);
res.sendStatus(200);
});

💡 Best Practices​

  • Never exceed the option limits — extra options are dropped silently.
  • Use stable IDs, not titles, to branch your logic.
  • Avoid deep button chains — collapse to a list at 4+ choices.
  • Provide a text fallback for clients that can't render interactive content.
  • Confirm destructive actions with an explicit button.

Last Updated: May 2026