NAV Navigation
CURL Go NodeJS PHP Python Ruby

NusaSMS API v1.0

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Please be noted that there are two API host, development (test) and production server.

Production

Host: https://api.nusasms.com

You can use this host to make real transaction.

Grab your APIKey on app.nusasms.com, on Account > User management menu.

API Usage Notes

Development /Test (Currently inactive)

Development (testing), which user’s client credit top up is for testing only. Any result of this API (this host) is not real. Credit top up is not required on this server host.

On this server, an account (and only one) is being provided to user the API. The APIKey for this test server is DEV_TESTING_API_KEY. Please use the APIkey kindly.

Response

Success

HTTP Response Code, either 200, 201, 202 or 204 and error=false on the json response is success request.

Failed / Error

All neither 200, 201 nor 204 HTTP response code is failed response.

HTTP Status Code

Response Content Type

IP Whitelist

To be able to use NusaSMS API, you must register your IP address to be whitelisted.

Follow this steps to register your IP Address.

  1. Login app.nusasms.com
  2. Go to Account menu then choose IP Whitelist menu.
  3. Click the add button (the blue button with plus icon)
  4. Fill the fields and make sure to check the Active mark.
  5. Click Save and close

IP Whitelist configuration

Authentication

APIKey

Get user data using API Key

GET /nusasms_api/1.0/auth/api_key

BASE_URL=https://api.nusasms.com
# BASE_URL=https://dev.nusasms.com # For testing

curl ${BASE_URL}/nusasms_api/1.0/auth/api_key \
-H "APIKey: {YOUR_APIKEY}" \
-H 'Content-Type: application/json' \
# --insecure # Ignore SSL Verification
import requests

BASE_URL = "https://api.nusasms.com/nusasms_api/1.0"
# For testing
# BASE_URL = "https://dev.nusasms.com/nusasms_api/1.0"
HEADERS = {
"Accept": "application/json",
"APIKey": "{YOUR_API_KEY}"
}

r = requests.get(
f'{BASE_URL}/auth/api_key',
headers=HEADERS,
# verify=False # Skip SSL Verification
)

print(r.json())
package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"APIKey": []string{" YOUR_API_KEY "},
}
url := "https://api.nusasms.com/nusasms_api/1.0/auth/api_key"
// For testing
// url := "https://dev.nusasms.com/nusasms_api/1.0/auth/api_key"

req, _ := http.NewRequest("GET", url, nil)
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)

if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)

fmt.Println(string(body))
// ...
}
<?php
$BASE_URL = "https://api.nusasms.com/nusasms_api/1.0/auth/api_key";

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPHEADER => array(
'APIKey: {YOUR_API_KEY}',
'Content-Type: application/json'
),
CURLOPT_URL => $BASE_URL,

// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);
echo $resp;
curl_close($curl);
const axios = require('axios');

const headers = {
'Accept':'application/json',
'APIKey':'YOUR_API_KEY'
};
const url = 'https://api.nusasms.com/nusasms_api/1.0/auth/api_key'
// Test host
//const url = 'https://dev.nusasms.com/nusasms_api/1.0/auth/api_key'

axios.get(url, {headers: headers})
.then(function(response) {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY'
}
url = 'https://api.nusasms.com/nusasms_api/1.0/auth/api_key'
# Dev host
# url = 'https://dev.nusasms.com/nusasms_api/1.0/auth/api_key'

result = RestClient.get(url, headers=headers)

puts JSON.parse(result)

Example responses

200 Response

{
"error": false,
"message": "Data message",
"data": {
"userid": "string",
"idPerson": 0,
"idClient": 0
}
}

Responses

Status Meaning Description Schema
200 OK Successful Response PersonResponse

Account

Get Balance Data

GET /nusasms_api/1.0/balance

BASE_URL=https://api.nusasms.com/nusasms_api/1.0
# For testing
# BASE_URL=https://dev.nusasms.com/nusasms_api/1.0

curl -X GET "${BASE_URL}/balance" \
-H "accept: application/json" \
-H "Content-type: application/json" \
-H "APIKey: {YOUR_API_KEY}"
# --insecure # Ignore SSL Verification
<?php
$BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0/balance';
// For test
// $BASE_URL = 'https://dev.nusasms.com/nusasms_api/1.0/balance';

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $BASE_URL,
CURLOPT_HTTPHEADER => array(
"APIKey: {YOUR_API_KEY}",
'Accept: application/json',
'Content-Type: application/json'
),
CURLOPT_RETURNTRANSFER => 1,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);
echo $resp;
curl_close($curl);
import requests

BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0'
# For testing
# BASE_URL = 'https://dev.nusasms.com/nusasms_api/1.0'
HEADERS = {
"Accept": "application/json",
"APIKey": "YOUR_API_KEY"
}

r = requests.get(
f'{BASE_URL}/balance',
headers=HEADERS,
# Skip SSL Verification
# verify = False
)

print(r.json())
package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"APIKey": []string{" YOUR_API_KEY "},
}
url := "https://api.nusasms.com/nusasms_api/1.0/balance"
// For testing
// url := "https://dev.nusasms.com/nusasms_api/1.0/balance"

req, _ := http.NewRequest("GET", url, nil)
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)

if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
// ...
}
const axios = require('axios');

const headers = {
'Accept':'application/json',
'APIKey':'YOUR_API_KEY'
};
const url = 'https://api.nusasms.com/nusasms_api/1.0/balance'
// Test host
//const url = 'https://dev.nusasms.com/nusasms_api/1.0/balance'

axios.get(url, {headers})
.then(function(response) {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY'
}
url = 'https://api.nusasms.com/nusasms_api/1.0/balance'
# Dev host
# url = 'https://dev.nusasms.com/nusasms_api/1.0/balance'

result = RestClient.get(url, headers=headers)

puts JSON.parse(result)

Example responses

200 Response

{
"error": false,
"message": "Data message",
"data": {
"idClient": 0,
"wa_balance": 0,
"wa_expired_date": "2019-08-24",
"hlr_balance": 0,
"hlr_expired_date": "2019-08-24",
"sim_balance": 0,
"sim_expired_date": "2019-08-24",
"sms_balance": 0,
"sms_expired_date": "2019-08-24",
"pulsa_balance": 0
}
}

Responses

Status Meaning Description Schema
200 OK Successful Response CreditResponse

WhatsApp Official

Introduction

Whatsapp Official API helps to use WhatsApp Business API. You can send message using a message template by your channel (Whatsapp Account).

Usage flow

Rate Limit

Terminology

Types of Message

1. Broadcast Message

A message template is required to send broadcast message. You can send this message to anyone regarding either your recipient is valid Whatsapp account or not.

After the recipient reply your broadcast message, you will get a room. This room is assigned to your channel. room_id is going to be used to send reply message or interactive reply message.

For more information please see Send Broadcast Message section.

2. Reply Message

After getting room_id, you can send custom message without template, thus you will explicitly use previous channel which you use on broadcast message.

room_id is required to send reply message. You can get room_id from your Inbox after the recipient reply your broadcast message. room_id is active in 24 hours since is the the message recipient reply to broadcase message.

For more information please see Send Reply Message section.

3. Interactive Reply Message (Coming soon)

Interactive Reply Message is extension of reply message that allows to send custom message with interactive buttons which also require room_id.

Send Broadcast Message

POST /nusasms_api/1.0/wa_official/message/broadcast

# Template: "Your OTP Code is 1
# Sent message by this code: "Your OTP Code is CODE"

BASE_URL=https://api.nusasms.com/nusasms_api/1.0

curl -X POST "${BASE_URL}/wa_official/message/broadcast" \
-H 'Content-type: application/json' \
-H "Accept: application/json" \
-H "APIKey: {YOUR_API_KEY}" \
-d '{
"destination": "YOUR_DESTINATION",
"destination_name": "DESTINATION/RECIPIENT NAME",
"template_id": "YOUR-TEMPLATE-UUID",
"channel_id": "YOUR-CHANNEL-UUID",
"parameters": {
"body": [
{
"key": "1",
"value": "code",
"value_text": "CODE"
}
]
}
}'

