Library / SDK
netflie/whatsapp-cloud-api avatar
netflie/whatsapp-cloud-api

netflie/whatsapp-cloud-api: a PHP SDK for the WhatsApp Cloud API

The first PHP API to send and receive messages using a cloud-hosted version of the WhatsApp Business Platform

685 stars238 forksPHPMIT

At a glance

What is it?
The netflie/whatsapp-cloud-api package wraps the WhatsApp Cloud API in PHP, covering text, media, template, location, contact and list messages plus BSUID addressing, with a single constructor taking a phone number id and an access token. It targets PHP 7.4 and above and moved to a 4.x line in 2026.
Who is it for?
Adopt netflie/whatsapp-cloud-api if you are building a PHP service on the WhatsApp Cloud API and you want typed message objects for the media, template and contact payloads rather than hand assembling request arrays. Do not adopt it if you need inbound webhook handling with a supported framework integration, because the examples in the readme cover sending rather than receiving, and check the UPGRADE.md file before moving between major versions.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 83 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One constructor, then a method per message type

The package exists to make the WhatsApp Cloud API easy to access from PHP code, and the readme calls it the first PHP API to send and receive messages using the cloud hosted version of the WhatsApp Business Platform.

The entry point is a single class constructed with your credentials:

php
<?php

// Require the Composer autoloader.
require 'vendor/autoload.php';

use Netflie\WhatsAppCloudApi\WhatsAppCloudApi;

// Instantiate the WhatsAppCloudApi super class.
$whatsapp_cloud_api = new WhatsAppCloudApi([
    'from_phone_number_id' => 'your-configured-from-phone-number-id',
    'access_token' => 'your-facebook-whatsapp-application-token',
]);

$whatsapp_cloud_api->sendTextMessage('34676104574', 'Hey there! I\'m using WhatsApp Cloud API. Visit https://www.netflie.es');

Two configuration values are all you need to start, and the credentials come from the Facebook WhatsApp application you create following the Get Started section of the official guide. The sample environment file shipped in the repository names the variables the package expects:

code
WHATSAPP_CLOUD_API_FROM_PHONE_NUMBER="10100011011"
WHATSAPP_CLOUD_API_TOKEN="Shhhhh!"
WHATSAPP_CLOUD_API_BUSINESS_ID="10100011011"

After construction, the surface is a set of send methods, one per message type, and each takes the destination phone number as its first argument. There are methods for text, document, template, audio, image, video, sticker, location, location request, contact and list messages. The shape is consistent, which is what makes the package pleasant to use: you learn the calling convention once.

The minimum requirements are PHP 7.4 or later and a recent CURL, 7.19.4 or above, compiled with OpenSSL and zlib. The licence is MIT and the package is installed with Composer using the command composer require netflie/whatsapp-cloud-api.

Media is a typed object, not an array of parameters

The most useful design decision in the package is how it handles media, and it is the reason a lot of the readme is examples rather than prose.

Documents can be sent two ways: by uploading a file to the WhatsApp Cloud servers, where you receive an identifier, or from a link to a document published on the internet. The package models those as two different value objects, LinkID and MediaObjectID, and the send method accepts either:

php
<?php

use Netflie\WhatsAppCloudApi\Message\Media\LinkID;
use Netflie\WhatsAppCloudApi\Message\Media\MediaObjectID;

$document_id = '341476474779872';
$document_name = 'whatsapp-cloud-api-from-id.pdf';
$document_caption = 'WhastApp API Cloud Guide';

// With the Media Object ID of some document upload on the WhatsApp Cloud servers
$media_id = new MediaObjectID($document_id);
$whatsapp_cloud_api->sendDocument('34676104574', $media_id, $document_name, $document_caption);

// Or
$document_link = 'https://netflie.es/wp-content/uploads/2022/05/image.png';
$link_id = new LinkID($document_link);
$whatsapp_cloud_api->sendDocument('34676104574', $link_id, $document_name, $document_caption);

The same two class types are used for images, videos, audio and stickers, so the distinction between an uploaded object and a hosted link is consistent across every media type. That consistency is the payoff, because the alternative is remembering which field each endpoint expects.

Documents also take a file name and a caption, while video takes a caption, and image, audio and sticker take neither. Locations take a longitude, a latitude, a name and an address, and there is a separate location request message for asking a user to share their location or enter an address, with the body text as a parameter.

Templates carry a Component object for header, body and buttons

Template messages are the other place where the package does real work for you, because the Cloud API template payload is a nested structure that is unpleasant to build by hand.

A simple template needs a name and a language code, and the language defaults to en_US if you do not pass one:

php
<?php

$whatsapp_cloud_api->sendTemplate('34676104574', 'hello_world', 'en_US'); // If not specified, Language will be default to en_US and otherwise it will be required.

With parameters, the payload is assembled into a Component object with three parts, a header, a body and a set of buttons, and the button entries are typed as quick replies with a sub type, an index and a text parameter:

php
<?php

use Netflie\WhatsAppCloudApi\Message\Template\Component;

$component_header = [];

$component_body = [
    [
        'type' => 'text',
        'text' => '*Mr Jones*',
    ],
];

$component_buttons = [
    [
        'type' => 'button',
        'sub_type' => 'quick_reply',
        'index' => 0,
        'parameters' => [
            [
                'type' => 'text',
                'text' => 'Yes',
            ]
        ]
    ],
    [
        'type' => 'button',
        'sub_type' => 'quick_reply',
        'index' => 1,
        'parameters' => [
            [
                'type' => 'text',
                'text' => 'No',
            ]
        ]
    ]
];

