Main
🏠 Home ℹ️ About Us
WhatsApp
💬 WhatsApp Business API (WABA) 🔐 OTP & TAC via WhatsApp 🤖 WhatsApp + AI Chatbot 🔵 Blue Tick Verification
SMS
📱 One-Way Bulk SMS 🔒 Two-Factor Authentication (2FA) 🌏 Global SMS Coverage ⚡ SMS API
Email & API
✉️ Email Service Overview 🔌 Email SMTP API 🛠 REST API Reference
Queue System
🏢 Queue System Overview 💬 WhatsApp QMS ☁️ Cloud QMS ⚡ Cloud + WhatsApp QMS 📖 Cloud & WhatsApp QMS Guide 🎯 Request Free Demo
Pricing
💰 Full PHP Rate List 🛒 Buy SMS Credits
Support
📩 Contact Us ❓ FAQ 📖 End-User Guide ⚠️ Service Advisory
🔑 Login 📝 Register Free
💬
WhatsApp Business API — Billing Overview
All WABA messages are charged per message by Meta, except for Service messages (user-initiated conversations) which are charged per 24-hour session — meaning unlimited messages within that window at one session fee.
Message categories: Marketing (per message) · Utility (per message) · Authentication/OTP (per message) · Service/Customer Service (per 24-hour session, user-initiated only). Pricing varies by destination country. Contact us for a quote.
💬 WhatsApp Business API

WABA API Developer Reference

Send template messages, custom messages, and files via WhatsApp channel through the iSMS platform. Viber and Messenger coming soon.

Version 2.0 Last Updated: March 5, 2026 Protocol: HTTPS POST / JSON
ℹ️This API is available to all registered iSMS customers with an active WABA account. Contact our team to get your AppId and AppSecret credentials.

📡 Base URLs

Three endpoint URLs are provided. We recommend using Resource URL 2 or 3 for optimal performance and reliability in production.

URL 1https://ww3.isms.com.my/isms_send_waba.php
URL 2https://smtpapi.vocotext.com/isms_send_waba.phpRecommended
URL 3https://smtpapi2.vocotext.com/isms_send_waba.phpRecommended
POST application/json
⚠️All request bodies must be valid JSON. Ensure your HTTP client sets the Content-Type: application/json header in every request.

📱 Supported Channels

whatsapp✓ Available
viber⏳ Under Development
messenger⏳ Under Development

💬 Message Types

The Send Message API supports three message types. Template messages (Marketing, Utility, Authentication/OTP) are charged per message and can be sent anytime. Custom/free-text messages and files are only available within an active 24-hour user-initiated window — this is the Service message category, charged per session (not per message).

template

Send pre-approved Meta message templates with dynamic variable substitution.

✓ Available anytime
message

Send custom free-text messages to users who have recently messaged your WABA number.

⏱ Within 24-hour window
file

Send images, PDFs, documents, and other files via a direct publicly accessible URL.

⏱ Within 24-hour window

📋 Request Parameters

Complete parameter reference for the Send Message API. Required parameters must be in every request. Conditional parameters depend on message type.

ParameterTypeRequiredDescriptionExample
AppIdStringRequiredApplication ID from iSMS console8671971xxx
AppSecretStringRequiredApplication secret from iSMS console0b34b7cc...
unStringRequiredYour iSMS account usernameiSMS
pwdStringRequiredYour iSMS account passwordiSMS123
agreedtermStringRequiredMust be set to "YES" — confirms acceptance of iSMS TermsYES
ChannelTypeStringRequiredMessage channel. Currently supported: whatsapp. Viber and Messenger coming soon.whatsapp
TypeStringRequiredMessage type: template, message, or filetemplate
FromStringRequiredSender phone number — must be registered WABA number6391XXXXXXXX
ToStringRequiredRecipient phone number in international format6018222xxxx
TemplateCodeStringConditionalTemplate code — required when Type = template744c4b5c...
LanguageStringConditionalTemplate language code — required when Type = templateen
TemplateParamsObjectConditionalTemplate variable values as JSON — when Type = template{"param1":"val"}
ContentStringConditionalMessage text body — required when Type = messageHello World
fileUrlStringConditionalDirect public URL to file — required when Type = filehttps://...
fileNameStringConditionalDisplay name for the file — required when Type = fileinvoice.pdf
⚠️The fileUrl must be a direct, publicly accessible URL. URLs behind Cloudflare or similar proxy services may not be accessible by the WABA delivery system.