# --insecure # Ignore SSL Verification
<?php

/*
Template: "Your OTP Code is 1""
Sent message by this code: "Your OTP Code is VARIABLE_VALUE"
*/


$URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/message/broadcast';

$curl = curl_init();
$payload = json_encode(array(
'destination' => '628xxxxxxxxxx',
'destination_name' => 'DESTINATION/RECIPIENT NAME',
'template_id' => 'YOUR-TEMPLATE-UUID',
'channel_id' => 'YOUR-CHANNEL-UUID',
'parameters' => array(
'body' => array(
array(
'key' => '1',
'value' => 'VARIABLE_NAME',
'value_text' => 'VARIABLE_VALUE'
)
),
)
));
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $URL,
// For testing
// CURLOPT_URL => $BASE_TEST_URL,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array(
"APIKey: YOUR_API_KEY",
'Content-Type:application/json'
),
CURLOPT_POSTFIELDS => $payload,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);

if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
echo $resp;
}
curl_close($curl);
import requests

BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0'
HEADERS = {
"Accept": "application/json",
"APIKey": "YOUR_API_KEY"
}
PAYLOADS = {
'destination': '628xxxxxxxxxx',
"destination_name": "DESTINATION/RECIPIENT NAME",
"template_id": "YOUR-TEMPLATE-UUID",
"channel_id": "YOUR-CHANNEL-UUID",
"parameters": {
"header": {
"format": "DOCUMENT",
"params": [
{
"key": "url",
"value": "https://buildmedia.readthedocs.org/media/pdf/read-the-docs/latest/read-the-docs.pdf"
},
{
"key": "filename",
"value": "example.pdf"
}
]
},
"body": [
{'key': 1, 'value': 'code', 'value_text': 'CODE'},
],
"buttons": [
{
"index": "0",
"type": "url",
"value": "/url_endpoint?arg1=value"
}
]
}
}

r = requests.post(
f'{BASE_URL}/wa_official/message/broadcast',
headers=HEADERS,
json=PAYLOADS,
# Skip SSL Verification
# verify=False
)

print(r.json())
package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

/*
Template: "Your OTP Code is 1""
Sent message by this code: "Your OTP Code is CODE"
*/

func main() {
headers := map[string][]string {
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"APIKey": []string{"YOUR_API_KEY"},
}

param_header := []map[string]interface{} {
map[string]interface{}{
"key": "1", "value": "code", "value_text": "CODE",
},
}
payload, _ := json.Marshal(map[string]interface{} {
"destination": "62822344641960",
"destination_name": "Any name",
"template_id": "65a08d56-a2b9-45f5-98d3-98671e639055",
"channel_id": "15974c27-3116-49f4-8627-5fc30b0c66d8",
"parameters": map[string]interface{} {
"body": params_body,
},
})
url := "https://api.nusasms.com/nusasms_api/1.0/wa_official/message/broadcast"

req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
// ...
}
const axios = require('axios');

/*
Template: "Your OTP Code is 1""
Sent message by this code: "Your OTP Code is FIRST_PARAM"
*/


const headers = {
Accept: 'application/json',
APIKey: 'YOUR_API_KEY'
};
var data = {
destination: '628xxxxxxxxxx',
destination_name: 'DESTINATION/RECIPIENT NAME',
template_id: "YOUR-TEMPLATE-UUID",
channel_id: "YOUR-CHANNEL-UUID",
parameters: {
body: [
{"key": "1", "value": "otp_code", "value_text": "FIRST_PARAM"}
]
}
}
const url = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/message/broadcast'

axios.post(url, data, {headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
require 'rest-client'
require 'json'

# Template: "Your OTP Code is 1""
# Sent message by this code: "Your OTP Code is VARIABLE_VALUE"

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY',
'Content-Type' => 'application/json',
}
payloads = {
'destination' => '628xxxxxxxxxx',
'destination_name' => 'DESTINATION/RECIPIENT NAME',
'template_id' => 'YOUR-TEMPLATE-UUID',
'channel_id' => 'YOUR-CHANNEL-UUID',
'parameters' => {
'body' => [
{
'key' => '1',
'value' => 'VARIABLE_NAME',
'value_text' => 'VARIABLE_VALUE'
}
]
}
}
base_url = 'https://api.nusasms.com/nusasms_api/1.0'

response = RestClient::Request.new({
method: :post,
url: base_url + '/wa_official/message/broadcast',
payload: payloads.to_json,
headers: headers
}).execute do |response, request, result|
case response.code
# Success
when 201
[ :success, puts(response.to_str) ]
when 400
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 403
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 422
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
else
[
:error,
puts("Failed response=#{response.to_str}")
]
end
end

This endpoint allows you to send Whatsapp message using a template message.

API Parameters

Type of parameters Parameter Value

Body parameter

{
"destination": "string",
"destination_name": "string",
"template_id": "string",
"channel_id": "string",
"parameters": {
"property1": [
null
],
"property2": [
null
]
}
}

Parameters

Name In Type Required Description
body body BroadcastMessageParam true none

Example responses

201 Response

{
"error": false,
"message": "Send broadcast message",
"data": {
"ref_no": "string"
}
}

Responses

Status Meaning Description Schema
201 Created Successful Response BroadcastMessageResponse
422 Unprocessable Entity Validation Error HTTPValidationError

Send Reply Message

POST /nusasms_api/1.0/wa_official/message/reply

package main

import (
"bytes"
"fmt"
"io/ioutil"
"mime/multipart"
"net/http"
)

const url := "https://api.nusasms.com/nusasms_api/1.0/wa_official/message/reply"

func main() {
payload := &bytes.Buffer{}
writer := multipart.NewWriter(payload)
writer.WriteField("room_id", "YOUR-ROOM-UUID")
// writer.WriteField("type", "text")
writer.WriteField("text", "Your text here")
err := writer.Close()
if err != nil {
panic(err)
}

req, err := http.NewRequest("POST", url, payload)

req.Header.Add("Content-Type", writer.FormDataContentType())
req.Header.Add("APIKey", "YOUR_API_KEY")

client := &http.Client{}

resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
const axios = require('axios');
const fs = require('fs');

const url = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/message/reply'
const headers = {
'Accept': 'application/json',
'APIKey': 'YOUR_API_KEY',
'Content-Type': 'multipart/form-data'
};
var data = {
room_id: 'YOUR-ROOM-UUID',
type: 'image',
file: fs.createReadStream('/home/username/your-path/to-file.png'),
text: 'Image caption'
}

axios.post(url, data, {headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
<?php

$APIKEY = 'YOUR_API_KEY';
$URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/message/reply';

$curl = curl_init();
$payload = array(
'room_id' => 'YOUR-ROOM-ID',
'text' => 'test message'
);
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $URL,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array(
"APIKey: " . $APIKEY,
'Content-Type: multipart/form-data'
),
CURLOPT_POSTFIELDS => $payload,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);

if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
echo $resp;
}
curl_close($curl);
import requests

BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0'
HEADERS = {
"Accept": "application/json",
"APIKey": "YOUR_API_KEY"
}
PAYLOADS = {
'room_id': 'YOUR-ROOM-ID',
'type': 'text',
'text': 'Teks anda di sini'
}

r = requests.post(
f'{BASE_URL}/wa_official/message/reply',
headers=HEADERS,
data=PAYLOADS,
# Skip SSL Verification
# verify=False
)

print(r.json())
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY',
'Content-Type' => 'application/json',
}
payloads = {
'room_id' => 'YOUR-ROOM-ID',
'text' => 'test message'
}
base_url = 'https://api.nusasms.com/nusasms_api/1.0'

response = RestClient::Request.new({
method: :post,
url: base_url + '/wa_official/message/reply',
payload: payloads,
headers: headers
}).execute do |response, request, result|
case response.code
# Success
when 201
[ :success, puts(response.to_str) ]
when 400
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 403
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 422
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
else
[
:error,
puts("Failed response=#{response.to_str}")
]
end
end
 BASE_URL=https://api.nusasms.com/nusasms_api/1.0

curl -X POST "${BASE_URL}/wa_official/message/reply" \
-H "Accept: application/json" \
-H "APIKey: YOUR_API_KEY" \
--form 'type="text"' \
--form 'text="Contoh text"' \
--form 'room_id="YOUR-ROOM-UUID"'
# --insecure # Ignore SSL Verification

Send custom message without a template.

Parameters

Body parameter

room_id: string
type: text
file_url: http://example.com
text: string

Parameters

Name In Type Required Description
body body Body_send_reply_message_nusasms_api_1_0_wa_official_message_reply_post true none

Example responses

201 Response

{
"error": false,
"message": "Send reply message",
"data": {
"ref_no": "string"
}
}

Responses

Status Meaning Description Schema
201 Created Successful Response ReplyMessageResponse
422 Unprocessable Entity Validation Error HTTPValidationError

Get Templates

GET /nusasms_api/1.0/wa_official/templates

package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"APIKey": []string{"YOUR_API_KEY"},
}

