NAV
shell ruby python javascript go java php

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

  1. Log in to your InTouchVAS dashboard.
  2. On the top right corner, click the person/profile icon.
  3. Select Account.
  4. Navigate to the API Key section.
  5. Click Generate API Key (if no key exists).
  6. 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.

POST /api/message/send/group

When to use each SMS type

SMS TypeUse caseExample
PromotionalMarketing blasts, offers, announcements sent to opt-in contact groupsMonthly newsletter, product launch
TransactionalEvent-driven notifications sent to groups of affected usersScheduled maintenance alert, bulk order updates

Request Body Parameters

FieldRequiredTypeDescription
contact_group_idrequiredStringID of the contact group to message. Get this from List Contact Groups.
sender_idrequiredStringYour registered sender ID (alphanumeric, max 11 chars).
messagerequiredStringThe SMS message body. Use {first_name}, {other_name}, {custom_1}{custom_5} for personalisation.
campaign_nameoptionalStringLabel to identify this campaign in your reports.
sms_typeoptionalStringpromotional (default) or transactional.
scheduleoptionalBooleanSet true to schedule for future delivery. Requires schedule_date and schedule_time.
schedule_dateoptionalStringDate for scheduled send, format YYYY-MM-DD.
schedule_timeoptionalStringTime 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.

Typical workflow
  1. Create a new group and add contacts — Create Contacts
  2. Or upload a CSV file of contacts — Upload Contacts (CSV)
  3. Retrieve your group IDs — List Contact Groups
  4. 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.

GET /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.

POST /contact/create

Request Body Parameters

FieldRequiredTypeDescription
namerequired*StringContact group name. Required if id is 0.
idoptionalIntegerExisting contact group ID. Supply this to add contacts to an existing group.
country_codeoptionalStringDefault dialling code e.g. 254. Applied to short/local numbers that have no country prefix.
contactsrequiredArrayList of contact objects (see below).

Contact Object Fields

FieldRequiredTypeDescription
msisdnrequiredStringPhone number in any format — international (+254712345678), local (0712345678), or short (712345678).
first_nameoptionalStringContact first name. Used for SMS personalisation.
other_nameoptionalStringContact surname or other name.
country_codeoptionalStringPer-contact country code override. Overrides group-level country_code for this number.
custom_1 … custom_5optionalStringUp 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.

POST /contact/upload multipart/form-data

Form Data Parameters

FieldRequiredTypeDescription
filerequiredFileCSV or Excel (.xlsx) file. First row is treated as a header and skipped.
namerequired*StringContact group name. Required when id is not provided.
idoptionalIntegerExisting contact group ID. Contacts will be added to this group.
country_codeoptionalStringDefault 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.

ColumnDescription
msisdnPhone number (any format)
first_nameFirst name for personalisation
other_nameLast name / other name
custom_1Custom field 1
custom_2Custom field 2
custom_3Custom field 3
custom_4Custom field 4
custom_5Custom 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.

POST /contact/group/delete

Request Body Parameters

FieldRequiredTypeDescription
contact_group_idrequiredIntegerID 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