📤 Send Template Message

Template messages (Marketing, Utility, Authentication/OTP) are pre-approved by WhatsApp and can be sent anytime — ideal for notifications, OTP, reminders, and transactional alerts. These are charged per message regardless of session status.

JSON Request Body

JSONRequest Body
{
  "AppId": "8671971xxxxxxx",
  "AppSecret": "0b34b7cc0cbxxxxxc",
  "un": "your_username",
  "pwd": "your_password",
  "agreedterm": "YES",
  "Type": "template",
  "TemplateCode": "90934259xxxxxx",
  "TemplateParams": {
    "param1": "your value here"
  },
  "Language": "en",
  "From": "6391XXXXXXXX",
  "To": "639XXXXXXXXX"
}

PHP Example

PHPsend_template.php
<?php
$url = "https://smtpapi.vocotext.com/isms_send_waba.php";

$data = [
    "AppId"       => "your_app_id",
    "AppSecret"   => "your_app_secret",
    "un"          => "your_username",
    "pwd"         => "your_password",
    "agreedterm"  => "YES",
    "Type"        => "template",
    "TemplateCode" => "your_template_code",
    "TemplateParams" => ["param1" => date("Y-m-d H:i:s")],
    "Language"    => "en",
    "From"        => "your_waba_number",
    "To"          => "recipient_number"
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "cURL error: " . curl_error($ch);
} else {
    $result = json_decode($response, true);
    echo "Status: " . $result['statusCode'];
    echo " | MessageId: " . $result['messageId'];
}

curl_close($ch);
?>

✉️ Send Custom Message

Send free-form text messages. Only available within the active 24-hour Service session — triggered when a user messages your WABA number first. This session type is charged per 24-hour window, not per individual message.

JSONRequest Body
{
  "AppId": "867197xxxx",
  "AppSecret": "0b34b7ccxxxx",
  "un": "your_username",
  "pwd": "your_password",
  "agreedterm": "YES",
  "Type": "message",
  "Content": "Hello! Your appointment is confirmed for tomorrow at 10am.",
  "From": "6391XXXXXXXX",
  "To": "639XXXXXXXXX"
}
PHPsend_message.php
<?php
$url = "https://smtpapi.vocotext.com/isms_send_waba.php";

$data = [
    "AppId"      => "your_app_id",
    "AppSecret"  => "your_app_secret",
    "un"         => "your_username",
    "pwd"        => "your_password",
    "agreedterm" => "YES",
    "Type"       => "message",
    "Content"    => "Hello! Your appointment is confirmed for tomorrow at 10am.",
    "From"       => "your_waba_number",
    "To"         => "recipient_number"
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);
echo $response;
curl_close($ch);
?>

📎 Send File

Send images, PDFs, and other documents via a direct public URL. The file must be accessible by our servers without authentication.

JSONRequest Body
{
  "AppId": "8671971xxxxx",
  "AppSecret": "0b34b7cc0cbxxxxx",
  "un": "your_username",
  "pwd": "your_password",
  "agreedterm": "YES",
  "Type": "file",
  "fileUrl": "https://www.bulksms.com.sg/marketing.png",
  "fileName": "marketing_brochure",
  "From": "6391XXXXXXXX",
  "To": "639XXXXXXXXX"
}
PHPsend_file.php
<?php
$url = "https://smtpapi.vocotext.com/isms_send_waba.php";

