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.

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

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

WhatsApp Business

Introduction

Usage flow

Rate Limit

Type of Message

Message Template

WhatsApp message templates allow businesses to use pre-approved templates to send structured messages to customers who have opted in to receive notifications.

Message template is devided in 4 parts:

Template creation limitation:

Message Status

Message status for message is sent, delivered, read, and failed.

Send Broadcast Message

POST /nusasms_api/1.0/wa_business/broadcast

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"},
}

param_header := map[string]string {
"type": "image",
"link": "https://link.to/yourimage.png",
}
param_body := []interface{} {
map[string]string { "type": "text", "text": "your text" },
map[string]string { "type": "text", "text": "your text again" },
}
// param_buttons := []interface{} {
// map[string]interface{} {},
// }
payload, _ := json.Marshal(map[string]interface{} {
"recipient": "DESTINATION_PHONE_NUMBER",
"gateway_id": "PHONE_NUMBER_ID",
"template": map[string]string {
"name": "TEMPLATE_NAME",
"language": "TEMPLATE_LANGUAGE_CODE",
},
"header": param_header,
"body": param_body,
// "bottons": param_buttons,
})
url := "https://api.nusasms.com/nusasms_api/1.0/wa_business/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');

const headers = {
Accept: 'application/json',
APIKey: 'YOUR_API_KEY'
};
var data = {
gateway_id: "GATEWAY_ID",
recipient: "RECIPIENT_ID",
template: {
language: "LANG_CODE",
name: "TEMPLATE_NAME"
},
header: {
type: "document",
link: "https://link.to/your-document.pdf"
},
body: [
{ "type": "text", "text": "your text for param 1" },
{ "type": "text", "text": "your text for param 2" },
],
buttons: [
{
sub_type: "quick_reply",
index: 1,
parameters: [
{
type: "payload",
payload: "PAYLOAD"
}
]
}
]
}

const URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_business/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);
}
});
<?php

$BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_business/broadcast';

$curl = curl_init();
$payload = json_encode(array(
'recipient' => 'RECIPIENT',
'gateway_id' => 'GATEWAY_ID',
'template' => array(
'language' => 'LANG_CODE',
'name' => 'TEMPLATE_NAME',
),
'header' => array(
array(
"type" => "text",
"text" => "Text for param 1 on header",
),
array(
"type" => "text",
"text" => "Text for param 2 on header",
)
)
));

echo $payload . "\n";

curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $BASE_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);
echo $resp;
import requests

BASE_URL = 'https://api.nusasms.com'
URL = f'{BASE_URL}/nusasms_api/1.0/wa_business/broadcast'
HEADERS = {"APIKey": "DEV_TESTING_API_KEY"}

PAYLOADS = {
"recipient": "RECIPIENT",
"gateway_id": "GATEWAY_ID",
"template": {
"language": "LANG_CODE",
"name": "TEMPLATE_NAME"
},
"body": [
{ "type": "text", "text": "your text for param 1" },
{ "type": "text", "text": "your text for param 2" }
],
"buttons": [
{
"sub_type": "quick_reply",
"index": 1,
"parameters": [
{ "type": "payload", "payload": "PAYLOAD" }
]
}
]
}
r = requests.post(URL, json=PAYLOADS, headers=HEADERS)
print(r.json())
require 'rest-client'
require 'json'

headers = {
'APIKey' => 'DEV_TESTING_API_KEY',
'Content-Type' => 'application/json'
}
payloads = {
'recipient' => 'RECIPIENT',
'gateway_id' => 'GATEWAY_ID',
'template': {
'language' => 'LANG_CODE',
'name' => 'TEMPLATE_NAME'
},
'body' => [
{
"type" => "text",
"text" => "Text for param 1 on body",
},
{
"type" => "text",
"text" => "Text for param 2 on body",
}
]
}

base_url = 'https://api.nusasms.com/nusasms_api/1.0'