url := "https://api.nusasms.com/nusasms_api/1.0/wa_official/templates"
req, err := http.NewRequest("GET", url, nil)
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
const axios = require('axios');

const headers = {
'Accept':'application/json',
'APIKey':'YOUR_API_KEY'
};
const url = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/templates'

axios.get(url, {headers: headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
BASE_URL=https://api.nusasms.com/nusasms_api/1.0

curl -X GET "${BASE_URL}/wa_official/templates" \
-H "accept: application/json" \
-H "APIKey: YOUR_API_KEY"
# --insecure # Ignore SSL Verification
<?php
$URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/templates';

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $URL,
CURLOPT_HTTPHEADER => array(
"APIKey: YOUR_API_KEY",
'Content-Type:application/json'
),
CURLOPT_RETURNTRANSFER => 1,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);
if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
echo $resp;
}
curl_close($curl);
import requests

URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/templates'

HEADERS = {
"Accept": "application/json",
"APIKey": "YOUR_API_KEY"
}

r = requests.get(
URL, headers=HEADERS,
# Skip SSL Verification
# verify=False
)

print(r.json())
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY'
}
url = 'https://api.nusasms.com/nusasms_api/1.0'

result = RestClient.get(
url + '/wa_official/templates',
headers=headers
)

puts JSON.parse(result)

This endpoint show you list of your message templates.

Template need to be approved if you want to use it to send message. If you need to use new template, you will need to submit the template.

Therefore there are different statuses of template.

Example responses

200 Response

{
"error": false,
"message": "Templates",
"data": [
{
"id": "string",
"name": "string",
"header": null,
"body": null,
"footer": null,
"status": "string",
"category": "string"
}
]
}

Responses

Status Meaning Description Schema
200 OK Successful Response GetTemplatesResponse

Get Channels

GET /nusasms_api/1.0/wa_official/channels

BASE_URL=https://api.nusasms.com/nusasms_api/1.0

curl -X GET "${BASE_URL}/wa_official/channels" \
-H "accept: application/json" \
-H "APIKey: YOUR_API_KEY"
# --insecure # Ignore SSL Verification
<?php
$URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/channels';

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $URL,
CURLOPT_HTTPHEADER => array(
"APIKey: YOUR_API_KEY",
'Content-Type:application/json'
),
CURLOPT_RETURNTRANSFER => 1,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);
if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
echo $resp;
}
curl_close($curl);
import requests

URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/channels'

HEADERS = {
"Accept": "application/json",
"APIKey": "YOUR_API_KEY"
}

r = requests.get(
URL, headers=HEADERS,
# Skip SSL Verification
# verify=False
)

print(r.json())
package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"APIKey": []string{"YOUR_API_KEY"},
}

url := "https://api.nusasms.com/nusasms_api/1.0/wa_official/channels"
req, err := http.NewRequest("GET", url, nil)
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
const axios = require('axios');

const headers = {
'Accept':'application/json',
'APIKey':'YOUR_API_KEY'
};
const url = 'https://api.nusasms.com/nusasms_api/1.0/wa_official/channels'

axios.get(url, {headers: headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY'
}
url = 'https://api.nusasms.com/nusasms_api/1.0'

result = RestClient.get(
url + '/wa_official/channels',
headers=headers
)

puts JSON.parse(result)

Channel is your Whatsapp Gateway/Sender which going to be used to send message to your destination. User may have more multiple channels.

This endpoint will show you list of your Channel.

Example responses

200 Response

{
"error": false,
"message": "Channels",
"data": [
{
"id": "string",
"webhook": "string",
"settings": null,
"organization_id": "string",
"created_at": "2019-08-24T14:15:22Z"
}
]
}

Responses

Status Meaning Description Schema
200 OK Successful Response GetChannelsResponse

Callback

<?php

$myfile = fopen("callback.txt", "w") or die("Unable to open file!");
$data = file_get_contents("php://input");

fwrite($myfile, "callback data: " . $data . PHP_EOL);
fclose($myfile);
# This script is need to be run on a Server with
# public IP or Domain

import json
from flask import Flask, request, current_app

app = Flask(__name__)


@app.route('/callback_delivery_status', methods=['POST'])
def get_push_callback():
callback_data = request.get_json()
current_app.logger.info(f'Message status data: {callback_data}')
# You might want to process the callback data here
return json.dumps(callback_data)


@app.route('/callback_inbox', methods=['POST'])
def callback_inbox():
callback_data = request.get_json()
current_app.logger.info(f'Inbox data: {callback_data}')
# You might want to process the callback data here
return json.dumps(callback_data)

You can collect your Message Status and Inbox by registering your Callback URL.

Go to WA Official > Account from side menu to setting your callback URL.

Account Callback Setting

Message Status

Callback data

Callback JSON Request Example

{
    "ref_no": "YOUR_MESSAGE_REF_NO",
    "status": "read",
    "status_date": "2022-08-12 10:22:50"
}

Inbox

Callback data

Callback JSON Request Example

{
    "room_id": "xxxx-fb79-xxxx-b19e-546f761dfebf",
    "ref_no": "XXXX05224010031105891853",
    "text": "Pesan inbox",
    "inbox_date": "2022-08-12 10:50:13",
    "sender_number": "628XXXXXXXX"
}

WhatsApp

Introduction

Account Settings

Information

Tutorial Video: Send Message using PHP (Bahasa Indonesia)

Whatsapp Message Status

Code Name Description
Q QUEUE Message is on Queue to be proceed
S SENT Message is on process to be sent to the destination
D DELIVERED Message has been delivered
R READ Message has been read on destination side
A ABORT Message has been aborted and not going to be sent anymore
F FAILED Message is not sent. Issue may vary

Emoticons

Source: Full Emoji List

Use the emoji code as API message parameter examples

Emoticons Name Unicode As Message Parameter
😀 Grinning face U+1F600 “message”: “\\U0001F600”
🇮🇩 flag: Indonesia U+1F1EE U+1F1E9 “message”: “\\U0001F1EE\\U0001F1E9”

Send Media

POST /nusasms_api/1.0/whatsapp/media

BASE_URL=https://api.nusasms.com/nusasms_api/1.0
# For testing
# BASE_URL=https://dev.nusasms.com/nusasms_api/1.0

curl -X POST "${BASE_URL}/whatsapp/media" \
-H 'Content-type: application/json; charset=utf-8' \
-H "Accept: application/json" \
-H "APIKey: {YOUR_API_KEY}" \
-d "{
\"queue\": \"{YOUR_QUEUE}\",
\"destination\": \"628xxxxxxxxxx\",
\"caption\": \"Caption text\",
\"media_url\": \"https://example.com/image_name.png\",
\"include_unsubscribe\": true
}"