$data = [
    "AppId"      => "your_app_id",
    "AppSecret"  => "your_app_secret",
    "un"         => "your_username",
    "pwd"        => "your_password",
    "agreedterm" => "YES",
    "Type"       => "file",
    "fileUrl"    => "https://www.bulksms.com.sg/marketing.png",
    "fileName"   => "marketing_brochure",
    "From"       => "your_waba_number",
    "To"         => "recipient_number"
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);
echo $response;
curl_close($ch);
?>

✅ Response Format

Success Response

{ "requestId": "C9122953-C329-3D9A-9191-7EB5D70D54FC", "statusCode": "OK", "messageId": "202311882856605014114304" }
ParameterTypeDescription
requestIdStringUnique identifier for the API request — use for support enquiries
statusCodeStringOK or 0 = success. Any other value indicates failure. See Error Codes.
messageIdStringUnique identifier for the sent message — use for delivery status tracking

❌ Error Codes

General Errors

CodeDescription
0 / OKRequest successful
-1The system is busy — retry after a short delay
1000Unknown error
1001Authentication failed — check username and password
1002Account suspended or expired
1003IP address not allowed
1004Insufficient credits
1008Missing required parameter

WABA-Specific Errors

CodeDescription
50500Invalid destination phone number
70500Invalid WABA account
70501Invalid WABA API key
70502Insufficient WABA credits

Application & Session Errors

CodeDescription
40001Invalid AppSecret or AccessToken
40008Invalid message type
41000Required parameter not specified
42001Access token expired
45001API call limit exceeded
45010Reply time limit exceeded (outside 24h window)
47001JSON parsing error — check request body format
48001Not authorized to call this API

Template Errors

CodeDescription
60005templateCode parameter not specified
60006Template code does not exist
60012Invalid parameter format
70001Scenario sending policy not configured

📥 Inbound Messages (Webhook)

When a WhatsApp user sends a message to your WABA number, iSMS will immediately forward it to your registered webhook URL via an HTTPS POST request. The entire payload is delivered as a single response parameter encoded in base64.

ℹ️Contact sales@mobiweb.com.my to register your inbound webhook URL. Once configured, all inbound messages to your WABA number will be pushed to your endpoint automatically.

Webhook Method & URL Format

POST https://{yoururl}?response=xxxxx
ParameterLocationTypeDescription
response Query String String The full inbound message payload encoded as base64_encode(). Decode this value to retrieve the JSON object containing all message fields.

Decoded Payload Fields

After decoding the response parameter with base64_decode(), you will receive a JSON object with the following fields:

ParameterTypeRequiredDescription
MessageId String Yes The message ID.
From String Yes The phone number of the message sender.
To String Yes The phone number of the message receiver.
Timestamp Long Yes The timestamp is a Unix timestamp in milliseconds.
DisplayName String Yes The display name of the message sender.
Type String Yes The type of the media resources that are included in the message. Valid values:
  • TEXT
  • LOCATION
  • DOCUMENT
  • VIDEO
  • AUDIO
  • REPLY
  • IMAGE
  • CONTACTS
Message String Yes The content of the message.
Name String Yes The name of the end user.

Parameters that specify a location (Type = LOCATION)

When Type is LOCATION, the Message field is a JSON object with the following fields:

ParameterTypeRequiredDescription
latitudeFloatYesThe latitude of the location.
longitudeFloatYesThe longitude of the location.
nameStringNoThe name of the location.
addressStringNoThe address of the location.
// Example Message value when Type = LOCATION { "latitude": 14.5995, "longitude": 120.9842, "name": "Bonifacio Global City", "address": "Taguig, Metro Manila, Philippines" }

Parameters that specify an image (Type = IMAGE)

When Type is IMAGE, the Message field is a JSON object with the following fields:

