WhatsApp Messaging Guide

Learn how to send WhatsApp messages using the Zend.

Important: WhatsApp Template Requirement

WhatsApp requires template messages for business-initiated conversations. You cannot send free-form text messages.

Basic WhatsApp Template Message

Send a WhatsApp message using a template:

POST /messages
{
  "to": "+233593152134",
  "body": "Welcome to our service!",
  "preferred_channels": ["whatsapp"],
  "template_id": "6884c5d09c14b2b164500d58",
  "template_params": {
    "code": "123456",
    "verification_url": "https://yourapp.com/verify?code=123456"
  }
}

Response:

{
  "id": "6884da240f0e633b7b979bff",
  "status": "pending",
  "estimated_cost": 0.008,
  "message": "Message queued for processing"
}

WhatsApp Template with Button

Send a WhatsApp message with interactive buttons:

{
  "to": "+233593152134",
  "body": "Your verification code is ready",
  "preferred_channels": ["whatsapp"],
  "template_id": "12345678912345",
  "template_params": {
    "code": "123456",
    "verification_url": "https://yourapp.com/verify?code=123456"
  }
}

Template Structure Required:

{
  "name": "otp_verification",
  "variables": [
    {"name": "code", "type": "text", "required": true},
    {"name": "verification_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "whatsapp",
      "content": "Verification Code\n\nYour verification code is:\n{{code}}\n\nClick the button below to verify your account.",
      "header": "Verification Code",
      "footer": "Secure verification",
      "buttons": [
        {
          "type": "url",
          "text": "Verify Account",
          "variable_name": "verification_url"
        }
      ]
    }
  ]
}

WhatsApp with Media

Send WhatsApp message with image, document, or video:

{
  "to": "+233593152134",
  "body": "Check out our latest product catalog!",
  "preferred_channels": ["whatsapp"],
  "template_id": "12345678912345",
  "template_params": {
    "product_name": "Premium Widget",
    "price": "$99.99"
  },
  "media_url": "https://example.com/catalog.pdf",
  "media_type": "document"
}

Supported Media Types:

  • image - JPG, PNG, GIF
  • document - PDF, DOC, XLS
  • audio - MP3, OGG
  • video - MP4, 3GP

WhatsApp Button Types

URL Buttons

{
  "buttons": [
    {
      "type": "url",
      "text": "Visit Website",
      "variable_name": "website_url"
    }
  ]
}

Quick Reply Buttons

{
  "buttons": [
    {
      "type": "quick_reply",
      "text": "Yes, I'm interested"
    },
    {
      "type": "quick_reply", 
      "text": "No, thanks"
    }
  ]
}

WhatsApp with Fallback

Send WhatsApp with automatic fallback to SMS:

{
  "to": "+233593152134",
  "body": "Important notification: Your order has been shipped!",
  "preferred_channels": ["whatsapp", "sms"],
  "template_id": "12345678912345",
  "template_params": {
    "order_number": "ORD-2024-001",
    "tracking_url": "https://track.com/ORD-2024-001"
  },
  "fallback_enabled": true
}

WhatsApp Message Limits

  • Text Limit: 1024 characters
  • Header Limit: 60 characters
  • Footer Limit: 60 characters
  • Button Text: 25 characters per button
  • Rate Limit: 50 messages per minute
  • Cost: $0.008 per message

WhatsApp Best Practices

1. Template Design

  • Keep content concise and clear
  • Use emojis sparingly
  • Test with different screen sizes

2. Button Strategy

  • Limit to 3 buttons maximum
  • Use clear, action-oriented text
  • Ensure URLs are mobile-friendly

3. Media Guidelines

  • Optimize images for mobile
  • Keep file sizes under 16MB
  • Use HTTPS URLs only

4. Error Handling

try {
  const response = await fetch('/messages', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      to: '+233593152134',
      preferred_channels: ['whatsapp'],
      template_id: '12345678912345',
      template_params: {
        customer_name: 'John'
      }
    })
  });
  
  if (!response.ok) {
    const error = await response.json();
    if (error.message.includes('template')) {
      console.error('Template error:', error.message);
    } else {
      console.error('WhatsApp error:', error.message);
    }
  }
} catch (error) {
  console.error('Network error:', error);
}

WhatsApp Status Tracking

Check Message Status

GET /messages/{id}

Response:

{
  "id": "6884da240f0e633b7b979bff",
  "status": "delivered",
  "channel_used": "whatsapp",
  "to": "+233593152134",
  "body": "Your verification code is: 123456",
  "total_cost": 0.008,
  "delivery_attempts": [
    {
      "channel": "whatsapp",
      "status": "delivered",
      "attempted_at": "2024-01-15T10:30:00Z",
      "cost": 0.008
    }
  ],
  "created_at": "2024-01-15T10:29:55Z",
  "sent_at": "2024-01-15T10:30:00Z",
  "delivered_at": "2024-01-15T10:30:05Z"
}

Common WhatsApp Errors

Template Required

{
  "statusCode": 400,
  "message": "WhatsApp requires template messages for business-initiated conversations. Please provide a template_id and template_params.",
  "error": "Bad Request"
}

Invalid Template

{
  "statusCode": 400,
  "message": "Template rendering failed: Required variable 'customer_name' is missing",
  "error": "Bad Request"
}

Template Not Approved

{
  "statusCode": 400,
  "message": "Template 'marketing_promo' is not approved by WhatsApp. Please use an approved template.",
  "error": "Bad Request"
}

Number Not on WhatsApp

{
  "statusCode": 400,
  "message": "Recipient +233593152134 is not available on WhatsApp",
  "error": "Bad Request"
}

WhatsApp Templates

Welcome Template

{
  "name": "welcome_message",
  "description": "Welcome message for new customers",
  "category": "transactional",
  "variables": [
    {"name": "customer_name", "type": "text", "required": true},
    {"name": "website_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "whatsapp",
      "content": "Welcome {{customer_name}}! 🎉\n\nThank you for joining our platform. We're excited to have you on board!\n\nGet started by exploring our features.",
      "header": "Welcome!",
      "footer": "We're here to help",
      "buttons": [
        {
          "type": "url",
          "text": "Get Started",
          "variable_name": "website_url"
        }
      ]
    }
  ]
}

Order Confirmation Template

{
  "name": "order_confirmation",
  "description": "Order confirmation with tracking",
  "category": "transactional",
  "variables": [
    {"name": "customer_name", "type": "text", "required": true},
    {"name": "order_number", "type": "text", "required": true},
    {"name": "tracking_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "whatsapp",
      "content": "Hi {{customer_name}}! ✅\n\nYour order #{{order_number}} has been confirmed and is being prepared for shipment.\n\nWe'll notify you when it ships!",
      "header": "Order Confirmed",
      "footer": "Thank you for your purchase",
      "buttons": [
        {
          "type": "url",
          "text": "Track Order",
          "variable_name": "tracking_url"
        }
      ]
    }
  ]
}

Appointment Reminder Template

{
  "name": "appointment_reminder",
  "description": "Appointment reminder with actions",
  "category": "notification",
  "variables": [
    {"name": "customer_name", "type": "text", "required": true},
    {"name": "appointment_date", "type": "text", "required": true},
    {"name": "appointment_time", "type": "text", "required": true},
    {"name": "reschedule_url", "type": "url", "required": true}
  ],
  "channel_variants": [
    {
      "channel": "whatsapp",
      "content": "Hi {{customer_name}}! 📅\n\nReminder: You have an appointment tomorrow at {{appointment_time}}.\n\nPlease arrive 10 minutes early.",
      "header": "Appointment Reminder",
      "footer": "See you soon!",
      "buttons": [
        {
          "type": "url",
          "text": "Reschedule",
          "variable_name": "reschedule_url"
        },
        {
          "type": "quick_reply",
          "text": "Confirm"
        },
        {
          "type": "quick_reply",
          "text": "Cancel"
        }
      ]
    }
  ]
}

WhatsApp Webhooks

Receive real-time delivery status updates:

{
  "to": "+233593152134",
  "body": "Your order has been shipped!",
  "preferred_channels": ["whatsapp"],
  "template_id": "12345678912345",
  "template_params": {
    "order_number": "ORD-2024-001"
  },
  "webhook_url": "https://yourapp.com/webhooks/message-status"
}

Webhook Payload:

{
  "message_id": "6884da240f0e633b7b979bff",
  "status": "delivered",
  "channel": "whatsapp",
  "recipient": "+233593152134",
  "timestamp": "2024-01-15T10:30:05Z",
  "cost": 0.008
}