# --insecure # Ignore SSL Verification
# Parameter `sender` is optional
import base64

import requests

BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0'
# For testing
# BASE_URL = 'https://dev.nusasms.com/nusasms_api/1.0'

with open('file_name.png', 'rb') as file_descriptor:
file_data = file_descriptor.read()

base64_file = base64.b64encode(file_data).decode('utf8')

headers = {
"Accept": "application/json",
"APIKey": "{YOUR_API_KEY}"
}
payloads = {
'destination': '628xxxxxxxxxx',
# QUeue is optional
'queue': 'YOUR_SENDER',
'media_base64': base64_file,
'file_name': 'your_image_file.png',
'caption': 'Caption text',
'include_unsubscribe': True
}

# Send file with base64 encoded file
r = requests.post(
f'{BASE_URL}/whatsapp/media',
headers=headers,
json=payloads,
# verify=False # Skip SSL Verification
)

print(r.json())
<?php
$BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0/whatsapp/media';
$BASE_TEST_URL = 'https://dev.nusasms.com/nusasms_api/1.0/whatsapp/media';

$curl = curl_init();

$payload = json_encode(array(
'caption' => 'Caption text',
// Queue is optional
'queue' => 'YOUR_QUEUE',
'destination' => '628xxxxxxxxxx',
'media_url' => 'https://example.com/image_name.png',
'include_unsubscribe' => true,
));

curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $BASE_URL,
// For testing
// CURLOPT_URL => $BASE_TEST_URL,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array(
"APIKey: {YOUR_API_KEY}",
'Content-Type: application/json'
),
CURLOPT_POSTFIELDS => $payload,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);

if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
echo $resp;
}
curl_close($curl);
package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"APIKey": []string{"YOUR_API_KEY"},
}
payload, _ := json.Marshal(map[string]interface{}{
// Optional
// "queue": " YOUR_QUEUE ",
"destination": "628xxxxxxxxxx",
"caption": "Caption text",
"media_url": "https://example.com/image_name.png",
"include_unsubscribe": true,
})
url := "https://api.nusasms.com/nusasms_api/1.0/whatsapp/media"
// For testing
// url := "https://dev.nusasms.com/nusasms_api/1.0/whatsapp/media"

req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
// ...
}
const axios = require('axios');

const headers = {
Accept: 'application/json',
APIKey: 'YOUR_API_KEY'
};
var data = {
destination: '628xxxxxxxxxx',
// Sender is optional
queue: 'YOUR_QUEUE',
caption: 'Caption text',
media_url: 'https://example.com/your-image.png',
include_unsubscribe: true,
}
const url = 'https://api.nusasms.com/nusasms_api/1.0/whatsapp/media'
// Test host
//const url = 'https://dev.nusasms.com/nusasms_api/1.0/whatsapp/media'

axios.post(url, data, {headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY',
'Content-Type' => 'application/json',
}
payloads = {
'destination' => '628xxxxxxxxxx',
# Queue is optional
'queue' => 'YOUR_QUEUE',
'caption' => 'Caption text',
'media_url' => 'https://example.com/your-image.png',
'include_unsubscribe' => true,
}
base_url = 'https://api.nusasms.com/nusasms_api/1.0'
# Dev host
# base_url = 'https://dev.nusasms.com/nusasms_api/1.0'

response = RestClient::Request.new({
method: :post,
url: base_url + '/whatsapp/media',
payload: payloads.to_json,
headers: headers
}).execute do |response, request, result|
case response.code
# Success
when 201
[ :success, puts(response.to_str) ]
when 400
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 403
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 422
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
else
[
:error,
puts("Failed response=#{response.to_str}")
]
end
end

Warning

Note

Body parameter

{
"timeout": 86400,
"queue": "string",
"is_group": false,
"destination": "string",
"channel": 0,
"include_unsubscribe": false,
"sender": "string",
"caption": "string",
"media_url": "http://example.com",
"file_name": "string",
"media_base64": "string"
}

Parameters

Name In Type Required Description
body body SendMediaParams true none

Example responses

201 Response

{
"error": false,
"message": "Data message",
"data": {
"sender": "string",
"queue": "string",
"destination": "string",
"ref_no": "string",
"caption": "string",
"media_url": "string"
}
}

Responses

Status Meaning Description Schema
201 Created Successful Response SendMediaResponse
422 Unprocessable Entity Validation Error HTTPValidationError

Send Message

POST /nusasms_api/1.0/whatsapp/message

BASE_URL=https://api.nusasms.com/nusasms_api/1.0
# For testing
# BASE_URL=https://dev.nusasms.com/nusasms_api/1.0

curl -X POST "${BASE_URL}/whatsapp/message" \
-H 'Content-type: application/json; charset=utf-8' \
-H "Accept: application/json" \
-H "APIKey: YOUR_API_KEY" \
-d "{
\"destination\": \"628xxxxxxxxxx\",
\"message\": \"Message text\"
\"include_unsubscribe\": true
}"

# --insecure # Ignore SSL Verification
# Parameter `sender` is optional
<?php
$BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0/whatsapp/message';
// $BASE_TEST_URL = 'https://dev.nusasms.com/nusasms_api/1.0/whatsapp/message';

$curl = curl_init();
$payload = json_encode(array(
// 'queue' => 'YOUR_SENDER',
'destination' => '628xxxxxxxxxx',
'message' => 'Your message',
'include_unsubscribe' => true,
));
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $BASE_URL,
// For testing
// CURLOPT_URL => $BASE_TEST_URL,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array(
"APIKey: YOUR_API_KEY",
'Content-Type:application/json'
),
CURLOPT_POSTFIELDS => $payload,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);

if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
echo $resp;
}
curl_close($curl);
import requests

BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0'
# For testing
# BASE_URL = 'https://dev.nusasms.com/nusasms_api/1.0'

HEADERS = {
"Accept": "application/json",
"APIKey": "YOUR_API_KEY"
}
PAYLOADS = {
'destination': '628xxxxxxxxxx',
# Optional
'queue': 'YOUR_QUEUE',
'message': "your message here.\\nGrinning face emoticon: \\\\U0001F600",
'include_unsubscribe': True
}

r = requests.post(
f'{BASE_URL}/whatsapp/message',
headers=HEADERS,
json=PAYLOADS,
# Skip SSL Verification
# verify=False
)

print(r.json())
package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"APIKey": []string{"YOUR_API_KEY"},
}
payload, _ := json.Marshal(map[string]interface{}{
// Queue is optional
// "queue": "YOUR_QUEUE",
"destination": "628xxxxxxxxxx",
"message": "Message text",
"include_unsubscribe": true
})
url := "https://api.nusasms.com/nusasms_api/1.0/whatsapp/message"
// For testing
// url := "https://dev.nusasms.com/nusasms_api/1.0/whatsapp/message"

