Option 1 Generate Token
Before you begin API integrations you will have to generate authorization token. Below steps are outlined on how to generate authorization token. You need to create an account at InTouchVAS. Once you have the account ready, generate API Token via the below ndpoint
Authentication headers
Generate API endpoints accepts Basic Auth headers for authentication, you will need your account username and password to generate API Token
generated_auth=base64(username:password)
Authorization: Basic $generated_auth
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://identity-service.intouchvas.io/auth/api-key")
header = {'Content-Type': 'text/json','Authorization':'Basic [generated_auth]'}
# Create the HTTP objects
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri, header)
# Send the request
response = http.request(request)
import requests
newHeaders = {'Content-type': 'application/json', 'Authorization': 'Basic [generated_auth]'}
response = requests.get('https://identity-service.intouchvas.io/auth/api-key',headers=newHeaders)
print("Status code: ", response.status_code)
response_Json = response.json()
print("Printing Post JSON data")
print(response_Json['status'])
print(response_Json['message'])
curl --location --request GET 'https://identity-service.intouchvas.io/auth/api-key' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic [generated_auth]' \
// Creating a XHR object
let xhr = new XMLHttpRequest();
let url = "https://identity-service.intouchvas.io/auth/api-key";
// open a connection
xhr.open("GET", url, true);
// Set the request header i.e. which type of content you are sending
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("Authorization","Basic [generated_auth]");
// Create a state change callback
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 ) {
// Print received data from server
console.log(this.responseText.status);
console.log(this.responseText.message);
}
};
// Sending request
xhr.send();
package main
import (
"bytes"
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
)
func main() {
url := "https://identity-service.intouchvas.io/auth/api-key"
method := "GET"
// make http request
client := &http.Client {}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Basic [generated_auth]")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
public class PostJSONWithHttpURLConnection {
public static void main (String []args) throws IOException{
URL url = new URL ("https://identity-service.intouchvas.io/auth/api-key");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Content-Type", "application/json; utf-8");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Authorization", "Basic [generated_auth]");
con.setDoOutput(true);
int code = con.getResponseCode();
System.out.println(code);
try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))){
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
}
}
}
<?php
$httpRequest = curl_init("https://identity-service.intouchvas.io/auth/api-key");
curl_setopt($httpRequest,CURLOPT_TIMEOUT,60);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,1);
curl_setopt($httpRequest,CURLOPT_HTTPHEADER,array(
"Content-Type:application/json",
"Authorization: Basic [generated_auth]"
)
);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,true);
//curl_setopt($httpRequest,CURLOPT_HEADER,1);
$response = curl_exec($httpRequest);
$status = curl_getinfo($httpRequest,CURLINFO_HTTP_CODE);
curl_close($httpRequest);
echo $status;
echo $response;
The above command returns JSON structured like this on success:
{
"token": "API token",
"lifetime": 1800
}
On failure the following is returned, referer to status codes for error types
{
"status": 428,
"message": "error message"
}
Token Response
The API returns JSON payload with the following
| Key | Required | Data Type | Default | Description |
|---|---|---|---|---|
| token | yes | String | none | API Token |
| lifetime | yes | Integer | none | Token lifetime in seconds, this token expires after this number of seconds |
Option 2: Use API Key
Before you begin API integrations, you need to generate an API Key from your dashboard.
First, create an account at InTouchVAS. Once your account is ready, follow the steps below to generate your API Key:
How to Generate API Key
- Log in to your InTouchVAS dashboard.
- On the top right corner, click the person/profile icon.
- Select Account.
- Navigate to the API Key section.
- Click Generate API Key (if no key exists).
- Copy the generated API Key.
Example header:
Content-Type: application/json
x-api-key: YOUR_GENERATED_API_KEY
SMS API Authentication headers
IntouchVAS Portal uses API key or token to allow access to the API.
api-key: secureapikeys API Token authentication
x-api-key: secureapikeys API Key authentication
Bulk SMS APIs
Send Single SMS
Use this API to send single SMS or Same SMS upto 50 numbers at the same time. There are two main types of SMS
| SMS Type | Description |
|---|---|
| Transactional | This are real time SMS like OTP and transaction confirmations |
| Promotional | This is promotional and marketing SMS |
Transactional SMS API Endpoint
POST /message/send/transactional
Query Input Parameters
Request Parameters
| Key | Required | Data Type | Default | Description |
|---|---|---|---|---|
| message | yes | String | none | message ro send |
| msisdn | yes | String | true | Recipient phone number. To send same SMS to more than 1 number separate multiple numbers with comma ( , ) |
| sender_id | no | String | INTOUCHVAS | your registered sender ID |
| callback_url | no | String | none | Where DLR report will be send back |
This endpoint expects JSON in the below format:
{
"message": "message here",
"msisdn": "+2547xxxxxxxx",
"sender_id": "Intouchvas",
"callback_url": "https://callback.io/123/dlr"
}
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://sms-service.intouchvas.io/message/send/transactional")
header = {'Content-Type': 'text/json','api-key':'secureapikeys'}
user = {
message: 'message here',
msisdn: '+2547xxxxxxxx',
sender_id: 'INTOUCHVAS',
callback_url: 'https://callback.io/123/dlr'
}
# Create the HTTP objects
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = user.to_json
# Send the request
response = http.request(request)
import requests
newHeaders = {'Content-type': 'application/json', 'api-key': 'secureapikeys'}
payload = {'message': 'message here','msisdn':'+2547xxxxxxxx','sender_id':'INTOUCHVAS','callback_url': 'https://callback.io/123/dlr'}
response = requests.post('https://sms-service.intouchvas.io/message/send/transactional',data=payload,headers=newHeaders)
print("Status code: ", response.status_code)
response_Json = response.json()
print("Printing Post JSON data")
print(response_Json['status'])
print(response_Json['message'])
curl --location --request POST 'https://sms-service.intouchvas.io/message/send/transactional' \
--header 'Content-Type: application/json' \
--header 'api-key: secureapikeys' \
--data-raw '{
"message": "You message",
"msisdn": "+2547xxxxxxxx",
"sender_id": "INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr"
}'
// Creating a XHR object
let xhr = new XMLHttpRequest();
let url = "https://sms-service.intouchvas.io/message/send/transactional";
// open a connection
xhr.open("POST", url, true);
// Set the request header i.e. which type of content you are sending
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("api-key","secureapikeys");
// Create a state change callback
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 ) {
// Print received data from server
console.log(this.responseText.status);
console.log(this.responseText.message);
}
};
var message = {
"message": "message here",
"msisdn": "+2547xxxxxxxx",
"sender_id": "INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
}
// Converting JSON data to string
var data = JSON.stringify(message);
// Sending data with the request
xhr.send(data);
package main
import (
"bytes"
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
)
func main() {
url := "http://sms-service.intouchvas.io/message/send/transactional"
method := "POST"
// construct your message using interface
message := map[string] interface{}{
"message": "You message",
"msisdn":"+2547xxxxxxxx",
"sender_id":"INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
}
// convert to json
payload,err := json.Marshal(message)
if err != nil {
fmt.Println(err)
}
// make http request
client := &http.Client {}
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
if err != nil {
fmt.Println(err)
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("api-key", "secureapikeys")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
public class PostJSONWithHttpURLConnection {
public static void main (String []args) throws IOException{
URL url = new URL ("https://sms-service.intouchvas.io/message/send/transactional");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json; utf-8");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("api-key", "secureapikeys");
con.setDoOutput(true);
//JSON String need to be constructed for the specific resource.
Map<String, String> map = new LinkedHashMap<>();
map.put("message","You message");
map.put("msisdn","+2547xxxxxxxx");
map.put("sender_id","INTOUCHVAS");
map.put("callback_url","https://callback.io/123/dlr");
Gson gson = new Gson();
String jsonInputString = gson.toJson(map);
try(OutputStream os = con.getOutputStream()){
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
int code = con.getResponseCode();
System.out.println(code);
try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))){
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
}
}
}
<?php
$message = [
"message" => 'You message',
"msisdn" => "+2547xxxxxxxx",
"sender_id" => "INTOUCHVAS" ,
"callback_url" => "https://callback.io/123/dlr"
];
$data_string = json_encode($message);
$secureapikeys = "secureapikeys";
$httpRequest = curl_init("https://sms-service.intouchvas.io/message/send/transactional");
curl_setopt($httpRequest,CURLOPT_POST,true);
curl_setopt($httpRequest,CURLOPT_POSTFIELDS,$data_string);
curl_setopt($httpRequest,CURLOPT_TIMEOUT,60);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,1);
curl_setopt($httpRequest,CURLOPT_HTTPHEADER,array(
"Content-Type:application/json",
"api-key: $secureapikeys"
)
);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,true);
//curl_setopt($httpRequest,CURLOPT_HEADER,1);
$response = curl_exec($httpRequest);
$status = curl_getinfo($httpRequest,CURLINFO_HTTP_CODE);
curl_close($httpRequest);
echo $status;
echo $response;
The above command returns JSON structured like this on success:
{
"message": "SMS successfully queued for sending. Total recipients 1",
"status": 200,
"transaction_id": 2295
}
On failure the following is returned, referer to status codes for error types
{
"status": 428,
"message": "error message"
}
Promotional SMS API Endpoint
POST /message/send/promotional
Query Input Parameters
Request Parameters
| Key | Required | Data Type | Default | Description |
|---|---|---|---|---|
| message | yes | String | none | message ro send |
| msisdn | yes | String | true | Recipient phone number. To send same SMS to more than 1 number separate multiple numbers with comma ( , ) |
| sender_id | no | String | INTOUCHVAS | your registered sender ID |
| callback_url | no | String | none | Where DLR report will be send back |
This endpoint expects JSON in the below format:
{
"message": "message here",
"msisdn": "+2547xxxxxxxx",
"sender_id": "Intouchvas",
"callback_url": "https://callback.io/123/dlr"
}
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://sms-service.intouchvas.io/message/send/promotional")
header = {'Content-Type': 'text/json','api-key':'secureapikeys'}
user = {
message: 'message here',
msisdn: '+2547xxxxxxxx',
sender_id: 'INTOUCHVAS',
callback_url: 'https://callback.io/123/dlr'
}
# Create the HTTP objects
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = user.to_json
# Send the request
response = http.request(request)
import requests
newHeaders = {'Content-type': 'application/json', 'api-key': 'secureapikeys'}
payload = {'message': 'message here','msisdn':'+2547xxxxxxxx','sender_id':'INTOUCHVAS','callback_url': 'https://callback.io/123/dlr'}
response = requests.post('https://sms-service.intouchvas.io/message/send/promotional',data=payload,headers=newHeaders)
print("Status code: ", response.status_code)
response_Json = response.json()
print("Printing Post JSON data")
print(response_Json['status'])
print(response_Json['message'])
curl --location --request POST 'https://sms-service.intouchvas.io/message/send/promotional' \
--header 'Content-Type: application/json' \
--header 'api-key: secureapikeys' \
--data-raw '{
"message": "You message",
"msisdn": "+2547xxxxxxxx",
"sender_id": "INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr"
}'
// Creating a XHR object
let xhr = new XMLHttpRequest();
let url = "https://sms-service.intouchvas.io/message/send/promotional";
// open a connection
xhr.open("POST", url, true);
// Set the request header i.e. which type of content you are sending
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("api-key","secureapikeys");
// Create a state change callback
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 ) {
// Print received data from server
console.log(this.responseText.status);
console.log(this.responseText.message);
}
};
var message = {
"message": "message here",
"msisdn": "+2547xxxxxxxx",
"sender_id": "INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
}
// Converting JSON data to string
var data = JSON.stringify(message);
// Sending data with the request
xhr.send(data);
package main
import (
"bytes"
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
)
func main() {
url := "http://sms-service.intouchvas.io/message/send/promotional"
method := "POST"
// construct your message using interface
message := map[string] interface{}{
"message": "You message",
"msisdn":"+2547xxxxxxxx",
"sender_id":"INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
}
// convert to json
payload,err := json.Marshal(message)
if err != nil {
fmt.Println(err)
}
// make http request
client := &http.Client {}
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
if err != nil {
fmt.Println(err)
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("api-key", "secureapikeys")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
public class PostJSONWithHttpURLConnection {
public static void main (String []args) throws IOException{
URL url = new URL ("https://sms-service.intouchvas.io/message/send/promotional");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json; utf-8");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("api-key", "secureapikeys");
con.setDoOutput(true);
//JSON String need to be constructed for the specific resource.
Map<String, String> map = new LinkedHashMap<>();
map.put("message","You message");
map.put("msisdn","+2547xxxxxxxx");
map.put("sender_id","INTOUCHVAS");
map.put("callback_url","https://callback.io/123/dlr");
Gson gson = new Gson();
String jsonInputString = gson.toJson(map);
try(OutputStream os = con.getOutputStream()){
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
int code = con.getResponseCode();
System.out.println(code);
try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))){
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
}
}
}
<?php
$message = [
"message" => 'You message',
"msisdn" => "+2547xxxxxxxx",
"sender_id" => "INTOUCHVAS" ,
"callback_url" => "https://callback.io/123/dlr"
];
$data_string = json_encode($message);
$secureapikeys = "secureapikeys";
$httpRequest = curl_init("https://sms-service.intouchvas.io/message/send/promotional");
curl_setopt($httpRequest,CURLOPT_POST,true);
curl_setopt($httpRequest,CURLOPT_POSTFIELDS,$data_string);
curl_setopt($httpRequest,CURLOPT_TIMEOUT,60);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,1);
curl_setopt($httpRequest,CURLOPT_HTTPHEADER,array(
"Content-Type:application/json",
"api-key: $secureapikeys"
)
);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,true);
//curl_setopt($httpRequest,CURLOPT_HEADER,1);
$response = curl_exec($httpRequest);
$status = curl_getinfo($httpRequest,CURLINFO_HTTP_CODE);
curl_close($httpRequest);
echo $status;
echo $response;
The above command returns JSON structured like this on success:
{
"message": "SMS successfully queued for sending. Total recipients 1",
"status": 200,
"transaction_id": 2295
}
On failure the following is returned, referer to status codes for error types
{
"status": 428,
"message": "error message"
}
Schedule SMS
This API supports SMS Scheduling, all scheduled SMS are treated as promotional SMS, you cannot schedule a transactional SMS, an SMS that has been scheduled will be queued to be send later
API Endpoint
POST /message/send/promotional
Query Input Parameters
Request Parameters
| Key | Required | Data Type | Default | Description |
|---|---|---|---|---|
| message | yes | String | none | message ro send |
| msisdn | yes | String | true | Recipient phone number. To send same SMS to more than 1 number separate multiple numbers with comma ( , ) |
| country_code | no | String | ke | if this is not a kenya number, supply the country code |
| sender_id | no | String | INTOUCHVAS | your registered sender ID |
| callback_url | no | String | none | Where DLR report will be send back |
| schedule | no | Boolean | false | Is this SMS to be scheduled? |
| date | no | String | none | Date to send the SMS, date format YYYY-MM-DD |
| send_time | no | String | none | Time to send the SMS |
This endpoint expects JSON in the below format:
{
"message": "message here",
"msisdn": "+2547xxxxxxxx",
"sender_id": "INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
"schedule": true,
"date": "2030-01-01",
"send_time": "09:30:01"
}
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://sms-service.intouchvas.io/message/send/promotional")
header = {'Content-Type': 'text/json','api-key':'secureapikeys'}
user = {
message: 'message here',
msisdn: '+2547xxxxxxxx',
sender_id: 'INTOUCHVAS',
callback_url: 'https://callback.io/123/dlr',
schedule: true,
date: '2030-01-01',
send_time: '09:30:01'
}
# Create the HTTP objects
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = user.to_json
# Send the request
response = http.request(request)
import requests
newHeaders = {'Content-type': 'application/json', 'api-key': 'secureapikeys'}
payload = {'message': 'message here','msisdn':'+2547xxxxxxxx','sender_id':'INTOUCHVAS','callback_url': 'https://callback.io/123/dlr','schedule': true,'date':'2030-09-01','send_time':'09:30:01'}
response = requests.post('https://sms-service.intouchvas.io/message/send/promotional',data=payload,headers=newHeaders)
print("Status code: ", response.status_code)
response_Json = response.json()
print("Printing Post JSON data")
print(response_Json['status'])
print(response_Json['message'])
curl --location --request POST 'https://sms-service.intouchvas.io/message/send/promotional' \
--header 'Content-Type: application/json' \
--header 'Authorization: secureapikeys' \
--data-raw '{
"message": "You message",
"msisdn": "+2547xxxxxxxx",
"sender_id": "INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
"schedule": true,
"date": "2030-01-01",
"send_time": "09:30:01"
}'
// Creating a XHR object
let xhr = new XMLHttpRequest();
let url = "https://sms-service.intouchvas.io/message/send/promotional";
// open a connection
xhr.open("POST", url, true);
// Set the request header i.e. which type of content you are sending
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("api-key","secureapikeys");
// Create a state change callback
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 ) {
// Print received data from server
console.log(this.responseText.status);
console.log(this.responseText.message);
}
};
var message = {
"message": "message here",
"msisdn": "+2547xxxxxxxx",
"sender_id": "INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
"schedule": true,
"date": "2030-01-01",
"send_time": "09:30:01",
}
// Converting JSON data to string
var data = JSON.stringify(message);
// Sending data with the request
xhr.send(data);
package main
import (
"bytes"
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
)
func main() {
url := "http://sms-service.intouchvas.io/message/send/promotional"
method := "POST"
// construct your message using interface
message := map[string] interface{}{
"message": "You message",
"msisdn":"+2547xxxxxxxx",
"sender_id":"INTOUCHVAS",
"callback_url": "https://callback.io/123/dlr",
"schedule": true,
"date": "2030-01-01",
"send_time": "09:30:01",
}
// convert to json
payload,err := json.Marshal(message)
if err != nil {
fmt.Println(err)
}
// make http request
client := &http.Client {}
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
if err != nil {
fmt.Println(err)
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("api-key", "secureapikeys")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
public class PostJSONWithHttpURLConnection {
public static void main (String []args) throws IOException{
URL url = new URL ("https://sms-service.intouchvas.io/message/send/promotional");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json; utf-8");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("api-key", "secureapikeys");
con.setDoOutput(true);
//JSON String need to be constructed for the specific resource.
Map<String, String> map = new LinkedHashMap<>();
map.put("message","You message");
map.put("msisdn","+2547xxxxxxxx");
map.put("sender_id","INTOUCHVAS");
map.put("callback_url","https://callback.io/123/dlr");
map.put("schedule",true);
map.put("date","2030-01-01");
map.put("send_time","09:30:01");
Gson gson = new Gson();
String jsonInputString = gson.toJson(map);
try(OutputStream os = con.getOutputStream()){
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
int code = con.getResponseCode();
System.out.println(code);
try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))){
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
}
}
}
<?php
$message = [
"message" => 'You message',
"msisdn" => "+2547xxxxxxxx",
"sender_id" => "INTOUCHVAS" ,
"callback_url" => "https://callback.io/123/dlr"
];
$data_string = json_encode($message);
$secureapikeys = "secureapikeys";
$httpRequest = curl_init("https://sms-service.intouchvas.io/message/send/promotional");
curl_setopt($httpRequest,CURLOPT_POST,true);
curl_setopt($httpRequest,CURLOPT_POSTFIELDS,$data_string);
curl_setopt($httpRequest,CURLOPT_TIMEOUT,60);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,1);
curl_setopt($httpRequest,CURLOPT_HTTPHEADER,array(
"Content-Type:application/json",
"api-key: $secureapikeys"
)
);
curl_setopt($httpRequest,CURLOPT_RETURNTRANSFER,true);
//curl_setopt($httpRequest,CURLOPT_HEADER,1);
$response = curl_exec($httpRequest);
$status = curl_getinfo($httpRequest,CURLINFO_HTTP_CODE);
curl_close($httpRequest);
echo $status;
echo $response;
The above command returns JSON structured like this on success:
{
"message": "SMS successfully queued for sending. Total recipients 1",
"status": 200,
"transaction_id": 2295
}
On failure the following is returned, referer to status codes for error types
{
"status": 428,
"message": "error message"
}
File Upload
This API allows you to upload recipients in a file
API Endpoint
FORM POST /message/send/upload-file
Simple SMS Content
Simple SMS allows you to send the same SMS to many users by upload a file of file numbers. This endpoint provides an interface to upload contacts in a file.
file format
You can only upload a CSV file The first row will in the file will be treated as headers.
basic format
The first column is expected to be the phone numbers example below
| msisdn |
|---|
| +2547xxxxxxx0 |
| +2547xxxxxxx1 |
| +2547xxxxxxx2 |
| +2547xxxxxxx3 |
| +2547xxxxxxx4 |
Input Form Fields
The API expects a FORM POST with the following
| Key | Required | Data Type | Default | Description |
|---|---|---|---|---|
| message | yes | String | none | message ro send |
| country_code | no | String | ke | if this are not a kenya phone numbers, supply the country code |
| sender_id | no | String | IntouchVAS | your registered sender ID |
| file | yes | File | File to be uploaded | |
| campaign_name | no | String | Name of Campaign, contact group | |
| schedule | no | Boolean | false | Is this SMS to be scheduled? |
| date | no | String | none | Date to send the SMS, date format YYYY-MM-DD |
| send_time | no | String | none | Time to send the SMS |
require "uri"
require "net/http"
url = URI("https://sms-service.intouchvas.io/message/send/upload-file")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api-key"] = "secureapikeys"
form_data = [
['message', 'test SMS to {msisdn}'],
['sender_id', 'InTouchVAS'],
['campaign_name', 'test'],
['callback_url', 'https://intouchvas.io'],
['file', File.open('/Users/user1/Downloads/template (10).csv')]
]
request.set_form form_data, 'multipart/form-data'
response = https.request(request)
puts response.read_body
import requests
url = "https://sms-service.intouchvas.io/message/send/upload-file"
payload={'message': 'test SMS to [msisdn]',
'sender_id': 'InTouchVAS',
'campaign_name': 'test',
'callback_url': 'https://intouchvas.io'}
files=[
('file',('template (10).csv',open('/Users/user1/Downloads/template (10).csv','rb'),'text/csv'))
]
headers = {
'api-key': 'secureapikeys'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
curl --location --request POST 'https://sms-service.intouchvas.io/message/send/upload-file' \
--header 'api-key: secureapikeys=' \
--form 'message="test SMS to [msisdn]"' \
--form 'sender_id="InTouchVAS"' \
--form 'campaign_name="test"' \
--form 'callback_url="https://intouchvas.io"' \
--form 'file=@"/Users/user1/Downloads/template (10).csv"'
var data = new FormData();
data.append("message", "test SMS to [msisdn]");
data.append("sender_id", "InTouchVAS");
data.append("campaign_name", "test");
data.append("callback_url", "https://intouchvas.io");
data.append("file", fileInput.files[0], "template (10).csv");
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://sms-service.intouchvas.io/message/send/upload-file");
xhr.setRequestHeader("api-key", "secureapikeys");
xhr.send(data);
package main
import (
"fmt"
"bytes"
"mime/multipart"
"os"
"path/filepath"
"io"
"net/http"
"io/ioutil"
"log"
)
func main() {
endpoint := "https://sms-service.intouchvas.io/message/send/upload-file"
method := "POST"
csvFileToUpload := "/full/path/of/the/file.extension"
// your form fields
formFields := map[string]string{
"message": "test SMS to [msisdn]",
"sender_id": "InTouchVAS",
"campaign_name": "Bulk SMS",
"callback_url": "https://callback.io/dlr",
}
// open file for reading
file, err := os.Open(csvFileToUpload)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", filepath.Base(csvFileToUpload))
if err != nil {
fmt.Println(err)
return
}
_, err = io.Copy(part, file)
for key, val := range formFields {
_ = writer.WriteField(key, val)
}
err = writer.Close()
if err != nil {
fmt.Println(err)
return
}
req, err := http.NewRequest(method, endpoint, body)
if err != nil {
fmt.Println(err)
return
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("api-key", "secureapikeys")
client := &http.Client {}
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))
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
public class PostJSONWithHttpURLConnection {
public static void main (String []args) throws IOException{
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("message","test SMS to [msisdn]")
.addFormDataPart("sender_id","InTouchVAS")
.addFormDataPart("campaign_name","test")
.addFormDataPart("callback_url","https://intouchvas.io")
.addFormDataPart("file","template (10).csv",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("/Users/user1/Downloads/template (10).csv")))
.build();
Request request = new Request.Builder()
.url("https://sms-service.intouchvas.io/message/send/upload-file")
.method("POST", body)
.addHeader("api-key", "secureapikeys")
.build();
Response response = client.newCall(request).execute();
}
}
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sms-service.intouchvas.io/message/send/upload-file',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
'message' => 'test SMS to [msisdn]',
'sender_id' => 'InTouchVAS',
'campaign_name' => 'test',
'callback_url' => 'https://intouchvas.io',
'file'=> new CURLFILE('/Users/user1/Downloads/template (10).csv')
),
CURLOPT_HTTPHEADER => array(
'api-key: secureapikeys'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
The above command returns JSON structured like this on success:
{
"message": "SMS successfully queued for sending. Total recipients 10000",
"status": 200,
"transaction_id": 2295
}
On failure the following is returned, refere to status codes for error types
{
"status": 428,
"message": "error message"
}
File Upload - SMS Customization
This API allows you to upload recipients in a file and further customize SMS per recipient
API Endpoint
FORM POST /message/send/upload-file
This API allows you to send custom sms to a batch of contacts in a file e.g when sending school fees balance where you want to customize sms for every parent to pick the required fee balance.
1. step 1
When creating a file in this category, the 1st column remains to be phone number, the subsequent columns will be the replacement parameters. example you want to send sms to parents you want sms to go out with student name, fee balance and adminission number. Your file will have the below format. The 1st column will be treated as headers
| msisdn | name | admission | balance |
|---|---|---|---|
| 2547xxxxxxx0 | John Doe | adm/01 | 1000 |
| 2547xxxxxxx1 | Alice Bobby | adm/02 | 1000 |
| 2547xxxxxxx2 | Ruby Rose | adm/03 | 1000 |
| 2547xxxxxxx3 | George Nim | adm/04 | 1000 |
| 2547xxxxxxx4 | Lucas Madona | adm/05 | 1000 |
You can have as many columns and rows the only limit will be file size, your file should be below 100MB
2. step 2
Compose your sms to include column header name wrapped in square brackets [ and ] example to use name in SMS we use [name] back to our example above our sms will look like the following
Dear parent your student [name] has a fee balance of [balance]. Please pay your fees through paybill 89544 account [admission] thank you
The above will be your sms contents, the system will go through the file row by row replacing SMS parameters with values in the file in that column. Each recipient will receive a customized SMS
URL Parameters
This endpoint accepts form data with the below fields
| Key | Required | Data Type | Default | Description |
|---|---|---|---|---|
| message | yes | String | none | message to send |
| country_code | no | String | ke | if this are not a kenya phone numbers, supply the country code |
| sender_id | no | String | IntouchVAS | your registered sender ID |
| file | yes | File | File to be uploaded | |
| campaign_name | no | String | Name of Campaign, contact group | |
| schedule | no | Boolean | false | Is this SMS to be scheduled? |
| date | no | String | none | Date to send the SMS, date format YYYY-MM-DD |
| send_time | no | String | none | Time to send the SMS |
require "uri"
require "net/http"
url = URI("https://sms-service.intouchvas.io/message/send/upload-file")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api-key"] = "secureapikeys"
form_data = [
['message', 'test SMS to {msisdn}'],
['sender_id', 'InTouchVAS'],
['campaign_name', 'test'],
['callback_url', 'https://intouchvas.io'],
['file', File.open('/Users/user1/Downloads/template (10).csv')]
]
request.set_form form_data, 'multipart/form-data'
response = https.request(request)
puts response.read_body
import requests
url = "https://sms-service.intouchvas.io/message/send/upload-file"
payload={'message': 'test SMS to [msisdn]',
'sender_id': 'InTouchVAS',
'campaign_name': 'test',
'callback_url': 'https://intouchvas.io'}
files=[
('file',('template (10).csv',open('/Users/user1/Downloads/template (10).csv','rb'),'text/csv'))
]
headers = {
'api-key': 'secureapikeys'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
curl --location --request POST 'https://sms-service.intouchvas.io/message/send/upload-file' \
--header 'api-key: secureapikeys=' \
--form 'message="test SMS to [msisdn]"' \
--form 'sender_id="InTouchVAS"' \
--form 'campaign_name="test"' \
--form 'callback_url="https://intouchvas.io"' \
--form 'file=@"/Users/user1/Downloads/template (10).csv"'
var data = new FormData();
data.append("message", "test SMS to [msisdn]");
data.append("sender_id", "InTouchVAS");
data.append("campaign_name", "test");
data.append("callback_url", "https://intouchvas.io");
data.append("file", fileInput.files[0], "template (10).csv");
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://sms-service.intouchvas.io/message/send/upload-file");
xhr.setRequestHeader("api-key", "secureapikeys");
xhr.send(data);
package main
import (
"fmt"
"bytes"
"mime/multipart"
"os"
"path/filepath"
"io"
"net/http"
"io/ioutil"
"log"
)
func main() {
endpoint := "https://sms-service.intouchvas.io/message/send/upload-file"
method := "POST"
csvFileToUpload := "/full/path/of/the/file.extension"
// your form fields
formFields := map[string]string{
"message": "test SMS to [msisdn]",
"sender_id": "InTouchVAS",
"campaign_name": "Bulk SMS",
"callback_url": "https://callback.io/dlr",
}
// open file for reading
file, err := os.Open(csvFileToUpload)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", filepath.Base(csvFileToUpload))
if err != nil {
fmt.Println(err)
return
}
_, err = io.Copy(part, file)
for key, val := range formFields {
_ = writer.WriteField(key, val)
}
err = writer.Close()
if err != nil {
fmt.Println(err)
return
}
req, err := http.NewRequest(method, endpoint, body)
if err != nil {
fmt.Println(err)
return
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("api-key", "secureapikeys")
client := &http.Client {}
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))
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.gson.Gson;
public class PostJSONWithHttpURLConnection {
public static void main (String []args) throws IOException{
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("message","test SMS to [msisdn]")
.addFormDataPart("sender_id","InTouchVAS")
.addFormDataPart("campaign_name","test")
.addFormDataPart("callback_url","https://intouchvas.io")
.addFormDataPart("file","template (10).csv",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("/Users/user1/Downloads/template (10).csv")))
.build();
Request request = new Request.Builder()
.url("https://sms-service.intouchvas.io/message/send/upload-file")
.method("POST", body)
.addHeader("api-key", "secureapikeys")
.build();
Response response = client.newCall(request).execute();
}
}
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://sms-service.intouchvas.io/message/send/upload-file',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
'message' => 'test SMS to [msisdn]',
'sender_id' => 'InTouchVAS',
'campaign_name' => 'test',
'callback_url' => 'https://intouchvas.io',
'file'=> new CURLFILE('/Users/user1/Downloads/template (10).csv')
),
CURLOPT_HTTPHEADER => array(
'api-key: secureapikeys'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
The above command returns JSON structured like this on success:
{
"message": "SMS successfully queued for sending. Total recipients 10000",
"status": 200,
"transaction_id": 2295
}
On failure the following is returned, refere to status codes for error types
{
"status": 428,
"message": "error message"
}
SMS Delivery Report
When you send a Bulk SMS and add delivery callback_url, IntouchVAS will send you SMS status when its done processing, SMS is considered done processing when it either fails or is successfully delivered to the recipient.
DLR fields
| Name | Data Type | Description |
|---|---|---|
| msisdn | string | Phone number |
| status | Integer | see DLR Status section |
| status_description | String | Description of the status field |
| country | String | Recipient Country |
| network | String | Recipient Telcom Network |
| transaction_id | String | Message Transaction ID |
Sample DLR JSON
{
"msisdn": "254710XXXXXX",
"status": 3,
"country": "ke",
"network": "Safaricom",
"status_description": "Delivered To Teminal",
"transaction_id": 2295
}
```Dawsons-MacBook-Pro:slate phil$ You don't have write permissions for the /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0 directory.
Send SMS to Group
Send a promotional or transactional SMS to every active contact in a contact group with a single API call. The system fans the message out to all recipients automatically.
/api/message/send/group
When to use each SMS type
| SMS Type | Use case | Example |
|---|---|---|
| Promotional | Marketing blasts, offers, announcements sent to opt-in contact groups | Monthly newsletter, product launch |
| Transactional | Event-driven notifications sent to groups of affected users | Scheduled maintenance alert, bulk order updates |
Request Body Parameters
| Field | Required | Type | Description |
|---|---|---|---|
| contact_group_id | required | String | ID of the contact group to message. Get this from List Contact Groups. |
| sender_id | required | String | Your registered sender ID (alphanumeric, max 11 chars). |
| message | required | String | The SMS message body. Use {first_name}, {other_name}, {custom_1} … {custom_5} for personalisation. |
| campaign_name | optional | String | Label to identify this campaign in your reports. |
| sms_type | optional | String | promotional (default) or transactional. |
| schedule | optional | Boolean | Set true to schedule for future delivery. Requires schedule_date and schedule_time. |
| schedule_date | optional | String | Date for scheduled send, format YYYY-MM-DD. |
| schedule_time | optional | String | Time for scheduled send, format HH:MM (24-hour). |
Request body — immediate send:
{
"contact_group_id": "42",
"sender_id": "MYBRAND",
"message": "Hi {first_name}, enjoy 20% off this weekend only! Use code SAVE20. Reply STOP to opt out.",
"campaign_name": "July Weekend Offer",
"sms_type": "promotional"
}
Request body — scheduled send:
{
"contact_group_id": "42",
"sender_id": "MYBRAND",
"message": "Dear {first_name}, our system will be under maintenance on Saturday 8pm-10pm EAT. We apologise for any inconvenience.",
"campaign_name": "Maintenance Notice",
"sms_type": "transactional",
"schedule": true,
"schedule_date": "2025-08-02",
"schedule_time": "10:00"
}
Success response (HTTP 201):
{
"status": 200,
"message": "SMS successfully queued for sending. Total recipients 1500",
"transaction_id": 7821
}
curl --location --request POST 'https://sms-service.intouchvas.io/api/message/send/group' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
"contact_group_id": "42",
"sender_id": "MYBRAND",
"message": "Hi {first_name}, enjoy 20% off this weekend! Use code SAVE20.",
"campaign_name": "July Weekend Offer",
"sms_type": "promotional"
}'
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://sms-service.intouchvas.io/api/message/send/group")
header = { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY' }
body = {
contact_group_id: "42",
sender_id: "MYBRAND",
message: "Hi {first_name}, enjoy 20% off this weekend! Use code SAVE20.",
campaign_name: "July Weekend Offer",
sms_type: "promotional"
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = body.to_json
response = http.request(request)
puts response.body
import requests
import json
headers = {'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY'}
payload = {
"contact_group_id": "42",
"sender_id": "MYBRAND",
"message": "Hi {first_name}, enjoy 20% off this weekend! Use code SAVE20.",
"campaign_name": "July Weekend Offer",
"sms_type": "promotional"
}
response = requests.post(
'https://sms-service.intouchvas.io/api/message/send/group',
data=json.dumps(payload),
headers=headers
)
print(response.status_code)
print(response.json())
const payload = {
contact_group_id: "42",
sender_id: "MYBRAND",
message: "Hi {first_name}, enjoy 20% off this weekend! Use code SAVE20.",
campaign_name: "July Weekend Offer",
sms_type: "promotional"
};
fetch('https://sms-service.intouchvas.io/api/message/send/group', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY'
},
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
payload, _ := json.Marshal(map[string]interface{}{
"contact_group_id": "42",
"sender_id": "MYBRAND",
"message": "Hi {first_name}, enjoy 20% off this weekend! Use code SAVE20.",
"campaign_name": "July Weekend Offer",
"sms_type": "promotional",
})
client := &http.Client{}
req, _ := http.NewRequest("POST", "https://sms-service.intouchvas.io/api/message/send/group", bytes.NewBuffer(payload))
req.Header.Add("Content-Type", "application/json")
req.Header.Add("x-api-key", "YOUR_API_KEY")
res, _ := client.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
import java.io.*;
import java.net.*;
URL url = new URL("https://sms-service.intouchvas.io/api/message/send/group");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("x-api-key", "YOUR_API_KEY");
con.setDoOutput(true);
String json = "{\"contact_group_id\":\"42\",\"sender_id\":\"MYBRAND\","
+ "\"message\":\"Hi {first_name}, enjoy 20% off!\","
+ "\"campaign_name\":\"July Weekend Offer\",\"sms_type\":\"promotional\"}";
try (OutputStream os = con.getOutputStream()) {
os.write(json.getBytes("utf-8"));
}
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
StringBuilder resp = new StringBuilder();
String line;
while ((line = br.readLine()) != null) resp.append(line.trim());
System.out.println(resp.toString());
<?php
$payload = json_encode([
"contact_group_id" => "42",
"sender_id" => "MYBRAND",
"message" => "Hi {first_name}, enjoy 20% off this weekend! Use code SAVE20.",
"campaign_name" => "July Weekend Offer",
"sms_type" => "promotional"
]);
$ch = curl_init("https://sms-service.intouchvas.io/api/message/send/group");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"x-api-key: YOUR_API_KEY"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Contact Management
Contact Groups let you organise your recipients into named, reusable lists. Once a group is set up you can target the entire group in a single API call instead of passing thousands of individual numbers.
- Create a new group and add contacts — Create Contacts
- Or upload a CSV file of contacts — Upload Contacts (CSV)
- Retrieve your group IDs — List Contact Groups
- Send a promotional or transactional blast to the group — Send SMS to Group
List Contact Groups
Returns all contact groups that belong to the authenticated client. Each group includes total, active and inactive contact counts.
/api/contact/groups
No request body required — authentication header is sufficient.
Example response:
[
{
"id": 42,
"name": "VIP Customers",
"contacts": 1500,
"active": 1420,
"inactive": 80,
"created": "2025-01-15T08:00:00Z"
},
{
"id": 43,
"name": "July Promo List",
"contacts": 8200,
"active": 8200,
"inactive": 0,
"created": "2025-07-01T06:30:00Z"
}
]
curl --location --request GET 'https://sms-service.intouchvas.io/api/contact/groups' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY'
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://sms-service.intouchvas.io/api/contact/groups")
header = { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY' }
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri, header)
response = http.request(request)
puts JSON.parse(response.body)
import requests
headers = {'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY'}
response = requests.get('https://sms-service.intouchvas.io/api/contact/groups', headers=headers)
print(response.status_code)
print(response.json())
fetch('https://sms-service.intouchvas.io/api/contact/groups', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY'
}
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://sms-service.intouchvas.io/api/contact/groups"
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Content-Type", "application/json")
req.Header.Add("x-api-key", "YOUR_API_KEY")
res, _ := client.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
import java.io.*;
import java.net.*;
URL url = new URL("https://sms-service.intouchvas.io/api/contact/groups");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("x-api-key", "YOUR_API_KEY");
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
StringBuilder resp = new StringBuilder();
String line;
while ((line = br.readLine()) != null) resp.append(line.trim());
System.out.println(resp.toString());
<?php
$ch = curl_init("https://sms-service.intouchvas.io/api/contact/groups");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"x-api-key: YOUR_API_KEY"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Create Contacts
Creates a contact group (or updates an existing one) and inserts the provided contacts into it in a single request. Phone numbers are automatically formatted to E.164 and the mobile network (telco) is auto-detected. Supply country_code at the group level as a fallback for short/local numbers.
/contact/create
Request Body Parameters
| Field | Required | Type | Description |
|---|---|---|---|
| name | required* | String | Contact group name. Required if id is 0. |
| id | optional | Integer | Existing contact group ID. Supply this to add contacts to an existing group. |
| country_code | optional | String | Default dialling code e.g. 254. Applied to short/local numbers that have no country prefix. |
| contacts | required | Array | List of contact objects (see below). |
Contact Object Fields
| Field | Required | Type | Description |
|---|---|---|---|
| msisdn | required | String | Phone number in any format — international (+254712345678), local (0712345678), or short (712345678). |
| first_name | optional | String | Contact first name. Used for SMS personalisation. |
| other_name | optional | String | Contact surname or other name. |
| country_code | optional | String | Per-contact country code override. Overrides group-level country_code for this number. |
| custom_1 … custom_5 | optional | String | Up to 5 custom fields for personalisation (e.g. tier, city, loyalty points). |
Request body example:
{
"name": "VIP Customers",
"country_code": "254",
"contacts": [
{
"msisdn": "254712345678",
"first_name": "Jane",
"other_name": "Doe",
"custom_1": "Gold",
"custom_2": "Nairobi",
"custom_3": "",
"custom_4": "",
"custom_5": ""
},
{
"msisdn": "712345679",
"first_name": "John",
"other_name": "Smith",
"custom_1": "Silver",
"custom_2": "Mombasa"
}
]
}
Success response (HTTP 201):
"Contact group created successfully with contact ID 42, total contacts 2"
curl --location --request POST 'https://sms-service.intouchvas.io/contact/create' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
"name": "VIP Customers",
"country_code": "254",
"contacts": [
{
"msisdn": "254712345678",
"first_name": "Jane",
"other_name": "Doe",
"custom_1": "Gold"
}
]
}'
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://sms-service.intouchvas.io/contact/create")
header = { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY' }
body = {
name: "VIP Customers",
country_code: "254",
contacts: [
{ msisdn: "254712345678", first_name: "Jane", other_name: "Doe", custom_1: "Gold" }
]
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = body.to_json
response = http.request(request)
puts response.body
import requests
import json
headers = {'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY'}
payload = {
"name": "VIP Customers",
"country_code": "254",
"contacts": [
{
"msisdn": "254712345678",
"first_name": "Jane",
"other_name": "Doe",
"custom_1": "Gold"
}
]
}
response = requests.post(
'https://sms-service.intouchvas.io/contact/create',
data=json.dumps(payload),
headers=headers
)
print(response.status_code)
print(response.json())
const payload = {
name: "VIP Customers",
country_code: "254",
contacts: [
{ msisdn: "254712345678", first_name: "Jane", other_name: "Doe", custom_1: "Gold" }
]
};
fetch('https://sms-service.intouchvas.io/contact/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY'
},
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
payload := map[string]interface{}{
"name": "VIP Customers",
"country_code": "254",
"contacts": []map[string]string{
{"msisdn": "254712345678", "first_name": "Jane", "other_name": "Doe", "custom_1": "Gold"},
},
}
body, _ := json.Marshal(payload)
client := &http.Client{}
req, _ := http.NewRequest("POST", "https://sms-service.intouchvas.io/contact/create", bytes.NewBuffer(body))
req.Header.Add("Content-Type", "application/json")
req.Header.Add("x-api-key", "YOUR_API_KEY")
res, _ := client.Do(req)
defer res.Body.Close()
respBody, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(respBody))
}
import java.io.*;
import java.net.*;
URL url = new URL("https://sms-service.intouchvas.io/contact/create");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("x-api-key", "YOUR_API_KEY");
con.setDoOutput(true);
String json = "{\"name\":\"VIP Customers\",\"country_code\":\"254\",\"contacts\":[{\"msisdn\":\"254712345678\",\"first_name\":\"Jane\",\"other_name\":\"Doe\",\"custom_1\":\"Gold\"}]}";
try (OutputStream os = con.getOutputStream()) {
os.write(json.getBytes("utf-8"));
}
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
StringBuilder resp = new StringBuilder();
String line;
while ((line = br.readLine()) != null) resp.append(line.trim());
System.out.println(resp.toString());
<?php
$payload = json_encode([
"name" => "VIP Customers",
"country_code" => "254",
"contacts" => [
["msisdn" => "254712345678", "first_name" => "Jane", "other_name" => "Doe", "custom_1" => "Gold"]
]
]);
$ch = curl_init("https://sms-service.intouchvas.io/contact/create");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"x-api-key: YOUR_API_KEY"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Upload Contacts (CSV)
Upload a CSV or Excel file to bulk-import contacts into a group. The file is processed asynchronously in the background — large lists of tens of thousands of contacts are fully supported.
/contact/upload
multipart/form-data
Form Data Parameters
| Field | Required | Type | Description |
|---|---|---|---|
| file | required | File | CSV or Excel (.xlsx) file. First row is treated as a header and skipped. |
| name | required* | String | Contact group name. Required when id is not provided. |
| id | optional | Integer | Existing contact group ID. Contacts will be added to this group. |
| country_code | optional | String | Default country dialling code e.g. 254 for Kenya. Applied to short numbers. |
CSV File Format
Columns should be in this order. Only msisdn is mandatory — trailing columns can be omitted.
| Column | Description |
|---|---|
| msisdn | Phone number (any format) |
| first_name | First name for personalisation |
| other_name | Last name / other name |
| custom_1 | Custom field 1 |
| custom_2 | Custom field 2 |
| custom_3 | Custom field 3 |
| custom_4 | Custom field 4 |
| custom_5 | Custom field 5 |
Success response (HTTP 201):
"Contacts queued for processing"
curl --location --request POST 'https://sms-service.intouchvas.io/contact/upload' \
--header 'x-api-key: YOUR_API_KEY' \
--form 'file=@"/path/to/contacts.csv"' \
--form 'name="July Promo List"' \
--form 'country_code="254"'
require 'net/http'
require 'uri'
uri = URI.parse("https://sms-service.intouchvas.io/contact/upload")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
form_data = [
['name', 'July Promo List'],
['country_code', '254'],
['file', File.open('/path/to/contacts.csv')]
]
request = Net::HTTP::Post.new(uri.request_uri)
request['x-api-key'] = 'YOUR_API_KEY'
request.set_form(form_data, 'multipart/form-data')
response = http.request(request)
puts response.body
import requests
headers = {'x-api-key': 'YOUR_API_KEY'}
files = {'file': open('/path/to/contacts.csv', 'rb')}
data = {'name': 'July Promo List', 'country_code': '254'}
response = requests.post(
'https://sms-service.intouchvas.io/contact/upload',
headers=headers,
files=files,
data=data
)
print(response.status_code)
print(response.json())
const form = new FormData();
form.append('file', fileInput.files[0]); // from an <input type="file">
form.append('name', 'July Promo List');
form.append('country_code', '254');
fetch('https://sms-service.intouchvas.io/contact/upload', {
method: 'POST',
headers: { 'x-api-key': 'YOUR_API_KEY' },
body: form
})
.then(res => res.json())
.then(data => console.log(data));
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"io/ioutil"
)
func main() {
var b bytes.Buffer
w := multipart.NewWriter(&b)
w.WriteField("name", "July Promo List")
w.WriteField("country_code", "254")
fw, _ := w.CreateFormFile("file", "contacts.csv")
f, _ := os.Open("/path/to/contacts.csv")
io.Copy(fw, f)
w.Close()
req, _ := http.NewRequest("POST", "https://sms-service.intouchvas.io/contact/upload", &b)
req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("x-api-key", "YOUR_API_KEY")
client := &http.Client{}
res, _ := client.Do(req)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
// Use Apache HttpClient or OkHttp for multipart in Java
// Example with OkHttp:
OkHttpClient client = new OkHttpClient();
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("name", "July Promo List")
.addFormDataPart("country_code", "254")
.addFormDataPart("file", "contacts.csv",
RequestBody.create(new File("/path/to/contacts.csv"), MediaType.parse("text/csv")))
.build();
Request request = new Request.Builder()
.url("https://sms-service.intouchvas.io/contact/upload")
.addHeader("x-api-key", "YOUR_API_KEY")
.post(body)
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
<?php
$ch = curl_init("https://sms-service.intouchvas.io/contact/upload");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: YOUR_API_KEY"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'name' => 'July Promo List',
'country_code' => '254',
'file' => new CURLFile('/path/to/contacts.csv', 'text/csv', 'contacts.csv')
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Delete Contact Group
Permanently deletes a contact group and all contacts within it. This action cannot be undone.
/contact/group/delete
Request Body Parameters
| Field | Required | Type | Description |
|---|---|---|---|
| contact_group_id | required | Integer | ID of the contact group to delete. Obtain this from List Contact Groups. |
Request body:
{
"contact_group_id": 42
}
Success response (HTTP 201):
"Contact deleted successfully"
curl --location --request POST 'https://sms-service.intouchvas.io/contact/group/delete' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
"contact_group_id": 42
}'
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://sms-service.intouchvas.io/contact/group/delete")
header = { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY' }
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = { contact_group_id: 42 }.to_json
response = http.request(request)
puts response.body
import requests
import json
headers = {'Content-Type': 'application/json', 'x-api-key': 'YOUR_API_KEY'}
payload = {"contact_group_id": 42}
response = requests.post(
'https://sms-service.intouchvas.io/contact/group/delete',
data=json.dumps(payload),
headers=headers
)
print(response.status_code)
print(response.json())
fetch('https://sms-service.intouchvas.io/contact/group/delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY'
},
body: JSON.stringify({ contact_group_id: 42 })
})
.then(res => res.json())
.then(data => console.log(data));
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
payload, _ := json.Marshal(map[string]int{"contact_group_id": 42})
client := &http.Client{}
req, _ := http.NewRequest("POST", "https://sms-service.intouchvas.io/contact/group/delete", bytes.NewBuffer(payload))
req.Header.Add("Content-Type", "application/json")
req.Header.Add("x-api-key", "YOUR_API_KEY")
res, _ := client.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
import java.io.*;
import java.net.*;
URL url = new URL("https://sms-service.intouchvas.io/contact/group/delete");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("x-api-key", "YOUR_API_KEY");
con.setDoOutput(true);
try (OutputStream os = con.getOutputStream()) {
os.write("{\"contact_group_id\":42}".getBytes("utf-8"));
}
System.out.println(con.getResponseCode());
<?php
$ch = curl_init("https://sms-service.intouchvas.io/contact/group/delete");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(["contact_group_id" => 42]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"x-api-key: YOUR_API_KEY"
]);
echo curl_exec($ch);
curl_close($ch);
Errors
The IntouchVAS SMS API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request -- Your request is invalid. |
| 401 | Unauthorized -- Your API key is wrong. |
| 403 | Forbidden -- The data requested is hidden for administrators only. |
| 404 | Not Found -- The specified data could not be found. |
| 405 | Method Not Allowed -- You tried to access a data with an invalid method. |
| 406 | Not Acceptable -- You requested a format that isn't json. |
| 418 | Invalid Parameters supplied. |
| 421 | Invalid Parameters supplied. |
| 422 | Invalid Parameters supplied. |
| 428 | Invalid API Key or session expired. |
| 429 | Too Many Requests |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
SMS Delivery Status
The InTouchVAS SMS API will the following DLR status:
| Status | Meaning |
|---|---|
| 0 | Failed, SMS was not send to Telco. This occurs due to billing issues |
| 1 | Failed, SMS was not send to Telco. This |
| 2 | Pending. SMS was send to Telco but Telco did not send back delivery status |
| 3 | Delivered. SMS Delivered to Phone |