💬 WhatsApp API @ Best Rate | Zero Setup Fee → 99.9% Uptime OTP Delivery — Try FREE Demo! 🏆 10,000+ Registered Businesses — 2,000+ Enterprise Clients Served 🚀 API Integration in Under 5 Minutes 🏅 Verified Business Badge with RCS Messaging 💬 WhatsApp API @ Best Rate | Zero Setup Fee → 99.9% Uptime OTP Delivery — Try FREE Demo! 🏆 10,000+ Registered Businesses — 2,000+ Enterprise Clients Served 🚀 API Integration in Under 5 Minutes 🏅 Verified Business Badge with RCS Messaging
Talk to Sales: India 1800 102 1822
Developer documentation

SMS, OTP, WhatsApp, RCS, Voice & Email API Documentation

Everything you need to integrate SMSGatewayHub: endpoints, parameters, copy-ready code in cURL, PHP, Python, Node.js and C#, error codes, Swagger and downloadable PDF references.

REST / JSONHTTP GET & XMLWebhooksSMTP relayDLT-ready
7APIs, one account
200 RPSStandard throughput
99.9%Uptime SLA
ISO 27001Certified platform

Quick answer

SMSGatewayHub provides REST APIs for SMS and OTP (/api/mt/SendSMS), WhatsApp templates (Sparklebot /api/v1/{tenant}/messages/template), RCS (/api/v1/Rcs/sendmessage), voice calls and email, plus an SMTP relay on port 587. Sign up free, copy your API key from the panel, and send with the cURL, PHP, Python, Node.js or C# samples below. All APIs use Pay As You Go credits.

SMSGatewayHub API products

One account and one panel for every channel. Each API below has its own endpoint, authentication and examples on this page, plus a downloadable PDF and the interactive Swagger reference.

SMS API

Transactional, service, promotional and international SMS over HTTP GET, JSON or XML.

Product details →

OTP API

Priority OTP route on the same SendSMS endpoint with channel=OTP.

Product details →

WhatsApp API

Approved templates with text, media and document headers.

Product details →

RCS API

Rich, verified RCS template messages with variables.

Product details →

Voice API

Text-to-speech and audio calls with DTMF, transfer and reports.

Product details →

Email API

Transactional and bulk email with attachments and tracking.

Product details →

SMTP relay

Plug-and-play SMTP on port 587 with STARTTLS.

Product details →

SMPP

High-throughput SMPP binds for enterprises and resellers.

Product details →

Quick start: send your first SMS

  1. Create a free account and log in to the panel.
  2. Copy your API key from API Settings (WhatsApp token, RCS key, voice and email credentials are in their own panel sections).
  3. Register your entity, sender ID and templates on DLT for SMS. See DLT registration and sample templates.
  4. Send your first request with the snippet below, then check delivery with the delivery report API or webhooks.
  5. Go live: whitelist your server IPs, add webhooks and move to Pay As You Go credits.
curl -G "https://www.smsgatewayhub.com/api/mt/SendSMS" \
  --data-urlencode "APIKey=YOUR_API_KEY" \
  --data-urlencode "senderid=TESTIN" \
  --data-urlencode "channel=2" \
  --data-urlencode "DCS=0" \
  --data-urlencode "flashsms=0" \
  --data-urlencode "number=9198XXXXXXXX" \
  --data-urlencode "text=Your order 12345 is confirmed - TESTIN" \
  --data-urlencode "route=1" \
  --data-urlencode "EntityId=YOUR_ENTITY_ID" \
  --data-urlencode "dlttemplateid=YOUR_TEMPLATE_ID"
<?php
$params = [
    'APIKey' => 'YOUR_API_KEY',
    'senderid' => 'TESTIN',
    'channel' => '2',
    'DCS' => '0',
    'flashsms' => '0',
    'number' => '9198XXXXXXXX',
    'text' => 'Your order 12345 is confirmed - TESTIN',
    'route' => '1',
    'EntityId' => 'YOUR_ENTITY_ID',
    'dlttemplateid' => 'YOUR_TEMPLATE_ID'
];
$url = 'https://www.smsgatewayhub.com/api/mt/SendSMS?' . http_build_query($params);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
if ($result['ErrorCode'] === '000') {
    echo 'Sent. JobId: ' . $result['JobId'];
} else {
    echo 'Error ' . $result['ErrorCode'] . ': ' . $result['ErrorMessage'];
}
import requests

params = {
    "APIKey": "YOUR_API_KEY",
    "senderid": "TESTIN",
    "channel": "2",
    "DCS": "0",
    "flashsms": "0",
    "number": "9198XXXXXXXX",
    "text": "Your order 12345 is confirmed - TESTIN",
    "route": "1",
    "EntityId": "YOUR_ENTITY_ID",
    "dlttemplateid": "YOUR_TEMPLATE_ID"
}
r = requests.get("https://www.smsgatewayhub.com/api/mt/SendSMS", params=params, timeout=30)
data = r.json()
print(data["ErrorCode"], data.get("JobId"), data["ErrorMessage"])
const params = new URLSearchParams({
  APIKey: "YOUR_API_KEY",
  senderid: "TESTIN",
  channel: "2",
  DCS: "0",
  flashsms: "0",
  number: "9198XXXXXXXX",
  text: "Your order 12345 is confirmed - TESTIN",
  route: "1",
  EntityId: "YOUR_ENTITY_ID",
  dlttemplateid: "YOUR_TEMPLATE_ID"
});

const res = await fetch(`https://www.smsgatewayhub.com/api/mt/SendSMS?${params}`);
const data = await res.json();
console.log(data.ErrorCode, data.JobId, data.ErrorMessage);
using System.Net.Http;
using System.Linq;