req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
// ...
}
const axios = require('axios');

const headers = {
Accept: 'application/json',
APIKey: 'YOUR_API_KEY'
};
var data = {
// queue: 'YOUR_QUEUE',
destination: '628xxxxxxxxxx',
message: 'Message text',
include_unsubscribe: true,
}
const url = 'https://api.nusasms.com/nusasms_api/1.0/whatsapp/message'
// Test host
//const url = 'https://dev.nusasms.com/nusasms_api/1.0/whatsapp/message'

axios.post(url, data, {headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY',
'Content-Type' => 'application/json',
}
payloads = {
# 'queue' => 'YOUR_QUEUE',
'destination' => '628xxxxxxxxxx',
'message' => 'Message text',
'include_unsubscribe' => true
}
base_url = 'https://api.nusasms.com/nusasms_api/1.0'

response = RestClient::Request.new({
method: :post,
url: base_url + '/whatsapp/message',
payload: payloads.to_json,
headers: headers
}).execute do |response, request, result|
case response.code
# Success
when 201
[ :success, puts(response.to_str) ]
when 400
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 403
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
when 422
[
:error,
puts("Failed status_code=#{response.code} response=#{response.to_str}")
]
else
[
:error,
puts("Failed response=#{response.to_str}")
]
end
end

Note

Body parameter

{
"timeout": 86400,
"queue": "string",
"is_group": false,
"destination": "string",
"channel": 0,
"include_unsubscribe": false,
"sender": "string",
"message": "string"
}

Parameters

Name In Type Required Description
body body SendMessageParams true none

Example responses

201 Response

{
"error": false,
"message": "Data message",
"data": {
"sender": "string",
"queue": "string",
"destination": "string",
"ref_no": "string",
"message": "string"
}
}

Responses

Status Meaning Description Schema
201 Created Successful Response SendMessageResponse
422 Unprocessable Entity Validation Error HTTPValidationError

Message Info

GET /nusasms_api/1.0/whatsapp/status/{ref_no}

BASE_URL=https://api.nusasms.com/nusasms_api/1.0
# For testing
# BASE_URL=https://dev.nusasms.com/nusasms_api/1.0

curl -X GET "${BASE_URL}/whatsapp/status/{MESSAGE_REF_NO}" \
-H "accept: application/json" \
-H "APIKey: {YOUR_API_KEY}"
# --insecure # Ignore SSL Verification
<?php
$BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0/whatsapp/status';
$BASE_TEST_URL = 'https://dev.nusasms.com/nusasms_api/1.0/whatsapp/stasus';

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $BASE_URL . '/{MESSAGE_REF_NO}',
CURLOPT_HTTPHEADER => array(
"APIKey: {YOUR_API_KEY}",
'Content-Type:application/json'
),
CURLOPT_RETURNTRANSFER => 1,
// CURLOPT_SSL_VERIFYPEER => 0, // Skip SSL Verification
));

$resp = curl_exec($curl);
if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
echo $resp;
}
curl_close($curl);
import requests

BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0'
# For testing
# BASE_URL = 'https://dev.nusasms.com/nusasms_api/1.0'

HEADERS = {
"Accept": "application/json",
"APIKey": "{YOUR_API_KEY}"
}

r = requests.get(
f'{BASE_URL}/whatsapp/status/',
headers=HEADERS,
# Skip SSL Verification
# verify=False
)

print(r.json())
package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {

headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"APIKey": []string{"YOUR_API_KEY"},
}

url := "https://api.nusasms.com/nusasms_api/1.0/whatsapp/status/{MESSAGE_REF_NO}"
// For testing
// url := "https://dev.nusasms.com/nusasms_api/1.0/whatsapp/status/{YOUR_REF_NO}"

req, err := http.NewRequest("GET", url, nil)
req.Header = headers

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}

body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
// ...
}
const axios = require('axios');

const headers = {
'Accept':'application/json',
'APIKey':'YOUR_API_KEY'
};
const url = 'https://api.nusasms.com/nusasms_api/1.0/whatsapp/status'
// Test host
//const url = 'https://dev.nusasms.com/nusasms_api/1.0/whatsapp/status'
var ref_no = 'MESSAGE_REF_NO'

axios.get(url + '/' + ref_no, {headers: headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
if (error.response) {
console.error(error.response.data)
} else if (error.request) {
console.error(error.request)
} else {
console.error(error.message);
}
});
require 'rest-client'
require 'json'

headers = {
'Accept' => 'application/json',
'APIKey' => 'YOUR_API_KEY'
}
url = 'https://api.nusasms.com/nusasms_api/1.0'
# Dev host
# url = 'https://dev.nusasms.com/nusasms_api/1.0'

result = RestClient.get(
url + '/whatsapp/status/MESSAGE_REF_NO',
headers=headers
)

puts JSON.parse(result)

Whatsapp message status

Status Name Description
U UN-SENT Message is going to be added to queue
Q QUEUE Message is on queue (going to be sent)
S SENT Message is being sent
D DELIVERED Message is delivered to destination
R READ Message has been read
A ABORTED Message is aborted (will not be sent)
F FAILED Fail to save Message (WA Credit deduction will be reverted)

Note: if you set your own sender, please consider to set push callback to get immediate report of your message status to your server. Please contact support to set your push callback.

Test status on Test Server, with ref_no namely listed below:

Parameters

Name In Type Required Description
ref_no path string true none

Example responses

200 Response

{
"error": false,
"message": "Data message",
"data": {
"destination": "string",
"sender": "string",
"is_group": false,
"create_date": "2019-08-24T14:15:22Z",
"sent_date": "2019-08-24T14:15:22Z",
"read_date": "2019-08-24T14:15:22Z",
"delivered_date": "2019-08-24T14:15:22Z",
"ref_no": "string",
"status": "string",
"message": "string",
"caption": "string",
"media_url": "string"
}
}

Responses

Status Meaning Description Schema
200 OK Successful Response GetMessageResponse
422 Unprocessable Entity Validation Error HTTPValidationError

Delivery Status Callback

# This script is need to be run on a Server with
# public IP or Domain

import json
from flask import Flask, request

app = Flask(__name__)

@app.route('/your_DR_callback_url', methods=['GET', 'POST'])
def get_push_callback():
callback_data = {
'ref_no': request.args.get('ref_no'),
'status': request.args.get('status'),
'sent_date': request.args.get('sent_date'),
'err_code': request.args.get('err_code'),
}
# You might want to save the result to DB or else here
return json.dumps(callback_data)
<?php

/* This script is need to be run on a Server with
* public IP or Domain
*/


$ref_no = $_GET["ref_no"];
$status = $_GET["status"];
$sent_date = $_GET["sent_date"];
$err_code = $_GET["err_code"];

# you can write your code here, for example if you want to write the data to a file;
$myfile = fopen("callback.txt", "w") or die("Unable to open file!");

fwrite($myfile, "Ref No: " . $ref_no . PHP_EOL);
fwrite($myfile, "Status: " . $status . PHP_EOL);
fwrite($myfile, "Sent Date: " . $sent_date . PHP_EOL);
fwrite($myfile, "Error Code: " . $err_code . PHP_EOL);
fclose($myfile);

?>

Another method for collecting Delivery Status / Message status is by registering URL Call Back API in menu Account Setting on your web app account https://app.nusasms.com.

Open Account > Account Settings from side menu.

Account Settings

Push DR URL Form

More documentation for Delivery Status Callback: https://nusasms.com/sms-api/

Push Inbox

Inbox message can be retrieved via push inbox.

Callback HTTP Request Info

# This script is need to be run on a Server with
# public IP or Domain