response = RestClient::Request.new({
method: :post,
url: base_url + '/wa_business/broadcast',
payload: payloads.to_json,
headers: headers
}).execute do |response, request, result|
case response.code
# Success
when 201
[ :success, puts(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
URL=https://api.nusasms.com/nusasms_api/1.0/wa_business/broadcast

curl -X 'POST' $URL \
-H 'Accept: application/json' \
-H 'APIKey: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"recipient": "RECIPIENT",
"gateway_id": "GATEWAY_ID",
"template": {
"language": "LANG_CODE",
"name": "TEMPLATE_NAME"
},
"body": [
{ "type": "text", "text": "your text for param 1" },
{ "type": "text", "text": "your text for param 2" }
],
"buttons": [
{
"sub_type": "quick_reply",
"index": 1,
"parameters": [
{ "type": "payload", "payload": "PAYLOAD" }
]
}
]
}'

Broadcast message can be sent using pre-approved template. A template message parameters consists of message part, namely:

Media file is provided via header. The media file types that are allowed are document, image and video. Only one media header is allowed per message.

Apart from media you can have a message title that can use multiple text parameters.

Media (image, video and document)

Text

body

You can include multiple text parameters on the body upon requesting template.

buttons

There are 2 types of button on message template

Actions

Action buttons parameter is only for dynamic URL Button. The value of the parameter (text) is developer-provided suffix that is appended to the predefined prefix URL in the template.

Quick Reply

Body parameter

{
"recipient": "string",
"gateway_id": "string",
"template": {
"name": "string",
"language": "string"
},
"header": {
"type": "image",
"link": "http://example.com",
"filename": "string"
},
"body": [
{
"type": "text",
"text": "string"
}
],
"buttons": [
{
"sub_type": "QUICK_REPLY",
"parameters": {
"type": "payload",
"payload": "string"
},
"index": 2
}
]
}

Parameters

Name In Type Required Description
body body TemplateParam true none

Example responses

200 Response

{
"error": false,
"message": "Data message",
"data": {
"message_id": "string"
}
}

Responses

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

Send Reply Message

POST /nusasms_api/1.0/wa_business/reply

Send reply message

Text

Image (Coming soon)

Location (Coming soon)

Body parameter

{
"recipient": "RECIPIENT",
"gateway_id": "YOUR_GATEWAY_ID",
"type": "text",
"payloads": {
"body": "text example"
}
}

Parameters

Name In Type Required Description
body body ReplyParameter true none

Example responses

200 Response

{
"error": false,
"message": "Data message",
"data": {
"message_id": "string"
}
}

Responses

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

Send Otp Message

POST /nusasms_api/1.0/wa_business/otp

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{} {
"recipient": "DESTINATION_PHONE_NUMBER",
"gateway_id": "PHONE_NUMBER_ID",
"language": "TEMPLATE_LANGUAGE_CODE",
"otp": "YOUR OTP CODE"
})
url := "https://api.nusasms.com/nusasms_api/1.0/wa_business/otp"

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 = {
gateway_id: "GATEWAY_ID",
recipient: "RECIPIENT_ID",
language: "LANG_CODE",
otp: "YOUR OTP CODE"
}

const URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_business/otp'

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

$BASE_URL = 'https://api.nusasms.com/nusasms_api/1.0/wa_business/otp';

$curl = curl_init();
$payload = json_encode(array(
'recipient' => 'RECIPIENT',
'gateway_id' => 'GATEWAY_ID',
'language' => 'LANG_CODE',
'otp' => 'Your OTP Code'
));

echo $payload . "\n";

curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $BASE_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);
echo $resp;
import requests

BASE_URL = 'https://api.nusasms.com'
URL = f'{BASE_URL}/nusasms_api/1.0/wa_business/otp'
HEADERS = {"APIKey": "DEV_TESTING_API_KEY"}

PAYLOADS = {
"recipient": "RECIPIENT",
"gateway_id": "GATEWAY_ID",
"language": "LANG_CODE",
"otp": "Your OTP Code"
}
r = requests.post(URL, json=PAYLOADS, headers=HEADERS)
print(r.json())
require 'rest-client'
require 'json'

headers = {
'APIKey' => 'DEV_TESTING_API_KEY',
'Content-Type' => 'application/json'
}
payloads = {
'recipient' => 'RECIPIENT',
'gateway_id' => 'GATEWAY_ID',
'language' => 'LANG_CODE',
'otp' => 'Your OTP Code'
}

base_url = 'https://api.nusasms.com/nusasms_api/1.0'

