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.
Table of Contents
-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.
https://www.isms.com.my/isms_send_json.phpRecommendedhttps://ww3.isms.com.my/isms_send_json.phpRecommendedhttps://smtpapi.vocotext.com/isms_send_json.phphttps://smtpapi2.vocotext.com/isms_send_json.phphttps://www.isms.com.my/isms_balance_json.phphttps://www.isms.com.my/isms_send_all_id.phpRecommendedhttps://smtpapi2.vocotext.com/isms_send_all_id.phpRecommendedhttps://smtpapi.vocotext.com/isms_send_all_id.phphttps://ww3.isms.com.my/isms_send_all_id.phpPOST 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.
English, Bahasa Melayu, and other Latin-script languages. Maximum 153 characters per SMS credit. Messages longer than 153 characters are split into multiple parts.
Chinese, Japanese, Arabic, Korean, and other non-ASCII scripts. Maximum 63 characters per SMS credit. Unicode encoding allows full international character support.
✉️ 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.
Request Parameters (top level)
| Parameter | Type | Required | Description |
|---|---|---|---|
| un | String | Required | Your iSMS account username |
| pwd | String | Required | Your iSMS account password |
| type | String | Required | Encoding: 1 = ASCII (English/BM) · 2 = Unicode (Chinese/Arabic) |
| messages | Array | Required | Array of message objects (see below). Minimum 1, maximum 50 destination numbers total per request |
| agreedterm | String | Conditional | Set to YES to accept the iSMS Terms & Conditions, until the account has accepted the API terms. Otherwise rejected with -1013 |
| sendid | String | Optional | Sender ID shown to recipient. Max 11 alphanumeric characters, no spaces or special characters |
| fid | String | Optional | Feature ID for rate selection. Defaults to 5 when omitted |
| sendlater | String | Optional | Schedule for later delivery (date/time string). Leave empty to send immediately |
| imgurl | String | Optional | Image URL — WhatsApp gateway accounts only |
The messages Array
Each element carries its own destination and message body — enabling fully personalised content per recipient.
| Field | Type | Description |
|---|---|---|
| dstno | String | Destination 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 |
| msg | String | The SMS text body for this recipient |
-1010. For larger campaigns, split the list across multiple calls.Sample Request
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
<?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
| Field | Type | Description |
|---|---|---|
| status | String | success — all sent · partial — some failed · error — rejected / nothing sent |
| code | Integer | Overall code — 2000 on success/partial, negative error code otherwise |
| message | String | Human-readable summary of the outcome |
| total_messages | Integer | Number of message entries processed |
| total_success | Integer | Entries accepted and pushed to the telco |
| total_failed | Integer | Entries that failed validation or sending |
| total_credits_used | Integer | Total SMS credits deducted for this request |
| results | Array | Per-recipient results — each item has dstno, code, status, and sms_id (the TRX_ID on success) |
-1004 and nothing is sent.Sample Responses
Form-encoded parameters over GET or POST. One shared message per call; use ; to add recipients.
Request Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| un | String | Required | Your iSMS account username | myusername |
| pwd | String | Required | Your iSMS account password | mypassword |
| dstno | String | Required | Destination phone number in international format — no + prefix | 601X-XXXXXXX |
| msg | String | Required | SMS message text — URL-encoded for GET requests | Hello%20World |
| type | Integer | Required | Encoding: 1 = ASCII (English/BM) · 2 = Unicode (Chinese/Arabic) | 1 |
| agreedterm | String | Required | Must be YES — confirms acceptance of iSMS Terms & Conditions. Requests without this will be filtered. | YES |
| sendid | String | Optional | Sender ID displayed to recipient. Max 11 alphanumeric characters. No spaces or special characters. | MyCompany |
HTTP GET 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.
<?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)
<?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; ?>
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"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.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| un | String | Required | Your iSMS account username |
| pwd | String | Required | Your iSMS account password |
Sample Request
POST /isms_balance_json.php HTTP/1.1
Host: www.isms.com.my
Content-Type: application/json
{
"un": "myusername",
"pwd": "mypassword"
}Sample Responses
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.
| Code | Description |
|---|---|
| 2000 | SUCCESS:{TRX_ID} — Message submitted and pushed to Telco SMSC. TRX_ID is the unique transaction identifier. Note: does not confirm delivery to handset. |
| -1000 | Unknown Error — an unspecified server-side error occurred |
| -1001 | Authentication Failed — invalid username or password |
| -1002 | Account Suspended / Expired — the account is inactive or has expired |
| -1003 | IP Not Allowed — the originating IP address is not whitelisted for this account |
| -1004 | Insufficient Credits — not enough credits for the full request (validated before any message is sent) |
| -1005 | Invalid SMS Type — the type parameter is not 1 or 2 |
| -1006 | Invalid Body Length — message body exceeds the allowed character limit |
| -1007 | Invalid Hex Body — Unicode hex-encoded message body is malformed |
| -1008 | Missing Parameter — a required parameter is absent, or a destination number is invalid |
| -1009 | Invalid Message Content — the message body contains filtered / prohibited content |
| -1010 | Maximum Destination Numbers Exceeded — more than 50 destination numbers in one request JSON |
| -1012 | Invalid Message Type — the message contains characters not valid for the selected encoding type |
| -1013 | Invalid Term and Agreement — agreedterm is not set to YES |
| -1014 | Invalid JSON Format — the request body could not be parsed as JSON JSON |
| -1015 | Invalid 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.
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.
Callback URL Format
Example Callback
Delivery Status Values
PHP Callback Handler Example
<?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.
| Aspect | Classic API | JSON API |
|---|---|---|
| Method | GET or POST (form-encoded) | POST only (application/json) |
| Recipients per call | Multiple numbers, one shared message | Up to 50 numbers, each with its own message |
| Personalised content | Tokens only (%name%, …) | Per-recipient message body + tokens |
| Response format | Plain text | Structured JSON with per-recipient results |
| URL encoding | Required for msg | Not required (JSON handles encoding) |
| Endpoint | isms_send_all_id.php | isms_send_json.php |
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.