import json
from flask import Flask, request

app = Flask(__name__)

@app.route('/your_callback_url', methods=['POST'])
def get_push_callback():
callback_data = {
'id': request.form.get('id'),
'gateway_no': request.form.get('gateway_number'),
'sender': request.form.get('originator'),
'receive_date': request.form.get('receive_date'),
'message': request.form.get('msg'),
}
# You might want to save the result to DB or else here
return json.dumps(callback_data)
/* This script is need to be run on a Server with
* public IP or Domain
*/

$id = $_POST["id"];
$gateway_no = $_POST["gateway_number"];
$sender = $_POST["originator"];
$receive_date = $_POST["receive_date"];
$message = $_POST["msg"];

# you can write your code here, for example if you want to write the data to a file;
$myfile = fopen("inbox.txt", "w") or die("Unable to open file!");

fwrite($myfile, "ID: " . $id . PHP_EOL);
fwrite($myfile, "Gateway No: " . $gateway_no . PHP_EOL);
fwrite($myfile, "Sender: " . $sender . PHP_EOL);
fwrite($myfile, "Receive Date: " . $receive_date . PHP_EOL);
fwrite($myfile, "Message: " . $message . PHP_EOL);
fclose($myfile);

Set your Push URL to let us notify you of your WA message inbox.

Set Up

SMS

Note

Response Status

Status Value Description
ALL_RECIPIENTS_PROCESSED 0 Request was successful (all recipients)
SEND_ERROR -1 Error in processing the request
NOT_ENOUGH_CREDITS -2 Not enough credits on a specific account
NETWORK_NOTCOVERED -3 Targeted network is not covered on specific account
AUTHENTICATION_FAILED -5 Username or password is invalid
MISSING_DESTINATION_ADDRESS -6 Destination address is missing in the request
BALANCE_EXPIRED -7 Balance has expired
NO_ROUTE -9 Routing not found for specific operator
REJECTED -10 OTP messages that do not use an OTP route will be REJECTED
UNKNOWN_DESTINATION_ADDRESS -11 Number is not recognized by NusaSMS platform
MISSING_MESSAGE -12 Message is missing in the request
INVALID_DESTINATION_ADDRESS -13 Invalid Destination Address
SMS_TEXT_TOO_LONG -14 SMS text to long
SYNTAX_ERROR -22 Incorrect XML format, caused by syntax error
ERROR_PROCESSING -23 General error, reasons may vary
INVALID_API_COMMAND -24 Invalid API Command
COMMUNICATION_ERROR -26 General API error, reasons may vary
INVALID_SENDDATETIME -27 Invalid scheduling parametar
INVALID_DELIVERY_REPORT_PUSH_URL -28 Invalid PushURL in the request
INVALID_CLIENT_APPID -30 Invalid APPID in the request
RECORD_NOT_FOUND -31 Record not found
MISSING_MESSAGE_ID -32 Message ID is missing in request
DUPLICATE_MESSAGEID -33 Duplicated MessageID in the request
SENDER_NOT_ALLOWED -34 Sender name is not allowed
SENDER_NOT_REGISTERED -35 Sender not registered
SENDER_NOT_SET -36 Sender not set for user/account
IP_ADDRESS_FORBIDDEN -40 Client IP Address Not In White List
SPAM_PATTERN -77 Sending messages to the same number has reached the limit in 24 hours
LIMIT REACHED FOR DESTINATION NUMBER -78 Sending messages to the same number has reached the limit in 24 hours
REJECTED ROUTE -88 Operator Rejected The Request
GENERAL_ERROR -99 Error in processing request, reasons may vary

Send Plain

POST /sms/v3/sendsms/plain

package main

import (
"fmt"
"net/http"
"io/ioutil"
)

func main() {

url := "https://api.nusasms.com/api/v3/sendsms/plain" +
"?user=YOUR_USERNAME" +
"&password=YOUR_PASSWORD" +
"&SMSText=SMS_TEXT" +
"&GSM=DESTINATION_NUMBER" +
"&output=json"
method := "POST"

client := &http.Client {
}
req, err := http.NewRequest(method, url, nil)

if err != nil {
fmt.Println(err)
return
}
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://api.nusasms.com/api/v3/sendsms/plain',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'user' => 'username',
'password' => 'password',
'SMSText' => 'This is an example code using PHP.',
'GSM' => '6281572610701'
)
));
$resp = curl_exec($curl);
if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
header('Content-type: text/xml'); /*if you want to output to be an xml*/
echo $resp;
}
curl_close($curl);
?>
url = "https://api.nusasms.com/api/v3/sendsms/plain"
apikey = "apikey"

headers = {"Accept": 'application/json'}
payload = {
"SMSText": "This is an example code using Python.",
"GSM": "6281234xxxxxx",
"output": "json",
"user": "YOUR_USERNAME",
"password": "password"
}

try:
response = requests.post(url, headers=headers, data=payload)
print("RESPONSE: %s" % response.text)
except requests.exceptions.RequestException as e:
print("ERROR: %s" % e)
require "uri"
require "net/http"

url = URI(
"https://api.nusasms.com/api/v3/sendsms/plain"\
"?user=YOUR_USERNAME"\
"&password=YOUR_PASSWORD"\
"&SMSText=SMS_TEXT"\
"&GSM=DESTINATION_NUMBER"\
"&output=json"
)

req = Net::HTTP.new(url.host, url.port)
req.use_ssl = true
request = Net::HTTP::Post.new(url)

response = req.request(request)
puts response.read_body

Notes

Parameters

Parameter Required Description
user Your API username
password You API Password
SMSText Text message (160 characters)
GSM GMS recipient number in intenational format (e.g: 62810000XXXX)
unicode True for unicode message
otp Y for OTP message
output json or xml (default)

Parameterized URL Examples

Plain SMS:

https://api.nusasms.com/api/v3/sendsms/plain?user=user&password=password&SMSText=Hello%20NusaSMS!&GSM=628*********

Plain SMS (JSON Response):

https://api.nusasms.com/api/v3/sendsms/plain?user=user&password=password&SMSText=Kode%20OTP%20anda%20xxxxxx&GSM=628********&otp=Y&output=json

OTP SMS:

https://api.nusasms.com/api/v3/sendsms/plain?user=user&password=password&SMSText=Hello%20NusaSMS!&GSM=628********&otp=Y

Success Response Examples

XML

<?xml version="1.0" encoding="UTF-8"?>
<results>
     <result>
          <status>0</status>
          <messageid>175041319203754627</messageid>
          <destination>6285100803380</destination>
     </result>
</results>

JSON

{
    "results": [{
        "status": "0", "messageid": "175041319203754627",
        "destination": "628510080XXXX"
    }]
}

Wrong User / Password Response

XML

<?xml version="1.0" encoding="UTF-8"?>
<results>
     <result>
          <status>-5</status>
          <messageid></messageid>
          <destination>6285100803380</destination>
     </result>
</results>

JSON

{
    "results": [{
        "status": "-5",
        "messageid": "",
        "destination": "6285100803380"
    }]
}

Missing Destination Number Response

XML

<?xml version="1.0" encoding="UTF-8"?> 
  <results> 
     <result> 
       <status>-13</status> 
       <messageid></messageid> 
       <destination>085100803380</destination> 
    </result>
</results>

JSON

{
    "results": [{
        "status": "-13", 
        "messageid": "", 
        "destination": "6285100803380"
    }]
}

Parameters

Name In Type Required Description
user query string true none
password query string true none
SMSText query string true none
unicode query string false none
GSM query string false none
otp query string false none

Example responses

200 Response

null

Responses

