Skip to main content

WhatsApp Business API

Send rich media messages, interactive buttons, and automated chatbots on WhatsApp Business Platform. Official API partner with 99.9% uptime.

🚀 Quick Start​

curl -X POST https://api.afriroute.ai/api/v1/whatsapp/messages \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+251911234567",
"type": "template",
"template": {
"name": "welcome_message",
"language": "en"
}
}'

📤 Message Types​

1. Template Messages​

Pre-approved messages for outbound communication (required for first message).

await fetch('https://api.afriroute.ai/api/v1/whatsapp/messages', {
method: 'POST',
headers: {
'Authorization': 'Bearer $AFRIROUTE_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: '+251911234567',
type: 'template',
template: {
name: 'order_confirmation',
language: 'en',
components: [
{
type: 'body',
parameters: [
{ type: 'text', text: 'John' },
{ type: 'text', text: '#12345' }
]
}
]
}
})
});

2. Text Messages​

Simple text messages (within 24-hour window after user reply).

{
"to": "+251911234567",
"type": "text",
"text": {
"body": "Thanks for your order! Your tracking number is #12345.",
"preview_url": true
}
}

3. Media Messages​

Images, videos, documents, and audio files.

{
"to": "+251911234567",
"type": "image",
"image": {
"link": "https://example.com/product.jpg",
"caption": "Check out this new product!"
}
}

Supported types: image, video, document, audio

4. Interactive Messages​

Buttons and lists for rich engagement.

Quick Reply Buttons​

{
"to": "+251911234567",
"type": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "How can we help you today?"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "support",
"title": "Contact Support"
}
},
{
"type": "reply",
"reply": {
"id": "track",
"title": "Track Order"
}
}
]
}
}
}

List Messages​

{
"to": "+251911234567",
"type": "interactive",
"interactive": {
"type": "list",
"body": {
"text": "Choose a department:"
},
"action": {
"button": "View Options",
"sections": [
{
"title": "Departments",
"rows": [
{"id": "sales", "title": "Sales"},
{"id": "support", "title": "Support"},
{"id": "billing", "title": "Billing"}
]
}
]
}
}
}

📥 Receiving Messages (Webhooks)​

Configure webhooks to receive incoming messages.

app.post('/webhooks/whatsapp', async (req, res) => {
const { entry } = req.body;

for (const change of entry[0].changes) {
const message = change.value.messages?.[0];

if (message) {
const { from, type, text } = message;

if (type === 'text') {
console.log(`Message from ${from}: ${text.body}`);

// Send auto-reply
await sendWhatsAppMessage({
to: from,
type: 'text',
text: { body: 'Thanks for your message!' }
});
} else if (type === 'interactive') {
const buttonId = message.interactive.button_reply?.id;
console.log(`Button clicked: ${buttonId}`);
}
}
}

res.sendStatus(200);
});

🔔 Webhook Events​

{
"object": "whatsapp_business_account",
"entry": [{
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "251911234567",
"phone_number_id": "123456789"
},
"messages": [{
"from": "251922222222",
"id": "wamid.abc123",
"timestamp": "1710500000",
"type": "text",
"text": {
"body": "Hello!"
}
}]
}
}]
}]
}

📱 Message Status​

Track delivery, read receipts, and failures.

{
"object": "whatsapp_business_account",
"entry": [{
"changes": [{
"value": {
"statuses": [{
"id": "wamid.abc123",
"status": "delivered",
"timestamp": "1710500005",
"recipient_id": "251911234567"
}]
}
}]
}]
}

Status values: sent, delivered, read, failed

🎨 Template Management​

Create Template​

Templates must be approved by WhatsApp before use.

curl -X POST https://api.afriroute.ai/api/v1/whatsapp/templates \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-d '{
"name": "order_confirmation",
"language": "en",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, your order {{2}} has been confirmed!"
}
]
}'

💡 Best Practices​

Message Templates​

  • Use clear variable placeholders - {{1}}, {{2}} for dynamic content
  • Keep templates under 1024 characters for better approval rates
  • Avoid promotional language in utility templates
  • Test templates before submission using sandbox number

24-Hour Window​

  • First message must be template - user hasn't messaged you yet
  • After user replies, use any message type for 24 hours
  • Window resets with each user message
  • Use templates to restart conversations after window expires

Interactive Messages​

  • Limit to 3 buttons for quick replies
  • Use lists for 4+ options (up to 10 items)
  • Keep button text under 20 characters
  • Make IDs descriptive for webhook handling

Performance​

  • Implement webhook retry logic (exponential backoff)
  • Validate webhook signatures for security
  • Cache template data to reduce API calls
  • Use message batching for high-volume sends

Compliance​

  • Get user opt-in before sending messages
  • Provide opt-out instructions in templates
  • Respect business hours (9 AM - 9 PM local time)
  • Follow Meta's Commerce Policy

🔐 Security​

const crypto = require('crypto');

function verifyWebhook(req) {
const signature = req.headers['x-hub-signature-256'];
const payload = JSON.stringify(req.body);

const expectedSignature = 'sha256=' +
crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(payload)
.digest('hex');

return signature === expectedSignature;
}

⚠️ Error Handling​

try {
await sendWhatsAppMessage(messageData);
} catch (error) {
if (error.code === 131051) {
console.error('User has not opted in to receive messages');
} else if (error.code === 130472) {
console.error('User phone number is not a WhatsApp user');
} else if (error.code === 131026) {
console.error('Message template not approved');
}
}

Common Error Codes​

CodeDescriptionSolution
130472Not a WhatsApp userVerify phone number
131026Template not approvedSubmit for review
131051User not opted inGet explicit consent
133004Message undeliverableCheck number format

💰 Pricing​

Conversation TypePriceDescription
User-initiated$0.02User messages you first
Business-initiated$0.05You send template message
Service$0.01Utility messages (OTP, etc.)

View detailed pricing →

📊 Analytics​

Track message performance in the dashboard:

  • ✅ Delivery rates
  • 📖 Read rates
  • ⏱️ Response times
  • 💬 Conversation volumes
  • 🔄 Template approval status

🛠️ SDKs​

// JavaScript/Node.js
const afriroute = require('@afriroute/sdk');
const whatsapp = new afriroute.WhatsApp('$AFRIROUTE_API_KEY');

await whatsapp.sendTemplate({
to: '+251911234567',
template: 'order_confirmation',
variables: ['John', '#12345']
});
# Python
from afriroute import WhatsApp

whatsapp = WhatsApp(api_key='$AFRIROUTE_API_KEY')
whatsapp.send_template(
to='+251911234567',
template='order_confirmation',
variables=['John', '#12345']
)

Need help? Contact Support → | View Code Examples →