Main
🏠 Home ℹ️ About Us
WhatsApp
💬 WhatsApp Business API (WABA) 🔐 OTP & TAC via WhatsApp 🤖 WhatsApp + AI Chatbot 🔵 Blue Tick Verification 🤖 AI Chatbot 🎨 Automation Flow Builder 🔘 Interactive Messages 💡 Automation Use Cases 📱 App Coexistence
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
📱 iSMS SMS Gateway API

SMS Gateway API Reference

Integrate SMS messaging into your applications two ways — a modern JSON API with per-recipient personalised messages and structured responses, or the classic HTTP GET/POST API. Built for transactional alerts, OTP delivery, bulk campaigns, and notifications.

Version 2.1 Protocol: JSON POST · HTTPS GET/POST Base URL: www.isms.com.my Format: JSON / Plain Text
⚠️IP Whitelist Required — All API requests must originate from a whitelisted server IP address. Contact sales@mobiweb.com.my to whitelist your IP before making API calls. Non-whitelisted IPs will be rejected with error code -1003.

📡 API Endpoint URLs

Four redundant hosts are provided for each API. Hosts 1 and 2 are recommended for production — configure your integration to fall back to the alternatives if the primary is unavailable.

JSON API — Recommended
1 — Primaryhttps://www.isms.com.my/isms_send_json.phpRecommended
2 — Secondaryhttps://ww3.isms.com.my/isms_send_json.phpRecommended
3 — Tertiaryhttps://smtpapi.vocotext.com/isms_send_json.php
4 — Quaternaryhttps://smtpapi2.vocotext.com/isms_send_json.php
Check Balancehttps://www.isms.com.my/isms_balance_json.php
Classic GET / POST API
1 — Primaryhttps://www.isms.com.my/isms_send_all_id.phpRecommended
2 — Secondaryhttps://smtpapi2.vocotext.com/isms_send_all_id.phpRecommended
3 — Tertiaryhttps://smtpapi.vocotext.com/isms_send_all_id.php
4 — Fallbackhttps://ww3.isms.com.my/isms_send_all_id.php
ℹ️All hosts are HTTPS only. The JSON API requires POST with Content-Type: application/json. The classic API accepts both GET and POST (form-encoded) with identical parameters.

🔤 SMS Encoding Types

The type parameter controls character encoding. Use type 1 for Latin-script languages and type 2 for Chinese, Japanese, Arabic, and other non-ASCII scripts.

type = 1 — ASCII 153 chars

English, Bahasa Melayu, and other Latin-script languages. Maximum 153 characters per SMS credit. Messages longer than 153 characters are split into multiple parts.

type = 2 — Unicode 63 chars

Chinese, Japanese, Arabic, Korean, and other non-ASCII scripts. Maximum 63 characters per SMS credit. Unicode encoding allows full international character support.

⚠️Messages exceeding the per-part character limit are automatically split and billed as multiple SMS credits. A counter in the iSMS portal shows how many credits your message will consume.

✉️ Send SMS

Pick the API that fits your integration. The JSON API sends up to 50 recipients — each with its own personalised message — in a single request and returns structured per-recipient results. The classic API uses form-encoded GET/POST with one shared message per call.

POST a single JSON body. Each entry in messages is delivered with its own text, in the same order in the response.

POST /isms_send_json.php  ·  application/json

Request Parameters (top level)

ParameterTypeRequiredDescription
unStringRequiredYour iSMS account username
pwdStringRequiredYour iSMS account password
typeStringRequiredEncoding: 1 = ASCII (English/BM) · 2 = Unicode (Chinese/Arabic)
messagesArrayRequiredArray of message objects (see below). Minimum 1, maximum 50 destination numbers total per request
agreedtermStringConditionalSet to YES to accept the iSMS Terms & Conditions, until the account has accepted the API terms. Otherwise rejected with -1013
sendidStringOptionalSender ID shown to recipient. Max 11 alphanumeric characters, no spaces or special characters
fidStringOptionalFeature ID for rate selection. Defaults to 5 when omitted
sendlaterStringOptionalSchedule for later delivery (date/time string). Leave empty to send immediately
imgurlStringOptionalImage URL — WhatsApp gateway accounts only

The messages Array

Each element carries its own destination and message body — enabling fully personalised content per recipient.