Status Meaning Description Schema
200 OK Successful Response Inline
422 Unprocessable Entity Validation Error HTTPValidationError

Response Schema

Send Group

POST /sms/v3/sendsms/group

package main

import (
"fmt"
"net/http"
"io/ioutil"
)

func main() {

url := "https://api.nusasms.com/api/v3/sendsms/group" +
"?user=YOUR_USERNAME" +
"&password=YOUR_PASSWORD" +
"&SMSText=SMS_TEXT" +
"&group=GROUP_NAME" +
"&output=json"
method := "POST"

client := &http.Client {
}
req, err := http.NewRequest(method, url, nil)

if err != nil {
fmt.Println(err)
return
}
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://api.nusasms.com/api/v3/sendsms/group',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'user' => 'username',
'password' => 'password',
'SMSText' => 'This is an example code using PHP.',
'group' => 'EXAMPLE_GROUP'
)
));
$resp = curl_exec($curl);
if (!$resp) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
} else {
header('Content-type: text/xml'); /*if you want to output to be an xml*/
echo $resp;
}
curl_close($curl);
?>
url = "https://api.nusasms.com/api/v3/sendsms/group"

headers = {"Accept": 'application/json'}
payload = {
"SMSText": "This is an example code using Python.",
"group": "EXAMPLE_GROUP",
"output": "json",
"user": "YOUR_USERNAME",
"password": "password"
}

try:
response = requests.post(url, headers=headers, data=payload)
print("RESPONSE: %s" % response.text)
except requests.exceptions.RequestException as e:
print("ERROR: %s" % e)
require "uri"
require "net/http"

url = URI(
"https://api.nusasms.com/api/v3/sendsms/group"\
"?user=YOUR_USERNAME"\
"&password=YOUR_PASSWORD"\
"&SMSText=SMS_TEXT"\
"&group=GROUP_NAME"\
"&output=json"
)

req = Net::HTTP.new(url.host, url.port)
req.use_ssl = true
request = Net::HTTP::Post.new(url)

response = req.request(request)
puts response.read_body

Notes

Parameters

Parameter Required Description
user Your API username
password You API Password
SMSText Text message (160 characters)
group Contacts Group name
unicode True for unicode message
otp Y for OTP message
output json or xml (default)

Parameterized URL Example

https://api.nusasms.com/api/v3/sendsms/group?user=user&password=password&SMSText=Hello%20NusaSMS!&group=Example

Result Example

XML

<?xml version="1.0" encoding="UTF-8"?>
<results>
  <result>
    <status>0</status>
    <campaign_name>Group-Api-Campaign-cf27252-5101</campaign_name>
    <group>Example</group>
  </result>
</results>

JSON

{
    "results": [{
        "status": "0", 
        "campaign_name": "Group-Api-Campaign-cf27252-5101",
        "group": "Example"
    }]
}

Failed Response

Group is not available or the group has no contact list

XML

<?xml version="1.0" encoding="UTF-8"?>
<results>
    <result>
      <status>-55</status>
      <campaign_name>Group-Api-Campaign-cf27252-5101</campaign_name>
      <group>Example</group>
    </result>
</results>

JSON

{
    "results": [{
        "status": "-55", 
        "campaign_name": "Group-Api-Campaign-cf27252-5101", 
        "group": "Example"
    }]
}

Parameters

Name In Type Required Description
user query string true none
password query string true none
SMSText query string true none
unicode query string false none
group query string false none
otp query string false none

Example responses

200 Response

null

Responses

Status Meaning Description Schema
200 OK Successful Response Inline
422 Unprocessable Entity Validation Error HTTPValidationError

Response Schema

Delivery Status Callback

# This script is need to be run on a Server with
# public IP or Domain

import json
from flask import Flask, request

app = Flask(__name__)

@app.route('/your_DR_callback_url')
def get_push_callback():
callback_data = {
'ref_no': request.args.get('ref_no'),
'status': request.args.get('status'),
'sent_date': request.args.get('sent_date'),
'err_code': request.args.get('err_code'),
}
# You might want to save the result to DB or else here
return json.dumps(callback_data)
<?php

/* This script is need to be run on a Server with
* public IP or Domain
*/


$ref_no = $_GET["ref_no"];
$status = $_GET["status"];
$sent_date = $_GET["sent_date"];
$err_code = $_GET["err_code"];

# you can write your code here, for example if you want to write the data to a file;
$myfile = fopen("callback.txt", "w") or die("Unable to open file!");

fwrite($myfile, "Ref No: " . $ref_no . PHP_EOL);
fwrite($myfile, "Status: " . $status . PHP_EOL);
fwrite($myfile, "Sent Date: " . $sent_date . PHP_EOL);
fwrite($myfile, "Error Code: " . $err_code . PHP_EOL);
fclose($myfile);

?>

Another method for collecting Delivery Status / Message status is by registering URL Call Back API in menu Account Setting on your web app account https://app.nusasms.com.

Open Account > Account Settings from side menu.

Account Settings

Push DR URL Form

More documentation for Delivery Status Callback: https://nusasms.com/sms-api/

Push Inbox

import json
from flask import Flask, request

app = Flask(__name__)

@app.route('/your_callback_url', methods=['POST'])
def get_push_callback():
callback_data = {
'id': request.form.get('id'),
'gateway_no': request.form.get('gateway_number'),
'sender': request.form.get('originator'),
'receive_date': request.form.get('receive_date'),
'message': request.form.get('msg'),
}
# You might want to save the result to DB or else here
return json.dumps(callback_data)
<?php

/* This script is need to be run on a Server with
* public IP or Domain
*/


$id = $_POST["id"];
$gateway_no = $_POST["gateway_number"];
$sender = $_POST["originator"];
$receive_date = $_POST["receive_date"];
$message = $_POST["msg"];

# you can write your code here, for example if you want to
# write the data to a file;
$myfile = fopen("inbox.txt", "w") or die("Unable to open file!");

fwrite($myfile, "ID: " . $id . PHP_EOL);
fwrite($myfile, "Gateway No: " . $gateway_no . PHP_EOL);
fwrite($myfile, "Sender: " . $sender . PHP_EOL);
fwrite($myfile, "Receive Date: " . $receive_date . PHP_EOL);
fwrite($myfile, "Message: " . $message . PHP_EOL);
fclose($myfile);

Set your SMS Push URL to let us notify you (via HTTP) when SMS is coming.

Set Up

Changelog

2023-09-26

Updated

2023-09-16

Updated

2023-03-03

Updated

v1.0 (2022-10-19)

Updated

v1.0 (2022-08-09)

Added

Changed

v1.0 (2022-07-20)

Added

v1.0 (2021-11-17)

Added

v1.0 (2021-10-18)

Added

v1.0

Changed

v0.x

Added

Schemas

Body_send_reply_message_nusasms_api_1_0_wa_official_message_reply_post

{
"room_id": "string",
"type": "text",
"file_url": "http://example.com",
"text": "string"
}

Body_send_reply_message_nusasms_api_1_0_wa_official_message_reply_post

Properties

Name Type Required Restrictions Description
room_id string(uuid4) true none none
type ReplyMessageType false none An enumeration.
file_url string(uri) false none none
text string false none none

BroadcastMessage

{
"ref_no": "string"
}

BroadcastMessage

Properties

Name Type Required Restrictions Description
ref_no string true none none

BroadcastMessageParam

{
"destination": "string",
"destination_name": "string",
"template_id": "string",
"channel_id": "string",
"parameters": {
"property1": [
null
],
"property2": [
null
]
}
}

BroadcastMessageParam

Properties

Name Type Required Restrictions Description
destination string true none none
destination_name string true none none
template_id string(uuid4) true none none
channel_id string(uuid4) true none none
parameters object false none none
» additionalProperties any false none none