$components = new Component($component_header, $component_body, $component_buttons);
$whatsapp_cloud_api->sendTemplate('34676104574', 'sample_issue_resolution', 'en_US', $components); // Language is optional

The index on each button is what tells the Cloud API which template button the parameter belongs to, and getting that wrong is a common source of rejected templates, so having it as an explicit field in the constructor is helpful.

The header component is left empty in this example, which is worth noticing: the object accepts a header, and the readme does not pretend every template needs one.

BSUID addressing lets you target a user without a phone number

The newest capability in the readme is BSUID as a recipient, and it is the one feature that changes how you model your users.

A BSUID is an identifier the Cloud API can address a recipient by, and the examples show three ways to use it. Sending by BSUID only, sending both the phone number and the BSUID in the same request, and the note that the Cloud API gives precedence to the to parameter when both are present:

php
<?php

$recipient_bsuid = 'US.13491208655302741918';

// Send using BSUID only
$whatsapp_cloud_api->sendTextMessage(null, 'Hello from BSUID', false, $recipient_bsuid);

// Send both values in the same request (WhatsApp Cloud API gives precedence to `to`)
$whatsapp_cloud_api->sendTextMessage('34676104574', 'Hello with both identifiers', false, $recipient_bsuid);

The optional recipient parameter is available in all send methods that post to the /messages endpoint, which is the important part for anyone retrofitting this into an existing integration. The signature is not a new method, it is an extra trailing argument, so the change is additive.

Contact messages take the BSUID in a different position, before the phone entries, which is an inconsistency worth noting if you are writing a wrapper that forwards arguments generically:

php
$contact_name = new \Netflie\WhatsAppCloudApi\Message\Contact\ContactName('John', 'Doe');
$phone = new \Netflie\WhatsAppCloudApi\Message\Contact\Phone('+14155550100', \Netflie\WhatsAppCloudApi\Message\Contact\PhoneType::CELL());

$whatsapp_cloud_api->sendContact(null, $contact_name, $recipient_bsuid, $phone);

The contact value objects are also typed, with a ContactName, a Phone and a PhoneType, which keeps the phone type a single enum rather than a string you have to get right.

Free tier, no inbound examples, and what the repository actually holds

A few practical points bound the decision.

On cost, the readme states that the first 1000 conversations each month are free from the WhatsApp Cloud API. That is enough to develop and to run a small deployment, and beyond it you are on WhatsApp's pricing, which this package does not influence.

On the scope of the documentation, every example in the readme is a send. The package description says send and receive, but the examples cover sending, and there is no inbound webhook example in the readme. If your requirement is handling replies, the webhook plumbing and the verification handshake are on you, and you should check the API documentation and the UPGRADE.md file for what changed between major versions.

The repository is a normal Composer package layout: a src directory, a tests directory, a composer.json, a composer.lock, a phpunit.xml.dist for the test configuration, a .php-cs-fixer.dist.php for code style, a .pre-commit-config.yaml, a CHANGELOG, an UPGRADE.md file, a .env.sample and a GitHub workflows directory. The presence of both a changelog and a dedicated upgrade guide is a good sign for a package at version 4, and the 4.x line arrived with a 4.0.0-beta1 before the final release, so pre-release testing was part of the process.

The releases show steady work: 4.0.0 on 2026-04-28, 4.0.0-beta1 on 2026-04-14, and 3.1.0 on 2026-03-23, with the last push on 2026-08-01. The package is described as the first PHP API for this service, and it is the reference implementation most PHP developers for the WhatsApp Cloud API will meet first, which is worth remembering when you compare it with a newer option.

Editorial conclusion

Adopt netflie/whatsapp-cloud-api if you are building a PHP service on the WhatsApp Cloud API and you want typed message objects for the media, template and contact payloads rather than hand assembling request arrays. Do not adopt it if you need inbound webhook handling with a supported framework integration, because the examples in the readme cover sending rather than receiving, and check the UPGRADE.md file before moving between major versions. Before you commit, create the Facebook WhatsApp application as the official guide describes, keep the access token out of source control using the environment variable names from the sample file, and confirm the first 1000 monthly conversations are enough for your volume.

Frequently asked questions

How do I install the netflie/whatsapp-cloud-api package?

Install it with Composer using the netflie/whatsapp-cloud-api package name, then require the Composer autoloader. The minimum requirements are PHP 7.4 or later and CURL 7.19.4 or newer compiled with OpenSSL and zlib.

How do I send a text message with the WhatsApp Cloud API PHP SDK?

Instantiate WhatsAppCloudApi with your from_phone_number_id and access_token, then call sendTextMessage with the destination phone number and the message body. The credentials come from the Facebook WhatsApp application you configure following the official Get Started guide.

What is the difference between LinkID and MediaObjectID?

LinkID points at a document, image, video, audio or sticker published on the internet, while MediaObjectID refers to a file already uploaded to the WhatsApp Cloud servers, identified by the id you received. Both are accepted by the media send methods, so the same method covers either source.

How much does the WhatsApp Cloud API cost?

The readme states that the first 1000 conversations each month are free from the WhatsApp Cloud API. Beyond that the platform pricing applies, which the SDK does not change.

Can I address a WhatsApp user without their phone number?

Yes, through BSUID. The optional recipient parameter is available in all send methods that post to the /messages endpoint, and when both a phone number and a BSUID are supplied the Cloud API gives precedence to the to parameter.

Official sources

  1. License: MIT
  2. netflie/whatsapp-cloud-api on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/netflie-whatsapp-cloud-api.svg)](https://hysenlabs.com/projects/netflie-whatsapp-cloud-api)

Was this useful?