ParameterTypeRequiredDescription
urlStringYesThe URL of the image file.
captionStringNoThe caption of the image.
// Example Message value when Type = IMAGE { "url": "https://cdn.example.com/photo.jpg", "caption": "Check out our latest product!" }

Parameters that specify a video file (Type = VIDEO)

When Type is VIDEO, the Message field is a JSON object with the following fields:

ParameterTypeRequiredDescription
urlStringYesThe URL of the video file.
captionStringNoThe caption of the video.
// Example Message value when Type = VIDEO { "url": "https://cdn.example.com/promo.mp4", "caption": "Watch our promo video" }

Parameters that specify an audio file (Type = AUDIO)

When Type is AUDIO, the Message field is a JSON object with the following fields:

ParameterTypeRequiredDescription
urlStringYesThe URL of the audio file.
// Example Message value when Type = AUDIO { "url": "https://cdn.example.com/voicenote.ogg" }

Parameters that specify a document (Type = DOCUMENT)

When Type is DOCUMENT, the Message field is a JSON object with the following fields:

ParameterTypeRequiredDescription
urlStringYesThe URL of the document file.
filenameStringNoThe file name of the document as displayed to the recipient.
captionStringNoThe caption of the document.
// Example Message value when Type = DOCUMENT { "url": "https://cdn.example.com/invoice.pdf", "filename": "Invoice_April2025.pdf", "caption": "Please find your invoice attached." }

Parameters that specify a reply button (Type = REPLY)

When Type is REPLY, the Message field is a JSON object with the following fields:

ParameterTypeRequiredDescription
replyMessageIdStringYesThe MessageId of the original message the user is replying to.
textStringYesThe text content of the reply.
// Example Message value when Type = REPLY { "replyMessageId": "C9122953-C329-3D9A-9191-7EB5D70D54FC", "text": "Yes, I confirm my appointment." }

Sample Decoded Payload (JSON)

This is what you get after base64_decode($response) and json_decode():

{ "MessageId": "C9122953-C329-3D9A-9191-7EB5D70D54FC", "From": "639171234567", "To": "6391XXXXXXXX", "Timestamp": 1712390400000, "DisplayName": "Juan dela Cruz", "Name": "Juan dela Cruz", "Type": "TEXT", "Message": "Hello, I would like to know more about your services." }

PHP Webhook Receiver Example

Save this as your webhook endpoint file on your server. Register its URL with BulkSMS support.

PHPwaba_inbound_webhook.php
<?php
/**
 * waba_inbound_webhook.php
 * Bulk SMS Philippines will POST to: https://yoursite.com/waba_inbound_webhook.php?response=xxxxx
 * The ?response= param is base64 encoded JSON.
 */

// 1. Read the raw base64-encoded response from query string
$encoded = $_POST['response'] ?? $_GET['response'] ?? '';

if (empty($encoded)) {
    http_response_code(400);
    echo 'Missing response parameter';
    exit;
}

// 2. Decode the base64 payload
$json = base64_decode($encoded);

if ($json === false) {
    http_response_code(400);
    echo 'Invalid base64 encoding';
    exit;
}

// 3. Parse JSON into array
$msg = json_decode($json, true);

if (!$msg || !isset($msg['MessageId'])) {
    http_response_code(400);
    echo 'Invalid payload';
    exit;
}

// 4. Extract fields
$messageId   = $msg['MessageId']   ?? '';
$from        = $msg['From']        ?? '';
$to          = $msg['To']          ?? '';
$timestamp   = $msg['Timestamp']   ?? 0;
$displayName = $msg['DisplayName'] ?? '';
$name        = $msg['Name']        ?? '';
$type        = $msg['Type']        ?? 'TEXT';
$message     = $msg['Message']     ?? '';

// 5. Convert timestamp (milliseconds) to readable datetime
$datetime = date('Y-m-d H:i:s', $timestamp / 1000);