var p = new Dictionary<string, string> {
    ["APIKey"] = "YOUR_API_KEY",
    ["senderid"] = "TESTIN",
    ["channel"] = "2",
    ["DCS"] = "0",
    ["flashsms"] = "0",
    ["number"] = "9198XXXXXXXX",
    ["text"] = "Your order 12345 is confirmed - TESTIN",
    ["route"] = "1",
    ["EntityId"] = "YOUR_ENTITY_ID",
    ["dlttemplateid"] = "YOUR_TEMPLATE_ID"
};
var query = string.Join("&", p.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
using var http = new HttpClient();
var json = await http.GetStringAsync("https://www.smsgatewayhub.com/api/mt/SendSMS?" + query);
Console.WriteLine(json);
https://www.smsgatewayhub.com/api/mt/SendSMS?APIKey=YOUR_API_KEY&senderid=TESTIN&channel=2&DCS=0&flashsms=0&number=9198XXXXXXXX&text=Your%20order%2012345%20is%20confirmed%20-%20TESTIN&route=1&EntityId=YOUR_ENTITY_ID&dlttemplateid=YOUR_TEMPLATE_ID

Base URLs and authentication

APIBase URL / hostAuthentication
SMS / OTP / Internationalhttps://www.smsgatewayhub.com/api/mt/APIKey query parameter or JSON field
RCS Messaginghttps://www.smsgatewayhub.com/api/v1/Rcs/sendmessageAuthorization header: your RCS API key
WhatsApp Businesshttps://sparklebot.in/api/v1/{tenant_subdomain}/messages/templateAuthorization: Bearer {API token}
Voice (TTS / OBD)https://vapi.smsgatewayhub.com/tts/3/Authorization: Basic base64(username:password)
Email APIhttps://e.api.itwalk.in/email/1/sendBasic auth (username:password) or Authorization: App {API key}
SMTP relaysmtp-api.itwalk.in : 587 (STARTTLS)SMTP username and password
Interactive referencehttps://www.smsgatewayhub.com/swagger/ui/indexTry endpoints in Swagger UI
Keep every key and token on your server. Never put API keys in mobile apps, browser JavaScript or public repositories. You can restrict SMS API keys to specific IP addresses in the panel.

Throughput, SLA and security

TierThroughputTypical response time
Standard200 requests / second100–500 ms
High-availability clusterUp to 2000 TPS50–150 ms
ISO 27001 ISO 9001:2015 SOC 2 VAPT tested TRAI DLT

All endpoints use TLS, sit behind a web application firewall and support IP-based access restriction. Delivery data is retained for 1 year for banking clients and 6 months for other clients, then archived. Details are on the Trust Center.

Need the high-availability cluster? Email info@smsgatewayhub.com or call 1800 102 1822.

Swagger reference and PDF downloads

SMS & OTP API

Send SMSGET

Send a DLT-compliant SMS to one number. This is the core endpoint for transactional, service, promotional, OTP and international SMS.

GEThttps://www.smsgatewayhub.com/api/mt/SendSMS
ParameterTypeRequiredDescription
APIKeystringYesYour API key from the panel (API Settings).
senderidstringYesDLT-approved 6-character sender ID (header).
channelstringYes2 Transactional/Service, 1 Promotional, OTP OTP route, INT International.
DCSstringNo0 English/GSM (default), 8 Unicode (Hindi and regional languages).
flashsmsstringNo0 normal SMS (default), 1 flash SMS.
numberstringYesRecipient with country code, e.g. 9198XXXXXXXX. Comma-separate for bulk.
textstringYesMessage text, URL-encoded. Must match the DLT template exactly.
routestringNoRoute ID assigned to your account.
EntityIdstringYes*DLT Principal Entity ID. *Not needed for channel=INT.
dlttemplateidstringYes*DLT content template ID. *Not needed for channel=INT.
schedtimestringNoSchedule time, format yyyy/mm/dd hh:mm:ss AM/PM.
groupidstringNoSend to a saved contact group instead of numbers.

Request

curl -G "https://www.smsgatewayhub.com/api/mt/SendSMS" \
  --data-urlencode "APIKey=YOUR_API_KEY" \
  --data-urlencode "senderid=TESTIN" \
  --data-urlencode "channel=2" \
  --data-urlencode "DCS=0" \
  --data-urlencode "flashsms=0" \
  --data-urlencode "number=9198XXXXXXXX" \
  --data-urlencode "text=Your order 12345 is confirmed - TESTIN" \
  --data-urlencode "route=1" \
  --data-urlencode "EntityId=YOUR_ENTITY_ID" \
  --data-urlencode "dlttemplateid=YOUR_TEMPLATE_ID"
<?php
$params = [
    'APIKey' => 'YOUR_API_KEY',
    'senderid' => 'TESTIN',
    'channel' => '2',
    'DCS' => '0',
    'flashsms' => '0',
    'number' => '9198XXXXXXXX',
    'text' => 'Your order 12345 is confirmed - TESTIN',
    'route' => '1',
    'EntityId' => 'YOUR_ENTITY_ID',
    'dlttemplateid' => 'YOUR_TEMPLATE_ID'
];
$url = 'https://www.smsgatewayhub.com/api/mt/SendSMS?' . http_build_query($params);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
if ($result['ErrorCode'] === '000') {
    echo 'Sent. JobId: ' . $result['JobId'];
} else {
    echo 'Error ' . $result['ErrorCode'] . ': ' . $result['ErrorMessage'];
}
import requests

params = {
    "APIKey": "YOUR_API_KEY",
    "senderid": "TESTIN",
    "channel": "2",
    "DCS": "0",
    "flashsms": "0",
    "number": "9198XXXXXXXX",
    "text": "Your order 12345 is confirmed - TESTIN",
    "route": "1",
    "EntityId": "YOUR_ENTITY_ID",
    "dlttemplateid": "YOUR_TEMPLATE_ID"
}
r = requests.get("https://www.smsgatewayhub.com/api/mt/SendSMS", params=params, timeout=30)
data = r.json()
print(data["ErrorCode"], data.get("JobId"), data["ErrorMessage"])
const params = new URLSearchParams({
  APIKey: "YOUR_API_KEY",
  senderid: "TESTIN",
  channel: "2",
  DCS: "0",
  flashsms: "0",
  number: "9198XXXXXXXX",
  text: "Your order 12345 is confirmed - TESTIN",
  route: "1",
  EntityId: "YOUR_ENTITY_ID",
  dlttemplateid: "YOUR_TEMPLATE_ID"
});

const res = await fetch(`https://www.smsgatewayhub.com/api/mt/SendSMS?${params}`);
const data = await res.json();
console.log(data.ErrorCode, data.JobId, data.ErrorMessage);
using System.Net.Http;
using System.Linq;

var p = new Dictionary<string, string> {
    ["APIKey"] = "YOUR_API_KEY",
    ["senderid"] = "TESTIN",
    ["channel"] = "2",
    ["DCS"] = "0",
    ["flashsms"] = "0",
    ["number"] = "9198XXXXXXXX",
    ["text"] = "Your order 12345 is confirmed - TESTIN",
    ["route"] = "1",
    ["EntityId"] = "YOUR_ENTITY_ID",
    ["dlttemplateid"] = "YOUR_TEMPLATE_ID"
};
var query = string.Join("&", p.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
using var http = new HttpClient();
var json = await http.GetStringAsync("https://www.smsgatewayhub.com/api/mt/SendSMS?" + query);
Console.WriteLine(json);
https://www.smsgatewayhub.com/api/mt/SendSMS?APIKey=YOUR_API_KEY&senderid=TESTIN&channel=2&DCS=0&flashsms=0&number=9198XXXXXXXX&text=Your%20order%2012345%20is%20confirmed%20-%20TESTIN&route=1&EntityId=YOUR_ENTITY_ID&dlttemplateid=YOUR_TEMPLATE_ID

Response

{
  "ErrorCode": "000",
  "ErrorMessage": "Success",
  "JobId": "20047",
  "MessageData": [
    { "Number": "9198XXXXXXXX", "MessageId": "BqTiw66A2UGLFV3DnwHFLQ" }
  ]
}
For Hindi or regional-language text use DCS=8 and URL-encode the Unicode text (70 characters per SMS part). Set flashsms=1 for a flash message. Use schedtime to schedule.

Bulk SMSGET

GEThttps://www.smsgatewayhub.com/api/mt/SendSMS

Pass comma-separated numbers in number; all other parameters are the same as Send SMS. For very large lists use the JSON POST API or SMPP.

curl -G "https://www.smsgatewayhub.com/api/mt/SendSMS" \
  --data-urlencode "APIKey=YOUR_API_KEY" \
  --data-urlencode "senderid=TESTIN" \
  --data-urlencode "channel=2" \
  --data-urlencode "DCS=0" \
  --data-urlencode "flashsms=0" \
  --data-urlencode "number=9198XXXXXXXX,9199XXXXXXXX" \
  --data-urlencode "text=Your order 12345 is confirmed - TESTIN" \
  --data-urlencode "route=1" \
  --data-urlencode "EntityId=YOUR_ENTITY_ID" \
  --data-urlencode "dlttemplateid=YOUR_TEMPLATE_ID"
<?php
$params = [
    'APIKey' => 'YOUR_API_KEY',
    'senderid' => 'TESTIN',
    'channel' => '2',
    'DCS' => '0',
    'flashsms' => '0',
    'number' => '9198XXXXXXXX,9199XXXXXXXX',
    'text' => 'Your order 12345 is confirmed - TESTIN',
    'route' => '1',
    'EntityId' => 'YOUR_ENTITY_ID',
    'dlttemplateid' => 'YOUR_TEMPLATE_ID'
];
$url = 'https://www.smsgatewayhub.com/api/mt/SendSMS?' . http_build_query($params);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
if ($result['ErrorCode'] === '000') {
    echo 'Sent. JobId: ' . $result['JobId'];
} else {
    echo 'Error ' . $result['ErrorCode'] . ': ' . $result['ErrorMessage'];
}
import requests

params = {
    "APIKey": "YOUR_API_KEY",
    "senderid": "TESTIN",
    "channel": "2",
    "DCS": "0",
    "flashsms": "0",
    "number": "9198XXXXXXXX,9199XXXXXXXX",
    "text": "Your order 12345 is confirmed - TESTIN",
    "route": "1",
    "EntityId": "YOUR_ENTITY_ID",
    "dlttemplateid": "YOUR_TEMPLATE_ID"
}
r = requests.get("https://www.smsgatewayhub.com/api/mt/SendSMS", params=params, timeout=30)
data = r.json()
print(data["ErrorCode"], data.get("JobId"), data["ErrorMessage"])
const params = new URLSearchParams({
  APIKey: "YOUR_API_KEY",
  senderid: "TESTIN",
  channel: "2",
  DCS: "0",
  flashsms: "0",
  number: "9198XXXXXXXX,9199XXXXXXXX",
  text: "Your order 12345 is confirmed - TESTIN",
  route: "1",
  EntityId: "YOUR_ENTITY_ID",
  dlttemplateid: "YOUR_TEMPLATE_ID"
});

const res = await fetch(`https://www.smsgatewayhub.com/api/mt/SendSMS?${params}`);
const data = await res.json();
console.log(data.ErrorCode, data.JobId, data.ErrorMessage);
using System.Net.Http;
using System.Linq;

var p = new Dictionary<string, string> {
    ["APIKey"] = "YOUR_API_KEY",
    ["senderid"] = "TESTIN",
    ["channel"] = "2",
    ["DCS"] = "0",
    ["flashsms"] = "0",
    ["number"] = "9198XXXXXXXX,9199XXXXXXXX",
    ["text"] = "Your order 12345 is confirmed - TESTIN",
    ["route"] = "1",
    ["EntityId"] = "YOUR_ENTITY_ID",
    ["dlttemplateid"] = "YOUR_TEMPLATE_ID"
};
var query = string.Join("&", p.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
using var http = new HttpClient();
var json = await http.GetStringAsync("https://www.smsgatewayhub.com/api/mt/SendSMS?" + query);
Console.WriteLine(json);
https://www.smsgatewayhub.com/api/mt/SendSMS?APIKey=YOUR_API_KEY&senderid=TESTIN&channel=2&DCS=0&flashsms=0&number=9198XXXXXXXX%2C9199XXXXXXXX&text=Your%20order%2012345%20is%20confirmed%20-%20TESTIN&route=1&EntityId=YOUR_ENTITY_ID&dlttemplateid=YOUR_TEMPLATE_ID

Response

{
  "ErrorCode": "000",
  "ErrorMessage": "Success",
  "JobId": "20048",
  "MessageData": [
    { "Number": "9198XXXXXXXX", "MessageId": "mvHdpSyS7UOs9hjxixQLvw" },
    { "Number": "9199XXXXXXXX", "MessageId": "PfivClgH20iG6G5R3usHwA" }
  ]
}

OTP SMSGET

GEThttps://www.smsgatewayhub.com/api/mt/SendSMS

Set channel=OTP on the same endpoint. OTP traffic uses priority routes that reach DND numbers 24x7, and still needs a DLT-approved OTP template with the code tagged as {#numeric#}. Generate and verify the OTP on your server; expire it after a few minutes and limit retries.

curl -G "https://www.smsgatewayhub.com/api/mt/SendSMS" \
  --data-urlencode "APIKey=YOUR_API_KEY" \
  --data-urlencode "senderid=TESTIN" \
  --data-urlencode "channel=OTP" \
  --data-urlencode "DCS=0" \
  --data-urlencode "flashsms=0" \
  --data-urlencode "number=9198XXXXXXXX" \
  --data-urlencode "text=482913 is your OTP to log in to ABC App. Valid for 10 minutes. - TESTIN" \
  --data-urlencode "route=1" \
  --data-urlencode "EntityId=YOUR_ENTITY_ID" \
  --data-urlencode "dlttemplateid=YOUR_TEMPLATE_ID"
<?php
$params = [
    'APIKey' => 'YOUR_API_KEY',
    'senderid' => 'TESTIN',
    'channel' => 'OTP',
    'DCS' => '0',
    'flashsms' => '0',
    'number' => '9198XXXXXXXX',
    'text' => '482913 is your OTP to log in to ABC App. Valid for 10 minutes. - TESTIN',
    'route' => '1',
    'EntityId' => 'YOUR_ENTITY_ID',
    'dlttemplateid' => 'YOUR_TEMPLATE_ID'
];
$url = 'https://www.smsgatewayhub.com/api/mt/SendSMS?' . http_build_query($params);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
if ($result['ErrorCode'] === '000') {
    echo 'Sent. JobId: ' . $result['JobId'];
} else {
    echo 'Error ' . $result['ErrorCode'] . ': ' . $result['ErrorMessage'];
}
import requests

params = {
    "APIKey": "YOUR_API_KEY",
    "senderid": "TESTIN",
    "channel": "OTP",
    "DCS": "0",
    "flashsms": "0",
    "number": "9198XXXXXXXX",
    "text": "482913 is your OTP to log in to ABC App. Valid for 10 minutes. - TESTIN",
    "route": "1",
    "EntityId": "YOUR_ENTITY_ID",
    "dlttemplateid": "YOUR_TEMPLATE_ID"
}
r = requests.get("https://www.smsgatewayhub.com/api/mt/SendSMS", params=params, timeout=30)
data = r.json()
print(data["ErrorCode"], data.get("JobId"), data["ErrorMessage"])
const params = new URLSearchParams({
  APIKey: "YOUR_API_KEY",
  senderid: "TESTIN",
  channel: "OTP",
  DCS: "0",
  flashsms: "0",
  number: "9198XXXXXXXX",
  text: "482913 is your OTP to log in to ABC App. Valid for 10 minutes. - TESTIN",
  route: "1",
  EntityId: "YOUR_ENTITY_ID",
  dlttemplateid: "YOUR_TEMPLATE_ID"
});

const res = await fetch(`https://www.smsgatewayhub.com/api/mt/SendSMS?${params}`);
const data = await res.json();
console.log(data.ErrorCode, data.JobId, data.ErrorMessage);
using System.Net.Http;
using System.Linq;

var p = new Dictionary<string, string> {
    ["APIKey"] = "YOUR_API_KEY",
    ["senderid"] = "TESTIN",
    ["channel"] = "OTP",
    ["DCS"] = "0",
    ["flashsms"] = "0",
    ["number"] = "9198XXXXXXXX",
    ["text"] = "482913 is your OTP to log in to ABC App. Valid for 10 minutes. - TESTIN",
    ["route"] = "1",
    ["EntityId"] = "YOUR_ENTITY_ID",
    ["dlttemplateid"] = "YOUR_TEMPLATE_ID"
};
var query = string.Join("&", p.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
using var http = new HttpClient();
var json = await http.GetStringAsync("https://www.smsgatewayhub.com/api/mt/SendSMS?" + query);
Console.WriteLine(json);
https://www.smsgatewayhub.com/api/mt/SendSMS?APIKey=YOUR_API_KEY&senderid=TESTIN&channel=OTP&DCS=0&flashsms=0&number=9198XXXXXXXX&text=482913%20is%20your%20OTP%20to%20log%20in%20to%20ABC%20App.%20Valid%20for%2010%20minutes.%20-%20TESTIN&route=1&EntityId=YOUR_ENTITY_ID&dlttemplateid=YOUR_TEMPLATE_ID
Learn more on the OTP SMS service page or add a missed call OTP fallback.

International SMSGET

GEThttps://www.smsgatewayhub.com/api/mt/SendSMS

Use channel=INT with the full number including country code and no +. EntityId and dlttemplateid are not required. See international bulk SMS.

curl -G "https://www.smsgatewayhub.com/api/mt/SendSMS" \
  --data-urlencode "APIKey=YOUR_API_KEY" \
  --data-urlencode "senderid=TESTIN" \
  --data-urlencode "channel=INT" \
  --data-urlencode "DCS=0" \
  --data-urlencode "flashsms=0" \
  --data-urlencode "number=12093158246" \
  --data-urlencode "text=Your verification code is 482913" \
  --data-urlencode "route=1"
<?php
$params = [
    'APIKey' => 'YOUR_API_KEY',
    'senderid' => 'TESTIN',
    'channel' => 'INT',
    'DCS' => '0',
    'flashsms' => '0',
    'number' => '12093158246',
    'text' => 'Your verification code is 482913',
    'route' => '1'
];
$url = 'https://www.smsgatewayhub.com/api/mt/SendSMS?' . http_build_query($params);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
if ($result['ErrorCode'] === '000') {
    echo 'Sent. JobId: ' . $result['JobId'];
} else {
    echo 'Error ' . $result['ErrorCode'] . ': ' . $result['ErrorMessage'];
}
import requests

params = {
    "APIKey": "YOUR_API_KEY",
    "senderid": "TESTIN",
    "channel": "INT",
    "DCS": "0",
    "flashsms": "0",
    "number": "12093158246",
    "text": "Your verification code is 482913",
    "route": "1"
}
r = requests.get("https://www.smsgatewayhub.com/api/mt/SendSMS", params=params, timeout=30)
data = r.json()
print(data["ErrorCode"], data.get("JobId"), data["ErrorMessage"])
const params = new URLSearchParams({
  APIKey: "YOUR_API_KEY",
  senderid: "TESTIN",
  channel: "INT",
  DCS: "0",
  flashsms: "0",
  number: "12093158246",
  text: "Your verification code is 482913",
  route: "1"
});

const res = await fetch(`https://www.smsgatewayhub.com/api/mt/SendSMS?${params}`);
const data = await res.json();
console.log(data.ErrorCode, data.JobId, data.ErrorMessage);
using System.Net.Http;
using System.Linq;

var p = new Dictionary<string, string> {
    ["APIKey"] = "YOUR_API_KEY",
    ["senderid"] = "TESTIN",
    ["channel"] = "INT",
    ["DCS"] = "0",
    ["flashsms"] = "0",
    ["number"] = "12093158246",
    ["text"] = "Your verification code is 482913",
    ["route"] = "1"
};
var query = string.Join("&", p.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
using var http = new HttpClient();
var json = await http.GetStringAsync("https://www.smsgatewayhub.com/api/mt/SendSMS?" + query);
Console.WriteLine(json);
https://www.smsgatewayhub.com/api/mt/SendSMS?APIKey=YOUR_API_KEY&senderid=TESTIN&channel=INT&DCS=0&flashsms=0&number=12093158246&text=Your%20verification%20code%20is%20482913&route=1

JSON and XML POST APIPOST

POSThttps://www.smsgatewayhub.com/api/mt/SendSMS

Send one or many messages in a single POST with Content-Type: application/json.

curl -X POST "https://www.smsgatewayhub.com/api/mt/SendSMS" \
  -H "Content-Type: application/json" \
  -d '{
  "Account": {
    "APIkey": "YOUR_API_KEY",
    "SenderId": "TESTIN",
    "Channel": "2",
    "DCS": "0",
    "EntityId": "YOUR_ENTITY_ID"
  },
  "Messages": [
    {
      "Text": "Your order 12345 is confirmed - TESTIN",
      "DLTTemplateId": "YOUR_TEMPLATE_ID",
      "Number": "9198XXXXXXXX"
    }
  ]
}'
<?php
$payload = <<<'JSON'
{
  "Account": {
    "APIkey": "YOUR_API_KEY",
    "SenderId": "TESTIN",
    "Channel": "2",
    "DCS": "0",
    "EntityId": "YOUR_ENTITY_ID"
  },
  "Messages": [
    {
      "Text": "Your order 12345 is confirmed - TESTIN",
      "DLTTemplateId": "YOUR_TEMPLATE_ID",
      "Number": "9198XXXXXXXX"
    }
  ]
}
JSON;

$ch = curl_init('https://www.smsgatewayhub.com/api/mt/SendSMS');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "Account": {
    "APIkey": "YOUR_API_KEY",
    "SenderId": "TESTIN",
    "Channel": "2",
    "DCS": "0",
    "EntityId": "YOUR_ENTITY_ID"
  },
  "Messages": [
    {
      "Text": "Your order 12345 is confirmed - TESTIN",
      "DLTTemplateId": "YOUR_TEMPLATE_ID",
      "Number": "9198XXXXXXXX"
    }
  ]
}
r = requests.post("https://www.smsgatewayhub.com/api/mt/SendSMS",
                  headers={"Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://www.smsgatewayhub.com/api/mt/SendSMS", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    "Account": {
      "APIkey": "YOUR_API_KEY",
      "SenderId": "TESTIN",
      "Channel": "2",
      "DCS": "0",
      "EntityId": "YOUR_ENTITY_ID"
    },
    "Messages": [
      {
        "Text": "Your order 12345 is confirmed - TESTIN",
        "DLTTemplateId": "YOUR_TEMPLATE_ID",
        "Number": "9198XXXXXXXX"
      }
    ]
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
var body = new StringContent(@"{""Account"": {""APIkey"": ""YOUR_API_KEY"", ""SenderId"": ""TESTIN"", ""Channel"": ""2"", ""DCS"": ""0"", ""EntityId"": ""YOUR_ENTITY_ID""}, ""Messages"": [{""Text"": ""Your order 12345 is confirmed - TESTIN"", ""DLTTemplateId"": ""YOUR_TEMPLATE_ID"", ""Number"": ""9198XXXXXXXX""}]}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://www.smsgatewayhub.com/api/mt/SendSMS", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

XML body

Send the same request as XML with Content-Type: application/xml.

<SmsQueue>
  <Account>
    <APIKey>YOUR_API_KEY</APIKey>
    <SenderId>TESTIN</SenderId>
    <Channel>2</Channel>
    <EntityId>YOUR_ENTITY_ID</EntityId>
    <DCS>0</DCS>
    <Route>1</Route>
  </Account>
  <Messages>
    <Message>
      <Number>9198XXXXXXXX</Number>
      <Text>Your order 12345 is confirmed - TESTIN</Text>
      <DltTemplateId>YOUR_TEMPLATE_ID</DltTemplateId>
    </Message>
  </Messages>
</SmsQueue>
curl -X POST "https://www.smsgatewayhub.com/api/mt/SendSMS" \
  -H "Content-Type: application/xml" \
  --data-binary @message.xml

Check balanceGET

GEThttps://www.smsgatewayhub.com/api/mt/GetBalance?APIKey=YOUR_API_KEY
{ "ErrorCode": "0", "ErrorMessage": "Success", "Balance": "9988" }

Delivery reportsGET

GEThttps://www.smsgatewayhub.com/api/mt/GetDelivery?APIKey=YOUR_API_KEY&jobid=20047
ParameterTypeRequiredDescription
APIKeystringYesYour API key.
jobidstringYesJobId returned by SendSMS.
{
  "ErrorCode": "0",
  "ErrorMessage": "Success",
  "DeliveryReports": [
    {
      "MessageId": "mvHdpSyS7UOs9hjxixQLvw",
      "DeliveryStatus": "Delivered",
      "DeliveryDate": "YYYY-MM-DDTHH:MM:SS"
    }
  ]
}
Success is 000 on SendSMS and 0 on GetBalance and GetDelivery. Treat both as success in your code. Live delivery reports are also available in the panel; see live delivery reports.

SMS API error codes

CodeMeaningWhat to do
000SuccessNo action. Store the JobId and MessageId so you can match the delivery report later.
001Login details cannot be blankPass APIKey on every call. Check that your code is not dropping the parameter when the value is read from config or an environment variable.
003Sender cannot be blankAdd the senderid parameter with a 6-character DLT-approved header mapped to your account.
004Message text cannot be blankSend a non-empty text parameter. URL-encode it so characters such as & and # do not cut the value short.
005Message data cannot be blankFor JSON or bulk calls, include the message array with at least one number and text pair.
006Generic errorRetry once after a short wait. If it repeats, send the full request (with the API key masked) and the response to support.
007Username or password is invalidCopy the APIKey again from API Settings in the panel. Remove stray spaces and regenerate the key if it may have leaked.
008Account not activeThe account is inactive or expired. Contact support or your account manager to activate it.
009Account lockedThe account has been locked. Contact your account manager to find out why and to unlock it.
010API restrictionAPI access is not enabled for this account or route. Ask support to enable API sending.
011IP address restrictionIP whitelisting is on and the request came from another IP. Add your server's public IP in the panel or remove the restriction.
012Invalid length of message textThe text is longer than allowed. Shorten it, or check that a Unicode message is flagged correctly (70 characters per part instead of 160).
013Mobile numbers not validUse the country code plus the number (for India, 91 followed by 10 digits) with no +, spaces or leading zero. Separate multiple numbers with commas.
014Account locked due to spam messageSending was stopped because of content flagged as spam. Contact support, review the content and send only DLT-approved templates.
015Sender ID not validThe header is not approved on DLT or not mapped to your account. Check the header and the PE-TM chain in your DLT portal and the panel.
017Group ID not validThe group ID does not exist in your panel account. Fetch the correct ID from the contacts or groups section.
018Multi message to group is not supportedSend one text to a group, or use the bulk JSON call when every number needs a different message.
019Schedule date is not validUse the documented date-time format and a future time. Check your server's time zone against IST.
020Message or mobile number cannot be blankEvery entry in the request needs both a number and a message.
021Insufficient creditsYour Pay As You Go balance is too low for this send. Recharge, then retry. Call GetBalance before large campaigns.
022Invalid JobIdThe JobId does not belong to this account or is mistyped. Use the JobId exactly as returned by the Send SMS response.
023Parameter missingA required parameter is absent. Compare your call with the parameter table in the developer docs (APIKey, senderid, channel, DCS, flashsms, number, text, route, EntityId, dlttemplateid).
024Invalid template or template mismatchThe text does not match the approved DLT template. Check spaces, punctuation, line breaks, variable values and the dlttemplateid.
025{Field} can not be blank or emptyThe field named in the message is empty. Fill it in, or remove it if it is optional.
026Invalid date rangeThe from date must be before the to date, and both must use the documented format.
027Invalid optin userThe number has not opted in for this route. Collect and record consent before sending on an opt-in route.
Full fix guide for every code: SMS API error codes. Seeing operator or DLT failures in delivery reports instead? Use the DLT error codes and solutions guide.
WhatsApp Business API

WhatsApp API overview and authentication

Send Meta-approved WhatsApp template messages from your application. Template categories and billing follow Meta's rules; see WhatsApp pricing.

POSThttps://sparklebot.in/api/v1/{tenant_subdomain}/messages/template
ItemValue
MethodPOST
Content-Typeapplication/json (URLs) or multipart/form-data (file uploads)
AuthorizationBearer YOUR_API_TOKEN
Path parameter{tenant_subdomain} – your account's tenant subdomain

Where to find the tenant subdomain and API token

  1. Log in to your WhatsApp panel.
  2. Open Settings (bottom of the left menu).
  3. Click System Setting → API Management.
  4. Copy your Tenant Subdomain and API Token.

Send a template messagePOST

ParameterTypeRequiredDescription
phone_numberstringYesRecipient with country code, e.g. 91XXXXXXXXXX.
template_namestringYesApproved template name, exactly as approved.
template_languagestringYesLanguage code used at approval, e.g. en.
field_1, field_2 …stringIf usedBody variables in order: field_1 for {{1}}, field_2 for {{2}} and so on.
header_image_urlurlIf usedPublic URL of the header image (JSON body).
header_document_urlurlIf usedPublic URL of the header document (JSON body).
header_video_urlurlIf usedPublic URL of the header video (JSON body).
header_image_filefileIf usedUpload header image (form-data).
header_document_filefileIf usedUpload header document (form-data).
header_video_filefileIf usedUpload header video (form-data).
header_field_1stringIf usedValue for a variable in a text header.
curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "order_confirmation",
  "template_language": "en",
  "field_1": "Priya",
  "field_2": "ORD58213"
}'
curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "phone_number=91XXXXXXXXXX" \
  -F "template_name=order_confirmation" \
  -F "template_language=en" \
  -F "field_1=Priya" \
  -F "field_2=ORD58213"
<?php
$payload = <<<'JSON'
{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "order_confirmation",
  "template_language": "en",
  "field_1": "Priya",
  "field_2": "ORD58213"
}
JSON;

$ch = curl_init('https://sparklebot.in/api/v1/YOUR_TENANT/messages/template');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_TOKEN', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "phone_number": "91XXXXXXXXXX",
  "template_name": "order_confirmation",
  "template_language": "en",
  "field_1": "Priya",
  "field_2": "ORD58213"
}
r = requests.post("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template",
                  headers={"Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
  body: JSON.stringify({
    "phone_number": "91XXXXXXXXXX",
    "template_name": "order_confirmation",
    "template_language": "en",
    "field_1": "Priya",
    "field_2": "ORD58213"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer YOUR_API_TOKEN");
var body = new StringContent(@"{""phone_number"": ""91XXXXXXXXXX"", ""template_name"": ""order_confirmation"", ""template_language"": ""en"", ""field_1"": ""Priya"", ""field_2"": ""ORD58213""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Header types: image, document, video and text

Use exactly one header type that matches the approved template.

Case 1: Text only

Template without a header.

curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "order_confirmation",
  "template_language": "en",
  "field_1": "Priya",
  "field_2": "ORD58213"
}'
curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "phone_number=91XXXXXXXXXX" \
  -F "template_name=order_confirmation" \
  -F "template_language=en" \
  -F "field_1=Priya" \
  -F "field_2=ORD58213"
<?php
$payload = <<<'JSON'
{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "order_confirmation",
  "template_language": "en",
  "field_1": "Priya",
  "field_2": "ORD58213"
}
JSON;

$ch = curl_init('https://sparklebot.in/api/v1/YOUR_TENANT/messages/template');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_TOKEN', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "phone_number": "91XXXXXXXXXX",
  "template_name": "order_confirmation",
  "template_language": "en",
  "field_1": "Priya",
  "field_2": "ORD58213"
}
r = requests.post("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template",
                  headers={"Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
  body: JSON.stringify({
    "phone_number": "91XXXXXXXXXX",
    "template_name": "order_confirmation",
    "template_language": "en",
    "field_1": "Priya",
    "field_2": "ORD58213"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer YOUR_API_TOKEN");
var body = new StringContent(@"{""phone_number"": ""91XXXXXXXXXX"", ""template_name"": ""order_confirmation"", ""template_language"": ""en"", ""field_1"": ""Priya"", ""field_2"": ""ORD58213""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Case 2: Image header

Template with an image header.

curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "festive_offer",
  "template_language": "en",
  "field_1": "Priya",
  "header_image_url": "https://yourdomain.com/images/offer.jpg"
}'
curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "phone_number=91XXXXXXXXXX" \
  -F "template_name=festive_offer" \
  -F "template_language=en" \
  -F "field_1=Priya" \
  -F "header_image_file=@offer.jpg"
<?php
$payload = <<<'JSON'
{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "festive_offer",
  "template_language": "en",
  "field_1": "Priya",
  "header_image_url": "https://yourdomain.com/images/offer.jpg"
}
JSON;

$ch = curl_init('https://sparklebot.in/api/v1/YOUR_TENANT/messages/template');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_TOKEN', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "phone_number": "91XXXXXXXXXX",
  "template_name": "festive_offer",
  "template_language": "en",
  "field_1": "Priya",
  "header_image_url": "https://yourdomain.com/images/offer.jpg"
}
r = requests.post("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template",
                  headers={"Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
  body: JSON.stringify({
    "phone_number": "91XXXXXXXXXX",
    "template_name": "festive_offer",
    "template_language": "en",
    "field_1": "Priya",
    "header_image_url": "https://yourdomain.com/images/offer.jpg"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer YOUR_API_TOKEN");
var body = new StringContent(@"{""phone_number"": ""91XXXXXXXXXX"", ""template_name"": ""festive_offer"", ""template_language"": ""en"", ""field_1"": ""Priya"", ""header_image_url"": ""https://yourdomain.com/images/offer.jpg""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Case 3: Document header

Template with a PDF or document header.

curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "invoice_share",
  "template_language": "en",
  "field_1": "INV-1043",
  "header_document_url": "https://yourdomain.com/docs/invoice-1043.pdf"
}'
curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "phone_number=91XXXXXXXXXX" \
  -F "template_name=invoice_share" \
  -F "template_language=en" \
  -F "field_1=INV-1043" \
  -F "header_document_file=@invoice-1043.pdf"
<?php
$payload = <<<'JSON'
{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "invoice_share",
  "template_language": "en",
  "field_1": "INV-1043",
  "header_document_url": "https://yourdomain.com/docs/invoice-1043.pdf"
}
JSON;

$ch = curl_init('https://sparklebot.in/api/v1/YOUR_TENANT/messages/template');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_TOKEN', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "phone_number": "91XXXXXXXXXX",
  "template_name": "invoice_share",
  "template_language": "en",
  "field_1": "INV-1043",
  "header_document_url": "https://yourdomain.com/docs/invoice-1043.pdf"
}
r = requests.post("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template",
                  headers={"Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
  body: JSON.stringify({
    "phone_number": "91XXXXXXXXXX",
    "template_name": "invoice_share",
    "template_language": "en",
    "field_1": "INV-1043",
    "header_document_url": "https://yourdomain.com/docs/invoice-1043.pdf"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer YOUR_API_TOKEN");
var body = new StringContent(@"{""phone_number"": ""91XXXXXXXXXX"", ""template_name"": ""invoice_share"", ""template_language"": ""en"", ""field_1"": ""INV-1043"", ""header_document_url"": ""https://yourdomain.com/docs/invoice-1043.pdf""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Case 4: Video header

Template with a video header.

curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "product_demo",
  "template_language": "en",
  "field_1": "Priya",
  "header_video_url": "https://yourdomain.com/videos/demo.mp4"
}'
curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "phone_number=91XXXXXXXXXX" \
  -F "template_name=product_demo" \
  -F "template_language=en" \
  -F "field_1=Priya" \
  -F "header_video_file=@demo.mp4"
<?php
$payload = <<<'JSON'
{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "product_demo",
  "template_language": "en",
  "field_1": "Priya",
  "header_video_url": "https://yourdomain.com/videos/demo.mp4"
}
JSON;

$ch = curl_init('https://sparklebot.in/api/v1/YOUR_TENANT/messages/template');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_TOKEN', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "phone_number": "91XXXXXXXXXX",
  "template_name": "product_demo",
  "template_language": "en",
  "field_1": "Priya",
  "header_video_url": "https://yourdomain.com/videos/demo.mp4"
}
r = requests.post("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template",
                  headers={"Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
  body: JSON.stringify({
    "phone_number": "91XXXXXXXXXX",
    "template_name": "product_demo",
    "template_language": "en",
    "field_1": "Priya",
    "header_video_url": "https://yourdomain.com/videos/demo.mp4"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer YOUR_API_TOKEN");
var body = new StringContent(@"{""phone_number"": ""91XXXXXXXXXX"", ""template_name"": ""product_demo"", ""template_language"": ""en"", ""field_1"": ""Priya"", ""header_video_url"": ""https://yourdomain.com/videos/demo.mp4""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Case 5: Text header variable

Template whose text header contains a variable.

curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "account_alert",
  "template_language": "en",
  "field_1": "Priya",
  "header_field_1": "Security alert"
}'
curl -X POST "https://sparklebot.in/api/v1/YOUR_TENANT/messages/template" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "phone_number=91XXXXXXXXXX" \
  -F "template_name=account_alert" \
  -F "template_language=en" \
  -F "field_1=Priya" \
  -F "header_field_1=Security alert"
<?php
$payload = <<<'JSON'
{
  "phone_number": "91XXXXXXXXXX",
  "template_name": "account_alert",
  "template_language": "en",
  "field_1": "Priya",
  "header_field_1": "Security alert"
}
JSON;

$ch = curl_init('https://sparklebot.in/api/v1/YOUR_TENANT/messages/template');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_TOKEN', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "phone_number": "91XXXXXXXXXX",
  "template_name": "account_alert",
  "template_language": "en",
  "field_1": "Priya",
  "header_field_1": "Security alert"
}
r = requests.post("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template",
                  headers={"Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" },
  body: JSON.stringify({
    "phone_number": "91XXXXXXXXXX",
    "template_name": "account_alert",
    "template_language": "en",
    "field_1": "Priya",
    "header_field_1": "Security alert"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer YOUR_API_TOKEN");
var body = new StringContent(@"{""phone_number"": ""91XXXXXXXXXX"", ""template_name"": ""account_alert"", ""template_language"": ""en"", ""field_1"": ""Priya"", ""header_field_1"": ""Security alert""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://sparklebot.in/api/v1/YOUR_TENANT/messages/template", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Response and notes

{
  "success": true,
  "message": "Template message sent",
  "data": {
    "message_id": "wamid.HBgMOTE5OTk5OTk5OTk5FQIAERgS",
    "phone_number": "91XXXXXXXXXX",
    "status": "sent"
  }
}
  • Use only one header type per template: image, document, video or text.
  • Header media URLs must be publicly reachable (no login or expiring links).
  • Send field_1, field_2… in the same order as the template variables.
  • For file uploads use multipart/form-data; for URLs use a JSON body.
  • In Postman, add the API token under Authorization → Bearer Token.
RCS Messaging API

Send RCS messagePOST

Send an approved RCS template to one or more recipients from your verified RCS agent.

POSThttps://www.smsgatewayhub.com/api/v1/Rcs/sendmessage
HeaderValue
AuthorizationYOUR_RCS_API_KEY
Content-Typeapplication/json
ParameterTypeRequiredDescription
botidstringYesRCS Agent / Bot ID (RCS → My Agent in the panel). The agent must be active.
templatenamestringYesName of an approved RCS template.
destinationarrayYesRecipient numbers with country code, e.g. ["919999999999"].
varobjectYes*Template variables as key/value pairs. *Required when the template has variables.
callbackdatastringNoYour reference value to track the request or campaign.

How to get the Bot ID

  1. Log in to the SMSGatewayHub panel.
  2. Open the RCS section.
  3. Go to My Agent.
  4. Find the RCS agent you want to send from.
  5. Copy its Agent ID / Bot ID into botid.
curl -X POST "https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage" \
  -H "Authorization: YOUR_RCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "botid": "YOUR_BOT_ID",
  "templatename": "order_update",
  "destination": ["919999999999"],
  "callbackdata": "ref_1001"
}'
<?php
$payload = <<<'JSON'
{
  "botid": "YOUR_BOT_ID",
  "templatename": "order_update",
  "destination": ["919999999999"],
  "callbackdata": "ref_1001"
}
JSON;

$ch = curl_init('https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: YOUR_RCS_API_KEY', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "botid": "YOUR_BOT_ID",
  "templatename": "order_update",
  "destination": ["919999999999"],
  "callbackdata": "ref_1001"
}
r = requests.post("https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage",
                  headers={"Authorization": "YOUR_RCS_API_KEY", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage", {
  method: "POST",
  headers: { "Authorization": "YOUR_RCS_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    "botid": "YOUR_BOT_ID",
    "templatename": "order_update",
    "destination": ["919999999999"],
    "callbackdata": "ref_1001"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "YOUR_RCS_API_KEY");
var body = new StringContent(@"{""botid"": ""YOUR_BOT_ID"", ""templatename"": ""order_update"", ""destination"": [""919999999999""], ""callbackdata"": ""ref_1001""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Personalised many-to-many RCS (var)POST

Pass template variables in the var object. Keys must match the variable names configured in the template.

VariableExampleDescription
FestivalNameDiwaliFestival name in the template
NamePriyaCustomer name
BusinessNameABC StoreYour business name
Offer50% OFFOffer text
Date15 OctDate shown in the message
curl -X POST "https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage" \
  -H "Authorization: YOUR_RCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "botid": "YOUR_BOT_ID",
  "templatename": "genericfestival",
  "destination": ["919999999999", "919888888888"],
  "var": {
    "FestivalName": "Diwali",
    "Name": "Priya",
    "BusinessName": "ABC Store",
    "Offer": "50% OFF",
    "Date": "15 Oct"
  },
  "callbackdata": "ref_1002"
}'
<?php
$payload = <<<'JSON'
{
  "botid": "YOUR_BOT_ID",
  "templatename": "genericfestival",
  "destination": ["919999999999", "919888888888"],
  "var": {
    "FestivalName": "Diwali",
    "Name": "Priya",
    "BusinessName": "ABC Store",
    "Offer": "50% OFF",
    "Date": "15 Oct"
  },
  "callbackdata": "ref_1002"
}
JSON;

$ch = curl_init('https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: YOUR_RCS_API_KEY', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "botid": "YOUR_BOT_ID",
  "templatename": "genericfestival",
  "destination": ["919999999999", "919888888888"],
  "var": {
    "FestivalName": "Diwali",
    "Name": "Priya",
    "BusinessName": "ABC Store",
    "Offer": "50% OFF",
    "Date": "15 Oct"
  },
  "callbackdata": "ref_1002"
}
r = requests.post("https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage",
                  headers={"Authorization": "YOUR_RCS_API_KEY", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage", {
  method: "POST",
  headers: { "Authorization": "YOUR_RCS_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    "botid": "YOUR_BOT_ID",
    "templatename": "genericfestival",
    "destination": ["919999999999", "919888888888"],
    "var": {
      "FestivalName": "Diwali",
      "Name": "Priya",
      "BusinessName": "ABC Store",
      "Offer": "50% OFF",
      "Date": "15 Oct"
    },
    "callbackdata": "ref_1002"
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "YOUR_RCS_API_KEY");
var body = new StringContent(@"{""botid"": ""YOUR_BOT_ID"", ""templatename"": ""genericfestival"", ""destination"": [""919999999999"", ""919888888888""], ""var"": {""FestivalName"": ""Diwali"", ""Name"": ""Priya"", ""BusinessName"": ""ABC Store"", ""Offer"": ""50% OFF"", ""Date"": ""15 Oct""}, ""callbackdata"": ""ref_1002""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

RCS response

{
  "success": true,
  "messageId": ["24a051ba-96eb-4050-b098-6b2c90d5d5a7"],
  "campaignId": 359,
  "routeId": 1,
  "total": 1,
  "queued": 1,
  "invalid": 0,
  "status": "Sent",
  "sendTime": "YYYY-MM-DDTHH:MM:SS.sssZ",
  "message": "Campaign Sent successfully"
}
FieldTypeDescription
successbooleanWhether the request was processed.
messageIdarrayMessage IDs generated for the submitted recipients.
campaignIdintegerCampaign ID generated for the request.
routeIdintegerRoute used for delivery.
totalintegerTotal recipient numbers submitted.
queuedintegerMessages successfully queued.
invalidintegerInvalid recipient numbers.
statusstringSubmission status.
sendTimestringSubmission timestamp (ISO 8601, UTC).
messagestringProcessing message.

Error example

{ "success": false, "error": "Authorization header is required", "message": "Authorization header is required" }
  • Send numbers with the country code; for India use 91 followed by the 10-digit number.
  • Variable names in var must exactly match the variables configured in the template.
  • Use messageId for message-level tracking and campaignId for the request.
  • Use callbackdata as your own reference ID to reconcile requests.
Voice API

Single voice call (text-to-speech)POST

Place a text-to-speech or recorded-audio call. Authenticate with HTTP Basic auth.

POSThttps://vapi.smsgatewayhub.com/tts/3/single
ParameterTypeRequiredDescription
fromstringYesCaller ID in E.164 format without +, e.g. 919999999999.
tostringYesDestination number in E.164 format.
textstringNo*Text to speak, up to 1400 characters. *Send text or audioFileUrl.
languagestringNoLanguage code, default en. See voice languages.
voice.namestringNoVoice, e.g. Joanna, Aditi, Ravi, Heera.
audioFileUrlstringNo*Public URL of a wav/mp3/ogg file (max 4 MB), used instead of text.
curl -X POST "https://vapi.smsgatewayhub.com/tts/3/single" \
  -u USERNAME:PASSWORD \
  -H "Content-Type: application/json" \
  -d '{
  "from": "919999999999",
  "to": "916666666666",
  "text": "Your appointment is confirmed for tomorrow at 11 AM.",
  "language": "en",
  "voice": { "name": "Joanna", "gender": "female" }
}'
<?php
$payload = <<<'JSON'
{
  "from": "919999999999",
  "to": "916666666666",
  "text": "Your appointment is confirmed for tomorrow at 11 AM.",
  "language": "en",
  "voice": { "name": "Joanna", "gender": "female" }
}
JSON;

$ch = curl_init('https://vapi.smsgatewayhub.com/tts/3/single');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Basic BASE64(username:password)', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "from": "919999999999",
  "to": "916666666666",
  "text": "Your appointment is confirmed for tomorrow at 11 AM.",
  "language": "en",
  "voice": { "name": "Joanna", "gender": "female" }
}
r = requests.post("https://vapi.smsgatewayhub.com/tts/3/single",
                  headers={"Authorization": "Basic BASE64(username:password)", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://vapi.smsgatewayhub.com/tts/3/single", {
  method: "POST",
  headers: { "Authorization": "Basic BASE64(username:password)", "Content-Type": "application/json" },
  body: JSON.stringify({
    "from": "919999999999",
    "to": "916666666666",
    "text": "Your appointment is confirmed for tomorrow at 11 AM.",
    "language": "en",
    "voice": { "name": "Joanna", "gender": "female" }
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Basic BASE64(username:password)");
var body = new StringContent(@"{""from"": ""919999999999"", ""to"": ""916666666666"", ""text"": ""Your appointment is confirmed for tomorrow at 11 AM."", ""language"": ""en"", ""voice"": {""name"": ""Joanna"", ""gender"": ""female""}}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://vapi.smsgatewayhub.com/tts/3/single", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Response

{
  "messages": [
    {
      "to": "916666666666",
      "status": { "groupId": 1, "groupName": "PENDING", "name": "PENDING_ENROUTE" },
      "messageId": "2250be2d4219-3af1-78856-aabe-1362af1edfd2"
    }
  ]
}

Multiple voice callsPOST

POSThttps://vapi.smsgatewayhub.com/tts/3/multi

Mix TTS and audio-file messages to many recipients in one request.

curl -X POST "https://vapi.smsgatewayhub.com/tts/3/multi" \
  -u USERNAME:PASSWORD \
  -H "Content-Type: application/json" \
  -d '{
  "messages": [
    {
      "from": "919999999999",
      "to": ["916666666666", "919999999998"],
      "audioFileUrl": "https://example.com/media.mp3"
    },
    {
      "from": "919999999999",
      "to": ["916666666666"],
      "text": "Hello from SMSGatewayHub",
      "language": "en",
      "voice": { "name": "Joanna", "gender": "female" }
    }
  ]
}'
<?php
$payload = <<<'JSON'
{
  "messages": [
    {
      "from": "919999999999",
      "to": ["916666666666", "919999999998"],
      "audioFileUrl": "https://example.com/media.mp3"
    },
    {
      "from": "919999999999",
      "to": ["916666666666"],
      "text": "Hello from SMSGatewayHub",
      "language": "en",
      "voice": { "name": "Joanna", "gender": "female" }
    }
  ]
}
JSON;

$ch = curl_init('https://vapi.smsgatewayhub.com/tts/3/multi');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => ['Authorization: Basic BASE64(username:password)', 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

payload = {
  "messages": [
    {
      "from": "919999999999",
      "to": ["916666666666", "919999999998"],
      "audioFileUrl": "https://example.com/media.mp3"
    },
    {
      "from": "919999999999",
      "to": ["916666666666"],
      "text": "Hello from SMSGatewayHub",
      "language": "en",
      "voice": { "name": "Joanna", "gender": "female" }
    }
  ]
}
r = requests.post("https://vapi.smsgatewayhub.com/tts/3/multi",
                  headers={"Authorization": "Basic BASE64(username:password)", "Content-Type": "application/json"},
                  json=payload, timeout=30)
print(r.status_code, r.json())
const res = await fetch("https://vapi.smsgatewayhub.com/tts/3/multi", {
  method: "POST",
  headers: { "Authorization": "Basic BASE64(username:password)", "Content-Type": "application/json" },
  body: JSON.stringify({
    "messages": [
      {
        "from": "919999999999",
        "to": ["916666666666", "919999999998"],
        "audioFileUrl": "https://example.com/media.mp3"
      },
      {
        "from": "919999999999",
        "to": ["916666666666"],
        "text": "Hello from SMSGatewayHub",
        "language": "en",
        "voice": { "name": "Joanna", "gender": "female" }
      }
    ]
  })
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Text;

using var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Basic BASE64(username:password)");
var body = new StringContent(@"{""messages"": [{""from"": ""919999999999"", ""to"": [""916666666666"", ""919999999998""], ""audioFileUrl"": ""https://example.com/media.mp3""}, {""from"": ""919999999999"", ""to"": [""916666666666""], ""text"": ""Hello from SMSGatewayHub"", ""language"": ""en"", ""voice"": {""name"": ""Joanna"", ""gender"": ""female""}}]}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://vapi.smsgatewayhub.com/tts/3/multi", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Advanced voice optionsPOST

POSThttps://vapi.smsgatewayhub.com/tts/3/advanced
ParameterTypeRequiredDescription
bulkIdstringNoYour identifier for the bulk request.
speechRatedoubleNoPlayback speed 0.5 to 2.0 (default 1).
notifyUrlstringNoWebhook URL for delivery reports.
recordbooleanNoRecord the call (true/false).
ringTimeoutintNoRing duration in seconds before hang-up (default 45).
machineDetectionstringNohangup or continue (billed additionally).
retry.maxCountintNoMaximum retry attempts (up to 4).

Call transfer on any DTMF key

[
  { "if": "anyDtmf", "transferTo": "919999999999", "callTransferMaxDuration": 10 }
]
Machine detection is billed in addition to the call. Promotional calls must follow TRAI calling rules; see voice SMS.

Voice delivery reportsGET

GEThttps://vapi.smsgatewayhub.com/tts/3/reports
ParameterTypeRequiredDescription
bulkIdstringNoFilter by bulk request ID.
messageIdstringNoFilter by message ID.
limitintNoMaximum reports returned (default 50).
Each report is returned once; later calls return an empty list. Store reports when you fetch them, or use notifyUrl webhooks.

Voice languages

LanguageCodeFemale voicesMale voices
English (India)en-inAditi, Heera (default), Priya, RaveenaRavi
HindihiAadita (default), KalpanaHemant
English (US)enJoanna (default), Salli, Kendra, IvyMatthew, Justin
Email API & SMTP

Send emailPOST

Send transactional or bulk email with HTML, attachments, scheduling and delivery reports. Requests use multipart/form-data.

POSThttps://e.api.itwalk.in/email/1/send
ParameterTypeRequiredDescription
fromstringYesSender with optional name, e.g. Jane Doe <jane@yourdomain.com>. Domain must be verified.
tostringYesRecipient. Repeat for multiple recipients; may be a JSON object with placeholders or messageId.
cc / bccstringNoCopy recipients; repeat for multiple.
replyTostringNoReply-to address.
subjectstringYesMessage subject.
textstringNo*Plain-text body. *Send text, html or templateId.
htmlstringNo*HTML body. If both html and text are sent, html is delivered.
templateIdintNo*Broadcast template ID (content templates are not supported).
defaultPlaceholdersstringNoDefault placeholder values for all recipients.
attachmentfileNoFile attachment. Repeat for multiple attachments.
bulkIdstringNoYour ID for the request; auto-generated if omitted.
messageIdstringNoYour ID for an individual message.
sendAtdatetimeNoSchedule delivery for a later date and time.
intermediateReportbooleanNoSend real-time intermediate delivery reports to notifyUrl.
notifyUrlstringNoCallback URL for delivery reports.
notifyContentTypestringNoapplication/json or application/xml.
callbackDatastringNoYour data returned to notifyUrl (max 4000 characters).
trackbooleanNoOpen and click tracking, default true.
trackopensbooleanNoEnable or disable open tracking.
trackclicksbooleanNoEnable or disable click tracking.
trackingUrlstringNoCallback URL for open/click notifications (enables tracking).
curl -s --user USERNAME:PASSWORD \
  https://e.api.itwalk.in/email/1/send \
  -F from='Jane Smith <jane.smith@yourdomain.com>' \
  -F to='john.smith@example.com' \
  -F replyTo='replies@yourdomain.com' \
  -F subject='Your invoice is ready' \
  -F text='Hi John, your invoice is attached.' \
  --form-string html='<h1>Invoice ready</h1><p>Hi John, your invoice is attached.</p>' \
  -F attachment=@files/invoice.pdf \
  -F bulkId='customBulkId' \
  -F intermediateReport='true' \
  -F notifyUrl='https://www.example.com/email/dlr' \
  -F notifyContentType='application/json' \
  -F callbackData='order-58213'
<?php
$ch = curl_init('https://e.api.itwalk.in/email/1/send');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_USERPWD => 'USERNAME:PASSWORD',
    CURLOPT_POSTFIELDS => [
        'from' => 'Jane Smith <jane.smith@yourdomain.com>',
        'to' => 'john.smith@example.com',
        'subject' => 'Your invoice is ready',
        'html' => '<h1>Invoice ready</h1><p>Hi John, your invoice is attached.</p>',
        'attachment' => new CURLFile('files/invoice.pdf'),
        'notifyUrl' => 'https://www.example.com/email/dlr',
    ],
    CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));
import requests

data = {
    "from": "Jane Smith <jane.smith@yourdomain.com>",
    "to": "john.smith@example.com",
    "subject": "Your invoice is ready",
    "html": "<h1>Invoice ready</h1><p>Hi John, your invoice is attached.</p>",
    "notifyUrl": "https://www.example.com/email/dlr",
}
files = [("attachment", open("files/invoice.pdf", "rb"))]
r = requests.post("https://e.api.itwalk.in/email/1/send", auth=("USERNAME", "PASSWORD"),
                  data=data, files=files, timeout=60)
print(r.status_code, r.json())
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("from", "Jane Smith <jane.smith@yourdomain.com>");
form.append("to", "john.smith@example.com");
form.append("subject", "Your invoice is ready");
form.append("html", "<h1>Invoice ready</h1><p>Hi John, your invoice is attached.</p>");
form.append("attachment", new Blob([await readFile("files/invoice.pdf")]), "invoice.pdf");

const res = await fetch("https://e.api.itwalk.in/email/1/send", {
  method: "POST",
  headers: { Authorization: "App YOUR_API_KEY" },
  body: form
});
console.log(res.status, await res.json());
using System.Net.Http;
using System.Net.Http.Headers;

using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("App", "YOUR_API_KEY");
var form = new MultipartFormDataContent {
    { new StringContent("Jane Smith <jane.smith@yourdomain.com>"), "from" },
    { new StringContent("john.smith@example.com"), "to" },
    { new StringContent("Your invoice is ready"), "subject" },
    { new StringContent("<h1>Invoice ready</h1>"), "html" },
    { new ByteArrayContent(File.ReadAllBytes("files/invoice.pdf")), "attachment", "invoice.pdf" }
};
var res = await http.PostAsync("https://e.api.itwalk.in/email/1/send", form);
Console.WriteLine(await res.Content.ReadAsStringAsync());

Response

{
  "bulkId": "customBulkId",
  "messages": [
    {
      "to": "john.smith@example.com",
      "messageCount": 1,
      "messageId": "c268350e-c85e-41d1-b5a0-a60771b134bd",
      "status": {
        "groupId": 1,
        "groupName": "PENDING",
        "id": 7,
        "name": "PENDING_ENROUTE",
        "description": "Message sent to next instance"
      }
    }
  ]
}
FieldTypeDescription
bulkIdstringYour bulkId or an auto-generated one.
messagesarrayOne object per recipient with messageId and status.

Email authentication

MethodHow to send it
Username and passwordHTTP Basic auth, e.g. curl --user USERNAME:PASSWORD
API keyHeader Authorization: App YOUR_API_KEY. Set an expiry on keys and rotate them when they expire.
SMTPUsername and password over port 587 with STARTTLS (see SMTP relay).
Send only from a domain verified with SPF and DKIM, and publish a DMARC record. Unverified domains fail with EC 6036, 6047 or 6048.

Multiple recipients, cc/bcc and attachments

Repeat to, cc, bcc or attachment fields to add more.

curl -s --user USERNAME:PASSWORD \
  https://e.api.itwalk.in/email/1/send \
  -F from='Jane Smith <jane.smith@yourdomain.com>' \
  -F to='john.smith@example.com' \
  -F to='tom.smith@example.com' \
  -F cc='juliet.smith@example.com' \
  -F bcc='audit@yourdomain.com' \
  -F subject='Team update' \
  -F text='Hello team' \
  -F attachment=@files/report.pdf \
  -F attachment=@files/chart.png
  • If every address in to is rejected, the whole request is rejected.
  • Placeholders are not supported when cc or bcc is used.
  • Open and click tracking is not available for cc/bcc recipients.
  • Avoid repeating the same address across to, cc and bcc.

Custom message IDs and dynamic content

Pass a JSON object in to to set your own messageId per recipient, or placeholders for handlebars-style personalisation in the HTML.

Custom messageId

curl -X POST https://e.api.itwalk.in/email/1/send \
  -H 'Authorization: App YOUR_API_KEY' \
  -F 'from=Jane Smith <jane.smith@yourdomain.com>' \
  -F 'to={"to": "tom.smith@example.com", "messageId": "1234abcd5678defj"}' \
  -F 'to={"to": "henry.smith@example.com", "messageId": "zxcv0987qwer5436"}' \
  -F 'subject=Your account update' \
  -F 'text=Hello from SMSGatewayHub' 

Dynamic content

curl -X POST https://e.api.itwalk.in/email/1/send \
  -H 'Authorization: App YOUR_API_KEY' \
  -F 'from=Jane Smith <jane.smith@yourdomain.com>' \
  -F 'to={"to": "john.smith@example.com", "placeholders": {"name": "John"}}' \
  -F 'subject=Welcome aboard' \
  -F 'html=<html>{{#eq name "John"}}Dear {{name}}{{else}}Hi {{name}}{{/eq}}</html>' 

Open and click tracking webhooks

When trackingUrl is set, your server receives a POST for every open and click.

Open notification

{
  "notificationType": "OPENED",
  "domain": "yourdomain.com",
  "recipient": "john.smith@example.com",
  "sendDateTime": 1517652288663,
  "messageId": "zl3cf7frmy48ueavnnxy",
  "callbackData": "Email open and click callback data",
  "bulkId": "8pok2duu132mojj587zc",
  "recipientInfo": { "deviceType": "Desktop", "os": "Windows", "deviceName": "PC" }
}

Click notification

{
  "notificationType": "CLICKED",
  "domain": "yourdomain.com",
  "recipient": "jane.smith@example.com",
  "url": "https://www.example.com/landingpage.html",
  "sendDateTime": 1517652288646,
  "messageId": "zsf6q5vjgn1y6qqn65g7",
  "callbackData": "Email open and click callback data",
  "bulkId": "8pok2duu132mojj587zc",
  "recipientInfo": { "deviceType": "Desktop", "os": "Windows", "deviceName": "PC" }
}

SMTP relay settings

SettingValue
Serversmtp-api.itwalk.in
Port587
SecuritySTARTTLS (TLS)
AuthenticationAUTH LOGIN or AUTH PLAIN
UsernameYour SMTP username from the panel
PasswordYour SMTP password from the panel
Max message size25 MB (26214400 bytes, as advertised by the server)

Sample SMTP session

Connected to smtp://smtp-api.itwalk.in:587/?starttls=always
<< 220 smtp.email-messaging.com ESMTP
>> EHLO client.example.com
<< 250-SIZE 26214400
<< 250-STARTTLS
<< 250-AUTH LOGIN PLAIN
<< 250 OK
>> STARTTLS
<< 220 2.0.0 Ready to start TLS
>> AUTH PLAIN ************
<< 235 2.7.0 Authentication successful
>> MAIL FROM:<info@yourdomain.com>
<< 250 2.1.0 Sender <info@yourdomain.com> OK
>> RCPT TO:<customer@example.com>
<< 250 2.1.5 Recipient <customer@example.com> OK
>> DATA
<< 354 End data with <CR><LF>.<CR><LF>
>> (headers and MIME body)
>> .
<< 250 2.6.0 Message queued as <3e8htit1oaqiieac2u1g>

The Message queued as ID identifies the message in delivery reports downloaded from the panel. For campaigns and pricing see bulk email and bulk email pricing.

Email status and error codes (EC)

Permanent = Yes means do not retry without fixing the cause. No means a temporary condition that may clear on retry.

Content, sending and account errors

CodePermanentNameMeaning and fix
6002YesEC_SPAM_DETECTEDContent detected as possible spam. Review content before retrying.
6003YesEC_UNSUBSCRIBED_EMAIL_ADDRESSRecipient opted out from this sender.
6016YesEC_SENDER_DOMAIN_BOUNCE_BLOCKEDDomain blocked for high bounce rate; auto-unblocks after 24 hours. Clean your list.
6018YesEC_REQUEST_INVALIDRequest is invalid. Check parameters and format.
6020YesEC_EMAIL_TEMPLATE_NOT_FOUNDTemplate not found. Check templateId.
6021YesEC_EMAIL_PLACEHOLDERS_ERRORPlaceholder error. Check names and syntax.
6023YesEC_BLOCKED_SUSPICIOUS_ACTIVITYDomain blocked for suspicious activity. Contact support.
6024YesEC_EMAIL_TOO_MANY_URLSMore than 150 tracked URLs. Reduce URLs or disable tracking.
6025YesEC_EMAIL_INVALID_TRACKING_PARAMSInvalid tracking parameters.
6026YesEC_EMAIL_LANDING_PAGE_PLACEHOLDERS_SIZE_EXCEEDEDLanding page placeholders exceed 256 characters.
6027YesEC_EMAIL_INVALID_HEADERSInvalid or badly formatted headers.
6029YesEC_SENDER_ADDRESS_INVALIDSender invalid or unauthorised. Verify the sender domain.
6030YesEC_EMAIL_INVALID_LANDING_PAGELanding page invalid or unreachable.
6031YesEC_INVALID_PRESERVED_CC_OR_BCC_RECIPIENTInvalid preserved cc/bcc recipient or limit reached.
6033YesEC_INVALID_CC_BCC_EMAIL_ADDRESSInvalid cc/bcc address format.
6034YesEC_SUPPRESSED_BOUNCEAddress suppressed after an earlier bounce (also used for spam complaints).
6035YesEC_SUPPRESSED_SPAM_COMPLAINTAddress suppressed after a spam complaint (reserved).
6036YesEC_SENDER_DOMAIN_UNVERIFIEDRequired DNS records (SPF/DKIM) missing. Verify the domain.
6038YesEC_EMAIL_CONTENT_EXPIREDTemplate content expired from inactivity. Re-upload.
6039YesEC_EMAIL_TEMPLATE_LANGUAGE_ERRORTemplate language error.
6040YesEC_EMAIL_TEMPLATE_EXPIREDTemplate validity expired. Update or copy the template.
6041YesEC_EMAIL_TEMPLATE_NOT_SAVEDTemplate not saved in the web interface.
6050NoEC_SENDER_WARMUPSender domain reached today's warm-up limit.
6051NoEC_WARMUPSender reached today's warm-up limit.
6052YesEC_RECIPIENT_DOMAIN_TYPORecipient domain blocked (likely a typo).
6053NoEC_ACCESS_DENIED_BY_MAILBOX_PROVIDERMailbox provider denied access for the sender.
6054YesEC_SINGLE_SENDER_NOT_VERIFIEDSingle sender address not verified.
6055YesEC_SINGLE_SENDER_TRAFFIC_EXCEEDED100-email single-sender limit reached. Add and verify your domain.
6056NoEC_NO_IP_POOL_ASSIGNEDSending domain has no IP pool assigned.
6057NoEC_SAFETY_RATE_LIMITRate limited to protect reputation. Slow traffic to that provider.
6058NoEC_MAILBOX_PROVIDER_RATE_LIMITRate limited by the mailbox provider.

Recipient and mailbox provider errors

CodePermanentNameMeaning and fix
6006YesEC_INVALID_EMAIL_ADDRESSAddress invalid, inactive or disabled.
6007NoEC_MAILBOX_TEMPORARY_UNAVAILABLEMailbox temporarily unavailable. Retry in a few hours.
6009YesEC_MAILBOX_PERMANENTLY_UNAVAILABLERecipient domain may be permanently unavailable.
6010NoEC_RECIPIENT_INBOX_FULLRecipient mailbox is full.
6011NoEC_SOFT_BOUNCETemporary delivery error. Retry.
6012YesEC_HARD_BOUNCEPermanent delivery error.
6017NoEC_SENDER_IP_BLACKLISTEDSending IP is blocklisted. Request de-listing.
6037YesEC_RECIPIENT_DOMAIN_MX_NOT_FOUNDRecipient domain has no MX record.
6042YesEC_SPAM_REVERTEDMailbox provider flagged content as spam.
6043YesEC_SUSPICIOUS_CONTENTDenied for suspicious content.
6044YesEC_SUSPICIOUS_SENDERDenied for low domain/IP reputation.
6045YesEC_RECIPIENT_DOMAIN_POLICY_ERRORBlocked by the recipient organisation's policy.
6046NoEC_UNSOLICITED_RECIPIENTMessage likely unsolicited. Confirm opt-in.
6047YesEC_DOMAIN_CONFIGURATION_ERRORMissing or invalid DKIM/SPF record.
6048YesEC_DMARC_POLICY_ISSUEDMARC policy rejected by the recipient provider.
6049YesEC_SENDER_DOMAIN_BLACKLISTEDSender domain blocklisted by the recipient mailbox.

System errors

CodePermanentNameMeaning and fix
6013NoEC_INTERNAL_SYSTEM_ERRORTemporary platform error. Retry; contact support if it repeats.
More

Missed call webhookWEBHOOK

GEThttps://yourdomain.com/handler.php?who=%who&ChannelID=%channel&Circle=%circle&Operator=%operator&DateTime=%time

When someone gives a missed call to your toll-free or DID number, SMSGatewayHub calls your URL with these placeholders replaced.

PlaceholderValue
%whoCaller's phone number
%channelYour toll-free or DID number that received the call
%circleTelecom circle of the caller
%operatorCaller's operator (Jio, Airtel, Vi, BSNL)
%timeDate and time of the call
Respond quickly with plain text or JSON (no HTML). See missed call services and toll-free numbers.

URL-encoding special characters

Encode the text parameter with rawurlencode() (PHP), encodeURIComponent() (JavaScript) or urllib.parse.quote (Python).

CharacterEncoded
space%20
!%21
#%23
$%24
%%25
&%26
'%27
+%2B
/%2F
?%3F

Frequently asked questions

Create a free account, log in to the panel and open API Settings to copy your APIKey. Keep it on your server only and restrict it to your server IPs from the panel.

Indian operators scrub every commercial SMS against DLT. The SendSMS request must carry your DLT Principal Entity ID and the content template ID, and the text must match that template, or operators reject the message. International SMS (channel=INT) does not need them.

Call the same SendSMS endpoint with channel=OTP and a DLT-approved OTP template. OTP traffic is routed on priority transactional routes that also reach DND numbers.

Send a POST request to https://sparklebot.in/api/v1/{tenant_subdomain}/messages/template with your API token as a Bearer token, the approved template name and language, body variables as field_1, field_2 and an optional image, document, video or text header.

Use POST https://www.smsgatewayhub.com/api/v1/Rcs/sendmessage with your API key in the Authorization header, the botid of an active RCS agent, an approved templatename and the destination numbers. Add a var object for personalised templates.

Yes. Connect to smtp-api.itwalk.in on port 587 with STARTTLS using your SMTP username and password from the panel. Use the Email API instead when you need attachments, cc/bcc, placeholders, scheduling or open and click tracking webhooks.

Standard accounts support up to 200 requests per second with 100 to 500 ms response time. A high-availability cluster supports up to 2000 TPS for high-volume senders; contact support to enable it.

The message text does not match the approved DLT template, or the dlttemplateid is wrong. Check spaces, punctuation and variables against the template. The DLT error codes guide lists operator-level failures and fixes.

Promotional SMS (channel=1) is delivered only between 10 AM and 9 PM and only to numbers that have not blocked promotional messages or have given consent. Transactional, service and OTP messages are delivered 24x7, including to DND numbers.

Signing up, getting an API key and using the Swagger reference are free. Messages are billed on Pay As You Go pricing, and SMS is billed only when delivered.

Get your API key and send in minutes

Free signup, free Swagger reference and Pay As You Go credits. SMS is billed only when delivered.