FieldTypeDescription
dstnoStringDestination number in international format, no + prefix (e.g. 6016xxxxxxx). Multiple numbers sharing one message may be separated by ; or , — every number counts toward the 50-number limit
msgStringThe SMS text body for this recipient
⚠️Maximum 50 destination numbers total per request. Exceeding this returns -1010. For larger campaigns, split the list across multiple calls.

Sample Request

JSONPOST body
POST /isms_send_json.php HTTP/1.1
Host: www.isms.com.my
Content-Type: application/json

{
  "un":         "myusername",
  "pwd":        "mypassword",
  "type":       "1",
  "sendid":     "MyCompany",
  "agreedterm": "YES",
  "messages": [
    { "dstno": "6016xxxxxxx", "msg": "Hi Ali, your order #123 is ready for pickup" },
    { "dstno": "6019xxxxxxx", "msg": "Hi Siti, your appointment is confirmed at 3pm" },
    { "dstno": "6017xxxxxxx", "msg": "Hi Kumar, payment of RM150 received. Thank you" }
  ]
}

PHP cURL Example

PHPsend_json.php
<?php
$payload = [
    "un"         => "myusername",
    "pwd"        => "mypassword",
    "type"       => "1",            // 1 = ASCII, 2 = Unicode
    "sendid"     => "MyCompany",   // Max 11 chars, optional
    "agreedterm" => "YES",
    "messages"   => [
        ["dstno" => "6016xxxxxxx", "msg" => "Hi Ali, your order #123 is ready"],
        ["dstno" => "6019xxxxxxx", "msg" => "Hi Siti, your appointment is at 3pm"]
    ]
];

