Learn how to send WhatsApp messages using Zend.
WhatsApp requires template messages for business-initiated conversations. You cannot send free-form text messages.
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"
}
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"
  }
}
{
  "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"
        }
      ]
    }
  ]
}
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"
}
image - JPG, PNG, GIFdocument - PDF, DOC, XLSaudio - MP3, OGGvideo - MP4, 3GP{
  "buttons": [
    {
      "type": "url",
      "text": "Visit Website",
      "variable_name": "website_url"
    }
  ]
}
{
  "buttons": [
    {
      "type": "quick_reply",
      "text": "Yes, I'm interested"
    },
    {
      "type": "quick_reply", 
      "text": "No, thanks"
    }
  ]
}
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
}
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);
}
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"
}
{
  "statusCode": 400,
  "message": "WhatsApp requires template messages for business-initiated conversations. Please provide a template_id and template_params.",
  "error": "Bad Request"
}
{
  "statusCode": 400,
  "message": "Template rendering failed: Required variable 'customer_name' is missing",
  "error": "Bad Request"
}
{
  "statusCode": 400,
  "message": "Template 'marketing_promo' is not approved by WhatsApp. Please use an approved template.",
  "error": "Bad Request"
}
{
  "statusCode": 400,
  "message": "Recipient +233593152134 is not available on WhatsApp",
  "error": "Bad Request"
}
{
  "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"
        }
      ]
    }
  ]
}
{
  "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"
        }
      ]
    }
  ]
}
{
  "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"
        }
      ]
    }
  ]
}
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
}