// 6. Your business logic here — e.g. save to DB, trigger auto-reply, etc.
// Example: log to file
$log = sprintf(
    "[%s] From:%s To:%s Type:%s Msg:%s\n",
    $datetime, $from, $to, $type, $message
);
file_put_contents('inbound_log.txt', $log, FILE_APPEND | LOCK_EX);

// 7. Always respond 200 OK — Bulk SMS Philippines will retry if it receives non-200
http_response_code(200);
echo 'OK';
?>
⚠️Your webhook endpoint must respond with HTTP 200 within 10 seconds. If Bulk SMS Philippines receives a non-200 response or timeout, the webhook will be retried. Always return 200 OK immediately and process the payload asynchronously if needed.
Use the MessageId field to deduplicate messages in case of retries — store processed IDs in your database and skip any that have already been handled.

📬 Delivery Status (Webhook)

Receive real-time delivery status updates via webhook. WhatsApp Business API provides true handset-level delivery tracking — unlike SMS which only confirms Telco SMSC receipt, WABA reports actual message status at the recipient's device.

MessageId

Unique identifier for the sent message

From

Sender phone number (your WABA number)

To

Recipient phone number

Status

Message status: Sent (submitted to WhatsApp), Delivered (confirmed received at recipient's handset), or Read (recipient opened the message). Unlike SMS DLR, WhatsApp delivery status reflects true handset-level confirmation.

ErrorDescription

Error description if message failed to deliver

📄 Template List API

Endpointhttps://smtpapi.vocotext.com/api_waba_list_template.php
POST or GET application/json

Fetch all WhatsApp message templates associated with your account — including type, name, approval status, language, and components. The component field is base64 encoded.

ParameterTypeRequiredDescription
unStringRequiredYour iSMS account username
pwdStringRequiredYour iSMS account password

Success Response

{ "status": "success", "data": [ { "templateType": "PROMOTIONAL", "name": "New Year Offer", "auditStatus": "approved", "language": "en", "templateCode": "1XXXXXXXXX90", "last_updated_on": "2024-07-21T14:55:30Z", "component": "eyJ0eXBlIjogIkJPRFki...", "status_code": "200", "status_message": "Approved" } ] }
ℹ️The component field is base64 encoded. Use a base64 decoder (or PHP's base64_decode()) to read template component data.

PHP Example (POST)

PHPlist_templates.php
<?php
$url  = "https://smtpapi.vocotext.com/api_waba_list_template.php";
$data = json_encode(["un" => "your_username", "pwd" => "your_password"]);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

$response = curl_exec($ch);
$templates = json_decode($response, true);

if ($templates['status'] === 'success') {
    foreach ($templates['data'] as $tpl) {
        echo $tpl['name'] . " — " . $tpl['auditStatus'] . "\n";
    }
}
curl_close($ch);
?>

💰 Balance API

Endpointhttps://smtpapi.vocotext.com/api_waba_balance.php
POST or GET application/json

Check your WABA account credit balance. Each WABA account may have multiple phone numbers — the balance for each registered number is returned separately.

Success Response

{ "status": "success", "data": [ { "waba_number": "639XXXXXXXXX", "waba_status": "1", "waba_credit_balance": "100.00", "waba_credit_currency": "USD", "expiry_date": "2026-12-31" } ] }
PHPcheck_balance.php
<?php
$url  = "https://smtpapi.vocotext.com/api_waba_balance.php";
$data = json_encode(["un" => "your_username", "pwd" => "your_password"]);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

$response = curl_exec($ch);
$result   = json_decode($response, true);

if ($result['status'] === 'success') {
    foreach ($result['data'] as $acct) {
        echo $acct['waba_number'] . ": USD " . $acct['waba_credit_balance'];
    }
}
curl_close($ch);
?>

Need API Access or Integration Help?

Contact our developer support team — we'll get your AppId, AppSecret, and WABA number configured.

💬 Contact Developer Support →

📧 sales@mobiweb.com.my  ·  📞 +6016 450 2380

💬