$ch = curl_init("https://www.isms.com.my/isms_send_json.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

$result   = curl_exec($ch);
curl_close($ch);

$response = json_decode($result, true);
echo $response["message"];               // e.g. "2000 = SUCCESS"

foreach ($response["results"] as $r) {   // per-recipient outcome
    echo $r["dstno"] . " => " . $r["status"];
}
?>

Response Format

FieldTypeDescription
statusStringsuccess — all sent · partial — some failed · error — rejected / nothing sent
codeIntegerOverall code — 2000 on success/partial, negative error code otherwise
messageStringHuman-readable summary of the outcome
total_messagesIntegerNumber of message entries processed
total_successIntegerEntries accepted and pushed to the telco
total_failedIntegerEntries that failed validation or sending
total_credits_usedIntegerTotal SMS credits deducted for this request
resultsArrayPer-recipient results — each item has dstno, code, status, and sms_id (the TRX_ID on success)
ℹ️Credits are validated for the entire request before any message is sent. If the balance is insufficient for the full batch, the whole request is rejected with -1004 and nothing is sent.

Sample Responses

success — all messages sent
{ "status": "success", "code": 2000, "message": "2000 = SUCCESS", "total_messages": 2, "total_success": 2, "total_failed": 0, "total_credits_used": 2, "results": [ { "dstno": "6016xxxxxxx", "code": 2000, "status": "2000 = SUCCESS:1143007207|", "sms_id": "1143007207" }, { "dstno": "6019xxxxxxx", "code": 2000, "status": "2000 = SUCCESS:1143007209|", "sms_id": "1143007209" } ] }
partial — one number invalid
{ "status": "partial", "code": 2000, "message": "2000 = PARTIAL SUCCESS (1 SENT, 1 FAILED)", "total_messages": 2, "total_success": 1, "total_failed": 1, "total_credits_used": 1, "results": [ { "dstno": "6016xxxxxxx", "code": 2000, "status": "2000 = SUCCESS:1143007207|", "sms_id": "1143007207" }, { "dstno": "016xxx", "code": -1008, "status": "-1008 = MISSING PARAMETER" } ] }
error — request rejected (insufficient credits)
{ "status": "error", "code": -1004, "message": "-1004 = INSUFFICIENT CREDITS" }

Form-encoded parameters over GET or POST. One shared message per call; use ; to add recipients.

GETPOST /isms_send_all_id.php  ·  x-www-form-urlencoded

Request Parameters

ParameterTypeRequiredDescriptionExample
unStringRequiredYour iSMS account usernamemyusername
pwdStringRequiredYour iSMS account passwordmypassword
dstnoStringRequiredDestination phone number in international format — no + prefix601X-XXXXXXX
msgStringRequiredSMS message text — URL-encoded for GET requestsHello%20World
typeIntegerRequiredEncoding: 1 = ASCII (English/BM) · 2 = Unicode (Chinese/Arabic)1
agreedtermStringRequiredMust be YES — confirms acceptance of iSMS Terms & Conditions. Requests without this will be filtered.YES
sendidStringOptionalSender ID displayed to recipient. Max 11 alphanumeric characters. No spaces or special characters.MyCompany

HTTP GET Request

HTTPGET Request
GET /isms_send_all_id.php HTTP/1.1
Host: www.isms.com.my

?un=myusername
&pwd=mypassword
&dstno=601X-XXXXXXX
&msg=Hello%20World
&type=1
&sendid=MyCompany
&agreedterm=YES

HTTP POST Request (PHP cURL)

POST is recommended for production — it avoids URL length limits and is more secure than GET.

PHPisms_send_all_id.php
<?php
$params = [
    "un"         => "myusername",
    "pwd"        => "mypassword",
    "dstno"      => "601X-XXXXXXX",  // International format, no +
    "msg"        => "Hello World! Your OTP is 123456.",
    "type"       => "1",            // 1 = ASCII, 2 = Unicode
    "sendid"     => "MyCompany",   // Max 11 chars, optional
    "agreedterm" => "YES"
];

$ch = curl_init("https://www.isms.com.my/isms_send_all_id.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));

$result = curl_exec($ch);
curl_close($ch);

// Result format: "2000 = SUCCESS:1143007207" or "-1001" for errors
echo $result;
?>

Multiple Recipients (Semicolon-Separated)

PHPsend_multi.php
<?php
// Separate multiple recipients with semicolons — all receive the same message
$params = [
    "un"         => "myusername",
    "pwd"        => "mypassword",
    "dstno"      => "601X-XXXXXXX;601X-XXXXXXX;601X-XXXXXXX",
    "msg"        => "Your appointment reminder for tomorrow at 9am.",
    "type"       => "1",
    "sendid"     => "ClinicABC",
    "agreedterm" => "YES"
];

$ch = curl_init("https://www.isms.com.my/isms_send_all_id.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));

$result = curl_exec($ch);
curl_close($ch);
echo $result;
?>
ℹ️Need a different message per recipient? Use the JSON API tab above — it accepts an individual msg for each dstno in one call.

🏷️ Personalisation Tokens

Embed these tokens in any message body. Each is replaced with the matching field from your iSMS contact list (matched by phone number). If no contact record is found, the token is replaced with the recipient's phone number. Supported by both the JSON and classic APIs.

%name%Contact name
%hpno%Contact phone number
%email%Contact e-mail address
%dob%Contact date of birth
%desc%Contact description
ℹ️Example — "Hi %name%, your appointment is confirmed." becomes "Hi Ali, your appointment is confirmed."

💰 Check Balance — JSON POST

Retrieve the remaining SMS credit balance for a prepaid account.

POST /isms_balance_json.php  ·  application/json

Request Parameters

ParameterTypeRequiredDescription
unStringRequiredYour iSMS account username
pwdStringRequiredYour iSMS account password

Sample Request

JSONPOST body
POST /isms_balance_json.php HTTP/1.1
Host: www.isms.com.my
Content-Type: application/json

{
  "un":  "myusername",
  "pwd": "mypassword"
}

Sample Responses

success
{ "status": "success", "code": 0, "username": "myusername", "balance": "1500" }
error — authentication failed
{ "status": "error", "code": -1001, "message": "-1001 = AUTHENTICATION FAILED" }
⚠️Check Balance is available for Prepaid accounts only. Postpaid accounts receive an INVALID ACCOUNT TYPE response.

✅ API Response Codes

Every API request returns a response code. 2000 means the message was accepted and queued for delivery. All other codes indicate an error.

CodeDescription
2000SUCCESS:{TRX_ID} — Message submitted and pushed to Telco SMSC. TRX_ID is the unique transaction identifier. Note: does not confirm delivery to handset.
-1000Unknown Error — an unspecified server-side error occurred
-1001Authentication Failed — invalid username or password
-1002Account Suspended / Expired — the account is inactive or has expired
-1003IP Not Allowed — the originating IP address is not whitelisted for this account
-1004Insufficient Credits — not enough credits for the full request (validated before any message is sent)
-1005Invalid SMS Type — the type parameter is not 1 or 2
-1006Invalid Body Length — message body exceeds the allowed character limit
-1007Invalid Hex Body — Unicode hex-encoded message body is malformed
-1008Missing Parameter — a required parameter is absent, or a destination number is invalid
-1009Invalid Message Content — the message body contains filtered / prohibited content
-1010Maximum Destination Numbers Exceeded — more than 50 destination numbers in one request JSON
-1012Invalid Message Type — the message contains characters not valid for the selected encoding type
-1013Invalid Term and Agreement — agreedterm is not set to YES
-1014Invalid JSON Format — the request body could not be parsed as JSON JSON
-1015Invalid Request Method — the JSON endpoint accepts POST requests only JSON

📬 Delivery Status Callback (HTTP Push)

iSMS supports server-side delivery status notifications via HTTP Push. When a telco delivery update is received, the iSMS platform makes an HTTPS GET request to your callback URL with status parameters as query strings.

⚠️
Important — SMS Delivery Status Scope (Malaysia): All SMS delivery statuses (DELIVERED, ACCEPTED, SENT) reflect acknowledgement by the Telco SMSC (Short Message Service Centre) only — not delivery to the recipient's handset.

Malaysian telcos do not provide handset-level DLR by default. Handset delivery confirmation is available at extra cost per SMS charged by the telco. If you require confirmed Sent → Received → Read tracking at the handset level, we recommend using WhatsApp Business API (WABA) — which natively supports full message status callbacks including Sent, Delivered (received at handset), and Read.
ℹ️Configure your delivery callback URL in your iSMS account settings, or contact support to activate this feature.

Callback URL Format

https://{your-callbackurl}?msisdn={dstno}&trx_id={trx_id}&dn_status={status}

Example Callback

https://myapp.example.com/sms/status?msisdn=601X-XXXXXXX&trx_id=1143007207&dn_status=DELIVERED

Delivery Status Values

DELIVEREDAcknowledged by Telco SMSC. Does not confirm delivery to recipient's handset. Malaysia telcos do not provide handset DLR by default.
UNDELIVEREDDelivery failed — number invalid or unreachable
PENDINGSubmitted to iSMS platform — awaiting Telco SMSC acknowledgement.
ACCEPTED / SENTAccepted by Telco SMSC. Same scope as DELIVERED — confirms SMSC receipt only, not handset delivery.

PHP Callback Handler Example

PHPsms_callback.php
<?php
// iSMS Delivery Status Callback Handler
$msisdn    = $_GET['msisdn']    ?? '';    // Destination number
$trx_id    = $_GET['trx_id']    ?? '';    // Transaction ID
$dn_status = $_GET['dn_status'] ?? '';    // DELIVERED / UNDELIVERED / PENDING

if ($trx_id && $dn_status) {
    // Log to database
    $query = "UPDATE sms_log SET status='%s', updated_at=NOW() 
               WHERE trx_id='%s'";
    // Execute $query with $dn_status and $trx_id ...
    
    // Handle delivery outcomes
    if ($dn_status === 'DELIVERED') {
        // Mark as delivered in your system
    } elseif ($dn_status === 'UNDELIVERED') {
        // Alert or retry logic
    }
}

// Return 200 OK to acknowledge receipt
http_response_code(200);
echo "OK";
?>

🔄 Migrating from the Classic API

The JSON API keeps the same account credentials, sender IDs, credit billing, IP whitelisting, personalisation tokens, and response codes. Only the request and response shape change.

AspectClassic APIJSON API
MethodGET or POST (form-encoded)POST only (application/json)
Recipients per callMultiple numbers, one shared messageUp to 50 numbers, each with its own message
Personalised contentTokens only (%name%, …)Per-recipient message body + tokens
Response formatPlain textStructured JSON with per-recipient results
URL encodingRequired for msgNot required (JSON handles encoding)
Endpointisms_send_all_id.phpisms_send_json.php
ℹ️No account changes are needed — point your integration at isms_send_json.php and switch to a JSON body. Existing credentials, sender IDs, and whitelisted IPs continue to work.

Need SMS API Access or Integration Help?

Our developer team will whitelist your IP, provide test credentials, and guide you through your first integration.

📱 Contact Developer Support → View WABA API Docs
💬