anyOf

Name Type Required Restrictions Description
»» anonymous [any] false none none

or

Name Type Required Restrictions Description
»» anonymous object false none none

BroadcastMessageResponse

{
"error": false,
"message": "Send broadcast message",
"data": {
"ref_no": "string"
}
}

BroadcastMessageResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data BroadcastMessage true none none

Channel

{
"id": "string",
"webhook": "string",
"settings": null,
"organization_id": "string",
"created_at": "2019-08-24T14:15:22Z"
}

Channel

Properties

Name Type Required Restrictions Description
id string(uuid4) true none none
webhook string false none none
settings any false none none
organization_id string(uuid4) true none none
created_at string(date-time) true none none

Credit

{
"idClient": 0,
"wa_balance": 0,
"wa_expired_date": "2019-08-24",
"hlr_balance": 0,
"hlr_expired_date": "2019-08-24",
"sim_balance": 0,
"sim_expired_date": "2019-08-24",
"sms_balance": 0,
"sms_expired_date": "2019-08-24",
"pulsa_balance": 0
}

Credit

Properties

Name Type Required Restrictions Description
idClient integer true none none
wa_balance number false none none
wa_expired_date string(date) false none none
hlr_balance number false none none
hlr_expired_date string(date) false none none
sim_balance number false none none
sim_expired_date string(date) false none none
sms_balance number false none none
sms_expired_date string(date) false none none
pulsa_balance number false none none

CreditResponse

{
"error": false,
"message": "Data message",
"data": {
"idClient": 0,
"wa_balance": 0,
"wa_expired_date": "2019-08-24",
"hlr_balance": 0,
"hlr_expired_date": "2019-08-24",
"sim_balance": 0,
"sim_expired_date": "2019-08-24",
"sms_balance": 0,
"sms_expired_date": "2019-08-24",
"pulsa_balance": 0
}
}

CreditResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data Credit true none none

GetChannelsResponse

{
"error": false,
"message": "Channels",
"data": [
{
"id": "string",
"webhook": "string",
"settings": null,
"organization_id": "string",
"created_at": "2019-08-24T14:15:22Z"
}
]
}

GetChannelsResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data [Channel] false none none

GetMessage

{
"destination": "string",
"sender": "string",
"is_group": false,
"create_date": "2019-08-24T14:15:22Z",
"sent_date": "2019-08-24T14:15:22Z",
"read_date": "2019-08-24T14:15:22Z",
"delivered_date": "2019-08-24T14:15:22Z",
"ref_no": "string",
"status": "string",
"message": "string",
"caption": "string",
"media_url": "string"
}

GetMessage

Properties

Name Type Required Restrictions Description
destination string false none none
sender string false none none
is_group boolean false none none
create_date string(date-time) false none none
sent_date string(date-time) false none none
read_date string(date-time) false none none
delivered_date string(date-time) false none none
ref_no string false none none
status string false none none
message string false none none
caption string false none none
media_url string false none none

GetMessageResponse

{
"error": false,
"message": "Data message",
"data": {
"destination": "string",
"sender": "string",
"is_group": false,
"create_date": "2019-08-24T14:15:22Z",
"sent_date": "2019-08-24T14:15:22Z",
"read_date": "2019-08-24T14:15:22Z",
"delivered_date": "2019-08-24T14:15:22Z",
"ref_no": "string",
"status": "string",
"message": "string",
"caption": "string",
"media_url": "string"
}
}

GetMessageResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data GetMessage true none none

GetTemplatesResponse

{
"error": false,
"message": "Templates",
"data": [
{
"id": "string",
"name": "string",
"header": null,
"body": null,
"footer": null,
"status": "string",
"category": "string"
}
]
}

GetTemplatesResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data [Template] false none none

HTTPValidationError

{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}

HTTPValidationError

Properties

Name Type Required Restrictions Description
detail [ValidationError] false none none

Person

{
"userid": "string",
"idPerson": 0,
"idClient": 0
}

Person

Properties

Name Type Required Restrictions Description
userid string true none none
idPerson integer true none none
idClient integer true none none

PersonResponse

{
"error": false,
"message": "Data message",
"data": {
"userid": "string",
"idPerson": 0,
"idClient": 0
}
}

PersonResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data Person true none none

ReplyMessageResponse

{
"error": false,
"message": "Send reply message",
"data": {
"ref_no": "string"
}
}

ReplyMessageResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data BroadcastMessage true none none

ReplyMessageType

"audio"

ReplyMessageType

Properties

Name Type Required Restrictions Description
ReplyMessageType string false none An enumeration.

Enumerated Values

Property Value
ReplyMessageType audio
ReplyMessageType document
ReplyMessageType image
ReplyMessageType text
ReplyMessageType video
ReplyMessageType voice

SendMedia

{
"sender": "string",
"queue": "string",
"destination": "string",
"ref_no": "string",
"caption": "string",
"media_url": "string"
}

SendMedia

Properties

Name Type Required Restrictions Description
sender string false none none
queue string false none none
destination string true none none
ref_no string true none none
caption string false none none
media_url string false none none

SendMediaParams

{
"timeout": 86400,
"queue": "string",
"is_group": false,
"destination": "string",
"channel": 0,
"include_unsubscribe": false,
"sender": "string",
"caption": "string",
"media_url": "http://example.com",
"file_name": "string",
"media_base64": "string"
}

SendMediaParams

Properties

Name Type Required Restrictions Description
timeout integer false none none
queue string false none none
is_group boolean false none none
destination string true none none
channel integer false none none
include_unsubscribe boolean false none none
sender string false none none
caption string false none none
media_url string(uri) false none none
file_name string false none none
media_base64 string false none none

SendMediaResponse

{
"error": false,
"message": "Data message",
"data": {
"sender": "string",
"queue": "string",
"destination": "string",
"ref_no": "string",
"caption": "string",
"media_url": "string"
}
}

SendMediaResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data SendMedia true none none

SendMessage

{
"sender": "string",
"queue": "string",
"destination": "string",
"ref_no": "string",
"message": "string"
}

SendMessage

Properties

Name Type Required Restrictions Description
sender string false none none
queue string false none none
destination string true none none
ref_no string true none none
message string false none none

SendMessageParams

{
"timeout": 86400,
"queue": "string",
"is_group": false,
"destination": "string",
"channel": 0,
"include_unsubscribe": false,
"sender": "string",
"message": "string"
}

SendMessageParams

Properties

Name Type Required Restrictions Description
timeout integer false none none
queue string false none none
is_group boolean false none none
destination string true none none
channel integer false none none
include_unsubscribe boolean false none none
sender string false none none
message string true none none

SendMessageResponse

{
"error": false,
"message": "Data message",
"data": {
"sender": "string",
"queue": "string",
"destination": "string",
"ref_no": "string",
"message": "string"
}
}

SendMessageResponse

Properties

Name Type Required Restrictions Description
error boolean false none none
message string false none none
data SendMessage true none none

Template

{
"id": "string",
"name": "string",
"header": null,
"body": null,
"footer": null,
"status": "string",
"category": "string"
}

Template

Properties

Name Type Required Restrictions Description
id string(uuid4) true none none
name string true none none
header any false none none
body any false none none
footer any false none none
status string true none none
category string true none none

ValidationError

{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}

ValidationError

Properties

Name Type Required Restrictions Description
loc [anyOf] true none none

anyOf

Name Type Required Restrictions Description
» anonymous string false none none

or

Name Type Required Restrictions Description
» anonymous integer false none none

continued

Name Type Required Restrictions Description
msg string true none none
type string true none none