response = RestClient::Request.new({
method: :post,
url: base_url + '/wa_business/otp',
payload: payloads.to_json,
headers: headers
}).execute do |response, request, result|
case response.code
# Success
when 201
[ :success, puts(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
URL=https://api.nusasms.com/nusasms_api/1.0/wa_business/otp

curl -X 'POST' $URL \
-H 'Accept: application/json' \
-H 'APIKey: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"recipient": "RECIPIENT",
"gateway_id": "GATEWAY_ID",
"language": "LANG_CODE",
"otp": "Your OTP Code"
}'

Send OTP message

OTP message can be sent if you has a Authentication Template. OTP message only require one parameter to build the message namely otp

Body parameter

{
"recipient": "string",
"gateway_id": "string",
"otp": "string",
"language": "id"
}

Parameters

Name In Type Required Description
body body OTPParameter true none

Example responses

200 Response

{
"error": false,
"message": "Data message",
"data": {
"message_id": "string"
}
}

Responses

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

Changelog

2023-09-15

Added

2023-07-12

Added

2023-03-03

Added

v1

Added

Schemas

Button

{
"sub_type": "QUICK_REPLY",
"parameters": {
"type": "payload",
"payload": "string"
},
"index": 2
}

Button

Properties

Name Type Required Restrictions Description
sub_type ButtonSubTypeEnum false none An enumeration.
parameters ButtonParameter true none none
index integer true none none

ButtonParameter

{
"type": "payload",
"payload": "string"
}

ButtonParameter

Properties

Name Type Required Restrictions Description
type string false none none
payload string false none none

Enumerated Values

Property Value
type payload

ButtonSubTypeEnum

"QUICK_REPLY"

ButtonSubTypeEnum

Properties

Name Type Required Restrictions Description
ButtonSubTypeEnum any false none An enumeration.

Enumerated Values

Property Value
ButtonSubTypeEnum QUICK_REPLY
ButtonSubTypeEnum URL

Document

{
"type": "document",
"link": "http://example.com",
"filename": "string"
}

Document

Properties

Name Type Required Restrictions Description
type string true none none
link string(uri) true none none
filename string false none none

Enumerated Values

Property Value
type document

HTTPValidationError

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

HTTPValidationError

Properties

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

Image

{
"type": "image",
"link": "http://example.com",
"filename": "string"
}

Image

Properties

Name Type Required Restrictions Description
type string true none none
link string(uri) true none none
filename string false none none

Enumerated Values

Property Value
type image

OTPParameter

{
"recipient": "string",
"gateway_id": "string",
"otp": "string",
"language": "id"
}

OTPParameter

Properties

Name Type Required Restrictions Description
recipient string true none none
gateway_id string true none none
otp string true none none
language string 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

ReplyParameter

{
"recipient": "RECIPIENT",
"gateway_id": "YOUR_GATEWAY_ID",
"type": "text",
"payloads": {
"body": "text example"
}
}

ReplyParameter

Properties

Name Type Required Restrictions Description
recipient string true none none
gateway_id string true none none
type string true none none
payloads object false none none

Enumerated Values

Property Value
type text
type reaction
type audio
type document
type image
type sticker
type video
type location

Response

{
"error": false,
"message": "Data message",
"data": {
"message_id": "string"
}
}

Response

Properties

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

ResponseData

{
"message_id": "string"
}

ResponseData

Properties

Name Type Required Restrictions Description
message_id string true none none

Template

{
"name": "string",
"language": "string"
}

Template

Properties

Name Type Required Restrictions Description
name string true none none
language string true none none

TemplateParam

{
"recipient": "string",
"gateway_id": "string",
"template": {
"name": "string",
"language": "string"
},
"header": {
"type": "image",
"link": "http://example.com",
"filename": "string"
},
"body": [
{
"type": "text",
"text": "string"
}
],
"buttons": [
{
"sub_type": "QUICK_REPLY",
"parameters": {
"type": "payload",
"payload": "string"
},
"index": 2
}
]
}

TemplateParam

Properties

Name Type Required Restrictions Description
recipient string true none none
gateway_id string true none none
template Template true none none
header any false none none

anyOf

Name Type Required Restrictions Description
» anonymous Image false none none

or

Name Type Required Restrictions Description
» anonymous Document false none none

or

Name Type Required Restrictions Description
» anonymous Video false none none

or

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

continued

Name Type Required Restrictions Description
body [Text] false none none
buttons [Button] false none none

Text

{
"type": "text",
"text": "string"
}

Text

Properties

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

Enumerated Values

Property Value
type text

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

Video

{
"type": "video",
"link": "http://example.com",
"filename": "string"
}

Video

Properties

Name Type Required Restrictions Description
type string true none none
link string(uri) true none none
filename string false none none

Enumerated Values

Property Value
type video