WhatsApp Cloud API PHP is a lightweight Composer package that wraps Meta’s WhatsApp Cloud API into a clean, modern PHP interface. In other words, instead of writing raw cURL requests and parsing JSON responses yourself, you install one package and call methods like sendText(), sendImage(), and sendTemplate().
Additionally, this package has zero external dependencies — it uses only PHP’s built-in cURL and JSON extensions. As a result, it adds no bloat to your project and introduces no transitive dependency conflicts. The entire library is a single Composer require away.
Furthermore, the package is open source under the MIT license and available on both GitHub and Packagist.
What Is WhatsApp Cloud API PHP?
WhatsApp Cloud API PHP is a Composer package that handles authentication, request formatting, error parsing, and webhook verification for Meta’s WhatsApp Business Platform. Specifically, it supports every message type the Cloud API offers: text, templates, images, documents, videos, audio, locations, contacts, and stickers.
Moreover, the package includes full webhook support with HMAC-SHA256 signature validation. Consequently, you can both send and receive WhatsApp messages from a single library without cobbling together multiple dependencies.
Requirements
Before installing, make sure your environment meets these requirements:
- PHP 8.4 or higher — the package uses modern PHP features like named parameters and readonly properties.
- ext-curl — for HTTP requests to Meta’s API endpoints.
- ext-json — for encoding and decoding API payloads.
In addition, you need a Meta Business account with WhatsApp Cloud API access. Meta provides a free tier that includes 1,000 conversations per month at no cost.
Installation
Install the package via Composer:
composer require renzojohnson/whatsapp-cloud-api
After that, Composer autoloads the classes automatically. No manual file includes or bootstrap scripts are required.
Quick Start
The following example sends a text message in three lines of code:
use RenzoJohnson\WhatsApp\WhatsApp;
$wa = new WhatsApp('YOUR_PHONE_NUMBER_ID', 'YOUR_ACCESS_TOKEN');
$wa->sendText('14155551234', 'Hello from PHP!');
Specifically, you create a WhatsApp instance with your Phone Number ID and Access Token from the Meta Developer Console, then call sendText() with the recipient’s number and your message. As a result, the library handles the HTTP request, JSON encoding, and error checking behind the scenes.
Sending Messages
The WhatsApp Cloud API PHP package supports every message type available in the Cloud API. In fact, each message type has its own dedicated method with named parameters for clarity.
Text Messages
// Simple text
$wa->sendText('14155551234', 'Hello World');
// With link preview
$wa->sendText('14155551234', 'Check https://example.com', previewUrl: true);
Template Messages
Templates are pre-approved message formats required by WhatsApp for initiating conversations. Similarly, they support dynamic parameters:
// Simple template
$wa->sendTemplate('14155551234', 'hello_world', 'en_US');
// Template with parameters
$wa->sendTemplate('14155551234', 'order_update', 'en_US', [
['type' => 'body', 'parameters' => [
['type' => 'text', 'text' => 'John'],
['type' => 'text', 'text' => 'ORD-12345'],
]],
]);
Media Messages
Send images, documents, videos, audio, and stickers by URL or by media ID:
// Image with caption
$wa->sendImage('14155551234', link: 'https://example.com/photo.jpg', caption: 'A photo');
// Document with filename
$wa->sendDocument('14155551234', link: 'https://example.com/invoice.pdf',
caption: 'Your invoice', filename: 'invoice-2026.pdf');
// Video
$wa->sendVideo('14155551234', link: 'https://example.com/clip.mp4', caption: 'Watch this');
// Audio
$wa->sendAudio('14155551234', link: 'https://example.com/audio.mp3');
// Sticker
$wa->sendSticker('14155551234', link: 'https://example.com/sticker.webp');
Location and Contact
Moreover, the package supports rich message types like locations and contact cards:
// Location
$wa->sendLocation('14155551234', latitude: 28.5383, longitude: -81.3792,
name: 'Orlando Office', address: '123 Main St, Orlando, FL');
// Contact card
$wa->sendContact('14155551234',
name: ['first_name' => 'Jane', 'last_name' => 'Doe'],
phones: [['phone' => '+14155559999', 'type' => 'CELL']]);
Media Management
In addition to sending media by URL, you can upload files directly to Meta’s servers and manage them:
// Upload a file
$response = $wa->uploadMedia('/path/to/file.jpg', 'image/jpeg');
$mediaId = $response['id'];
// Retrieve media URL
$media = $wa->getMedia('media_123');
$url = $media['url'];
// Delete media
$wa->deleteMedia('media_123');
Consequently, you have full control over the media lifecycle — upload, retrieve, use, and delete — all through the same library.
Webhook Handling
Receiving incoming WhatsApp messages requires a webhook endpoint. The WhatsApp Cloud API PHP package handles both webhook verification and message parsing with built-in HMAC-SHA256 signature validation.
Webhook Verification
Meta sends a GET request to your webhook URL during setup. Specifically, the library handles the challenge-response automatically:
use RenzoJohnson\WhatsApp\Webhook\Listener;
Listener::verify('YOUR_VERIFY_TOKEN');
Receiving Messages
For incoming messages, the library validates the X-Hub-Signature-256 header, parses the payload, and passes a typed Notification object to your callback:
use RenzoJohnson\WhatsApp\Webhook\Listener;
use RenzoJohnson\WhatsApp\Webhook\Notification;
Listener::listen('YOUR_APP_SECRET', function (Notification $notification, array $raw) {
if ($notification->isText()) {
echo 'From: ' . $notification->from . "\n";
echo 'Text: ' . $notification->text . "\n";
}
if ($notification->isImage()) {
echo 'Image ID: ' . $notification->image['id'] . "\n";
}
});
Most importantly, invalid signatures are rejected with HTTP 401 automatically. As a result, your webhook endpoint is protected against forged payloads without writing any validation code yourself.
Error Handling
The package provides specialized exception classes for different failure scenarios. In particular, you can catch specific error types and handle them appropriately:
use RenzoJohnson\WhatsApp\Exception\{
AuthenticationException,
RateLimitException,
WhatsAppException
};
try {
$wa->sendText('14155551234', 'Hello');
} catch (AuthenticationException $e) {
// 401: Invalid or expired access token
} catch (RateLimitException $e) {
// 429: Too many requests — back off and retry
} catch (WhatsAppException $e) {
// Other API errors (400, 500, etc.)
$errorData = $e->getErrorData();
}
Consequently, your application can implement proper retry logic, token refresh flows, and graceful degradation based on the specific error type.
WhatsApp Cloud API PHP vs Other Libraries
Several PHP packages exist for the WhatsApp Cloud API. However, this package takes a different approach:
| Feature | renzojohnson/whatsapp-cloud-api | netflie/whatsapp-cloud-api | sdksio/whatsapp-cloud-api-sdk |
|---|---|---|---|
| PHP version | 8.4+ | 7.4+ | 8.1+ |
| Dependencies | Zero | guzzlehttp/guzzle | Multiple |
| Webhook validation | HMAC-SHA256 built-in | Basic | Manual |
| Named parameters | Yes | No | No |
| Media management | Upload, retrieve, delete | Upload, send | Send only |
| Exception types | Auth, RateLimit, General | General only | General only |
| Mark as read | Yes | Yes | No |
| License | MIT | MIT | MIT |
In short, this package is built for modern PHP applications that value minimal dependencies and explicit error handling.
Supported Message Types
The complete list of supported message types and their corresponding methods:
| Message Type | Method | Key Parameters |
|---|---|---|
| Text | sendText() |
to, text, previewUrl |
| Template | sendTemplate() |
to, template, language, components |
| Image | sendImage() |
to, link/mediaId, caption |
| Document | sendDocument() |
to, link/mediaId, caption, filename |
| Video | sendVideo() |
to, link/mediaId, caption |
| Audio | sendAudio() |
to, link/mediaId |
| Location | sendLocation() |
to, latitude, longitude, name, address |
| Contact | sendContact() |
to, name, phones |
| Sticker | sendSticker() |
to, link/mediaId |
Additionally, the markAsRead() method lets you mark incoming messages as read, which updates the blue checkmarks on the sender’s device.
Common Questions
Is the WhatsApp Cloud API free?
Meta provides 1,000 free service conversations per month. After that, pricing depends on your region and conversation type. However, the PHP package itself is completely free and open source under the MIT license.
Do I need a Meta Business account?
Yes. The WhatsApp Cloud API requires a Meta Business account and a registered WhatsApp Business phone number. Specifically, you need the Phone Number ID and a permanent Access Token generated through a System User in Business Manager.
Can I use this with Laravel or Symfony?
Yes. The package is framework-agnostic. It works with any PHP application that uses Composer autoloading — Laravel, Symfony, Slim, or plain PHP. In fact, there are no framework-specific dependencies to worry about.
What about rate limits?
Meta enforces messaging limits that start at 250 messages per 24 hours for new numbers and scale up as your account builds trust. The package throws a RateLimitException when you hit the limit, so you can implement retry logic with exponential backoff.
Getting Started
The WhatsApp Cloud API PHP package gives you a clean, dependency-free way to integrate WhatsApp messaging into your PHP application. In other words, you get full send and receive capabilities with proper error handling and webhook security in a single Composer package.
Additionally, check out these other open source contributions and tools:
- Arc — VS Code Terminal Bridge for AI coding agents.
- GA4 MCP Server for querying Google Analytics from AI agents.
- Iris — Telegram Bridge for Claude Code in VS Code.
- CF7 Mailchimp Extension for WordPress email marketing.
If you need help with the WhatsApp Cloud API PHP package or want to report an issue, open an issue on GitHub or contact us directly.