Why WhatsApp Business API matters
With over 2 billion users worldwide, WhatsApp is the most popular messaging app on the planet. For businesses, especially in Latin America, Europe, and Asia, WhatsApp is often the primary channel customers use to reach out.
The WhatsApp Business API lets you send and receive messages programmatically, enabling automated customer support, order notifications, and conversational commerce.
Getting started
Prerequisites
- A Facebook Business Manager account
- A verified business phone number
- A Meta Business account with WhatsApp Business API access
- A webhook endpoint with SSL
Choosing a provider
You have two options:
Direct from Meta: Use the WhatsApp Cloud API directly. This is the cheapest option but requires more development work.
Through a BSP (Business Solution Provider): Use a provider like Twilio, MessageBird, or 360dialog. They handle the infrastructure and provide simpler APIs. I usually recommend Twilio for most projects.
Setting up with Twilio
Step 1: Create a Twilio account
Sign up at twilio.com and navigate to the WhatsApp Business section. You’ll need to:
- Submit your business for verification
- Link your Facebook Business Manager
- Get a WhatsApp Business phone number
Step 2: Configure webhooks
WhatsApp needs a webhook to receive incoming messages. Set up an endpoint on your server:
import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.urlencoded({ extended: false }));
// Verify webhook
app.get('/webhook', (req, res) => {
const mode = req.query['hub.mode'];
const token = req.query['hub.verify_token'];
const challenge = req.query['hub.challenge'];
if (mode === 'subscribe' && token === process.env.VERIFY_TOKEN) {
res.status(200).send(challenge);
} else {
res.sendStatus(403);
}
});
// Receive messages
app.post('/webhook', (req, res) => {
const body = req.body;
if (body.object) {
body.entry.forEach((entry) => {
const changes = entry.changes;
changes.forEach((change) => {
if (change.field === 'messages') {
const message = change.value.messages?.[0];
if (message) {
handleIncomingMessage(message);
}
}
});
});
res.status(200).send('EVENT_RECEIVED');
} else {
res.sendStatus(404);
}
});
function handleIncomingMessage(message) {
const from = message.from;
const type = message.type;
if (type === 'text') {
const text = message.text.body;
console.log(`Message from ${from}: ${text}`);
// Process the message and send a response
}
}
app.listen(3000, () => console.log('Webhook server running on port 3000'));
Step 3: Send messages
import twilio from 'twilio';
const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
async function sendMessage(to, body) {
const message = await client.messages.create({
from: 'whatsapp:+14155238886',
to: `whatsapp:${to}`,
body: body,
});
return message;
}
Message templates
WhatsApp requires pre-approved message templates for business-initiated conversations. You can’t just send any message to a user who hasn’t messaged you first.
Creating a template
{
"name": "order_confirmation",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, your order #{{2}} has been confirmed and will be shipped to {{3}}. Expected delivery: {{4}}."
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Track Order"
},
{
"type": "QUICK_REPLY",
"text": "Contact Support"
}
]
}
]
}
Submit this through the Twilio console or Meta Business Manager. Approval typically takes 24-48 hours.
Building a conversational flow
For anything beyond simple notifications, you’ll want a conversational flow. Here’s a pattern I use:
const conversations = new Map();
async function handleMessage(from, message) {
const session = conversations.get(from) || { state: 'initial', data: {} };
switch (session.state) {
case 'initial':
await sendMessage(from,
"Welcome to PrimeRealty! Are you looking to:\n\n1. Buy a property\n2. Rent a property\n3. Speak to an agent");
session.state = 'awaiting_choice';
break;
case 'awaiting_choice':
if (message.text.body === '1') {
session.data.intent = 'buy';
await sendMessage(from, "What's your budget range?");
session.state = 'awaiting_budget';
} else if (message.text.body === '3') {
await sendMessage(from, "I'll connect you with an agent right away.");
await notifyAgent(from);
session.state = 'initial';
}
break;
case 'awaiting_budget':
session.data.budget = message.text.body;
await sendMessage(from, "What area are you interested in?");
session.state = 'awaiting_location';
break;
case 'awaiting_location':
session.data.location = message.text.body;
await sendMessage(from,
`Great! I have properties in ${session.data.location} within your budget of ${session.data.budget}. An agent will send you listings shortly.`);
await syncToCRM(from, session.data);
session.state = 'initial';
break;
}
conversations.set(from, session);
}
Rate limits and best practices
- Business-initiated messages: Limited to 1000 conversations per 24 hours per number
- User-initiated conversations: No limit, but you must respond within 24 hours of the user’s last message
- Template messages: No rate limit, but each template must be approved
- Media: Images, documents, and audio supported up to 16MB
Security considerations
- Verify webhook signatures: Always verify that incoming webhooks are from WhatsApp/Meta
- Encrypt sensitive data: Don’t store phone numbers or message content in plain text
- Respect opt-outs: Users can block your number — handle this gracefully
- Follow WhatsApp policies: Don’t send spam. WhatsApp will ban your account.
Conclusion
The WhatsApp Business API opens up powerful automation possibilities for customer communication. The setup is non-trivial, but once you have the infrastructure in place, you can build sophisticated conversational experiences that meet your customers where they already are.