Noxitel API Reference

Complete REST API reference for SMS, WhatsApp, RCS, Voice, and OTP. All requests return JSON.

Get API Keys → Contact Support
Noxitel API v2 hub connecting to SMS, WhatsApp, RCS, Voice, and OTP channels Animated API constellation diagram /api/v2 Noxitel 5 channels SMS WhatsApp RCS Voice OTP POST /api/v2/sms 200 OK • 12ms GET /api/v2/dlr { "status": "delivered" } 8B+ MSGS · 99.98% UPTIME · 190+ COUNTRIES · 600+ CARRIERS

Overview

The Noxitel REST API lets you send messages across SMS, WhatsApp Business, RCS, Voice, and OTP from any platform or programming language. All API calls use JSON request/response bodies over HTTPS.

💡 Quick start: Grab your API key from the dashboard, replace YOUR_API_TOKEN in any example below, and you're sending within minutes.

Supported channels

  • SMS — High-volume A2P messaging with DLR and personalization variables
  • WhatsApp Business — Template and free-form messages via official BSP access
  • RCS — Rich cards, carousels, suggestion chips, and media messages
  • Voice — Outbound calls with TTS, pre-recorded audio, and IVR flows
  • OTP — Managed one-time password send + verify in two API calls

Authentication

All requests must include your API key as a Bearer token in the Authorization header.

HTTP Header
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
🔒 Never expose your API key in client-side or public code. Store it as an environment variable. You can regenerate your key at any time from the dashboard.

Base URL

All endpoints below are relative to:

Base URL
https://dashboard.noxitel.com/api/v2

Quick endpoint map

ChannelPath prefix
SMS/sms  /dlr  /credits
WhatsApp/whatsapp/message  /whatsapp/report  /whatsapp/checkwindow  /whatsapp/prices
RCS/rcs/message  /rcs/agent  /rcs/capability  /rcs/dlr  …
Voice/voice/call
OTP/otp  /otp/verify

Error Codes

Errors return a JSON object. The message field is always human-readable and actionable.

Error Response
{
  "success": false,
  "status": 403,
  "message": "API Key Missing"
}
HTTPMeaning
400Bad request / missing parameter
401IP not whitelisted
403Invalid or missing API key
402Insufficient credits / balance
404Resource not found
429Rate limit exceeded
500Server error — contact support

Send SMS

POST /sms Send one or many SMS messages
ParameterTypeRequiredDescription
senderstringRequired*Sender ID / alphanumeric tag. Mandatory for approval-based routes.
messagestringRequired*Message text. Use #varname# for personalization. Optional if templateId supplied.
contactsarrayRequired*Array of contact objects [{mobile, parameters?}]. Required unless contactGroup supplied.
campaignIdintegerOptionalCampaign ID from dashboard. Uses default if omitted.
routeIdintegerOptionalRoute ID. Uses default if omitted.
modestringOptionaltext, flash, or unicode. Defaults to text. Auto-converts to unicode if detected.
templateIdintegerOptionalSaved template ID. Replaces message.
contactGroupintegerOptionalContact group ID. Replaces contacts array.
schedulestringOptionalScheduled send time: YYYY-MM-DD HH:MM:SS (system timezone).
notifyUrlstringOptionalWebhook URL for delivery receipts.
dlt_entity_idstringOptionalDLT entity ID (required for India A2P traffic).
dlt_template_idstringOptionalDLT template ID (required for India A2P traffic).

Contacts array formats

Basic
[
  { "mobile": "919887111111" },
  { "mobile": "918058222222" }
]
With Variables
// message: "Hi #name#, OTP: #otp#"
[
  {
    "mobile": "919887111111",
    "parameters": {
      "name": "Sam",
      "otp": "847291"
    }
  }
]

Code examples

cURL
curl -X POST https://dashboard.noxitel.com/api/v2/sms \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"campaignId": 1,
"routeId": 1,
"sender": "NOXITEL",
"mode": "text",
"message": "Hi #name#, your OTP is #otp#",
"contacts": [
{ "mobile": "919887111111", "parameters": { "name": "Sam", "otp": "847291" } }
],
"notifyUrl": "https://yourapp.com/webhook/sms",
"dlt_entity_id": "1234567890",
"dlt_template_id": "1234567890"
}'
Node.js
const fetch = require('node-fetch');

const data = {
  campaignId: 1, routeId: 1,
  sender: "NOXITEL",
  mode: "text",
  message: "Hi #name#, your OTP is #otp#",
  contacts: [
    { mobile: "919887111111", parameters: { name: "Sam", otp: "847291" } }
  ],
  notifyUrl: "https://yourapp.com/webhook/sms"
};

const res = await fetch('https://dashboard.noxitel.com/api/v2/sms', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
});
const json = await res.json();
console.log(json);
PHP
<?php
$data = [
  "campaignId" => 1, "routeId" => 1,
  "sender" => "NOXITEL",
  "mode" => "text",
  "message" => "Hi #name#, your OTP is #otp#",
  "contacts" => [[
    "mobile" => "919887111111",
    "parameters" => ["name" => "Sam", "otp" => "847291"]
  ]]
];
$ch = curl_init();
curl_setopt_array($ch, [
  CURLOPT_URL => "https://dashboard.noxitel.com/api/v2/sms",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($data),
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer YOUR_API_TOKEN",
    "Content-Type: application/json"
  ]
]);
echo curl_exec($ch); curl_close($ch);
Python
import requests

data = {
  "campaignId": 1, "routeId": 1,
  "sender": "NOXITEL",
  "mode": "text",
  "message": "Hi #name#, your OTP is #otp#",
  "contacts": [
    {"mobile": "919887111111", "parameters": {"name": "Sam", "otp": "847291"}}
  ]
}
headers = {
  "Authorization": "Bearer YOUR_API_TOKEN",
  "Content-Type": "application/json"
}
r = requests.post("https://dashboard.noxitel.com/api/v2/sms",
                 json=data, headers=headers)
print(r.json())
Go
package main

import (
  "bytes"; "encoding/json"
  "fmt"; "net/http"
)

func main() {
  data, _ := json.Marshal(map[string]interface{}{
    "sender": "NOXITEL", "mode": "text",
    "message": "Hi #name#, your OTP is #otp#",
    "contacts": []map[string]interface{}{
      {"mobile": "919887111111",
       "parameters": map[string]string{"otp": "847291"}},
    },
  })
  req, _ := http.NewRequest("POST",
    "https://dashboard.noxitel.com/api/v2/sms",
    bytes.NewBuffer(data))
  req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
  req.Header.Set("Content-Type", "application/json")
  resp, _ := (&http.Client{}).Do(req)
  fmt.Println(resp.Status)
}

Response

Success
{
  "status": "success",
  "message": "SMS Submitted successfully",
  "batch_id": "samsms_eink1rilz6ucphk",
  "total_contacts": 1,
  "message_id": [
    {
      "mobile": "919887111111",
      "sms_id": "1ef4d949-7639-6880-bf73-ae794..."
    }
  ]
}
Error
{
  "success": false,
  "status": 403,
  "message": "API Key Missing"
}

SMS Delivery Reports

GET /dlr Fetch delivery status for a message or batch
ParameterTypeRequiredDescription
batch_idstringRequired*The batch_id from the send response. Use to fetch DLR for all contacts in a campaign. Required if sms_id not supplied.
sms_idstringRequired*The per-contact sms_id from the send response. Use for a single message DLR. Required if batch_id not supplied.
cURL — by batch
curl -X GET https://dashboard.noxitel.com/api/v2/dlr \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"batch_id": "samsms_eink1rilz6ucphk"}'

# or by single message id:
curl -X GET https://dashboard.noxitel.com/api/v2/dlr \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sms_id": "1ef4d949-7639-6880-bf73-ae794..."}'
Node.js
const res = await fetch('https://dashboard.noxitel.com/api/v2/dlr', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ sms_id: "1ef4d949-7639-6880-bf73-ae794..." })
});
console.log(await res.json());
Python
import requests
r = requests.get(
  "https://dashboard.noxitel.com/api/v2/dlr",
  headers={"Authorization": "Bearer YOUR_API_TOKEN"},
  json={"sms_id": "1ef4d949-7639-6880-bf73-ae794..."}
)
print(r.json())

Success response

JSON
{
  "status": "success",
  "data": [
    {
      "sms_shoot_id": "user_6q0za64m0ql0vu7",
      "mobile": 918058111111,
      "sender_id": "NOXITEL",
      "sent": "2026-05-01 10:05:30",
      "dlr": {
        "status": "Handset Delivered",
        "operator_reply": "DELIVRD",
        "delivery_time": "2026-05-01 10:05:42"
      }
    }
  ]
}

Credit Balance

GET /credits Retrieve account wallet and credit balance

No request body parameters required. Pass only the Authorization header.

cURL
curl -X GET https://dashboard.noxitel.com/api/v2/credits \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Node.js
const res = await fetch('https://dashboard.noxitel.com/api/v2/credits', {
  method: 'GET',
  headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' }
});
console.log(await res.json());
Python
import requests
r = requests.get(
  "https://dashboard.noxitel.com/api/v2/credits",
  headers={"Authorization": "Bearer YOUR_API_TOKEN"}
)
print(r.json())
Success Response
{
  "status": "success",
  "billing_mode": "credits",
  "wallet": { "amount": "120.00", "currency": "USD" },
  "credits": [
    { "route": "Standard", "credits": 3946684 }
  ]
}

Send WhatsApp Message

⚠️ Your WhatsApp Business Account must be active. Contact Noxitel to begin BSP onboarding before using this endpoint.
POST /whatsapp/message
ParameterTypeRequiredDescription
phoneIdstringOptionalWhatsApp phone ID to send from. Uses default if omitted.
typestringOptionaltext | image | video | audio | document | reaction | reply | location | template. Defaults to text.
messagestringRequired*Free-form message text. Required when type is text.
mediaobjectRequired*{url, caption?} — required when type is image/video/audio/document.
locationobjectRequired*{latitude, longitude, name, address} — required when type is location.
replyToMessageIdstringRequired*Message ID to reply to or react to. Required for types reply and reaction.
templateIdstringRequired*Template ID. Required when type is template.
contactsarrayRequired*Array of {msisdn, parameters?} objects. For templates, parameters includes header, body, and buttons arrays.

Template parameters format

contacts for template messages
[
  {
    "msisdn": "919887111111",
    "parameters": {
      "header": [{ "type": "text", "value": "Welcome!" }],
      "body": ["Sam", "Special Offer"],
      "buttons": [{ "index": 0, "url": "https://example.com/offer" }]
    }
  }
]
cURL — template message
curl -X POST https://dashboard.noxitel.com/api/v2/whatsapp/message \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phoneId": "1234567890",
"type": "template",
"templateId": "welcome_template",
"contacts": [
{
"msisdn": "919887111111",
"parameters": {
"header": [{"type":"text","value":"Hello!"}],
"body": ["Sam", "Special Offer"],
"buttons": [{"index":0,"url":"https://brand.com/offer"}]
}
}
]
}'
Node.js
const res = await fetch('https://dashboard.noxitel.com/api/v2/whatsapp/message', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    phoneId: "1234567890",
    type: "text",
    message: "Hello! Your order has been shipped.",
    contacts: [{ msisdn: "919887111111" }]
  })
});
console.log(await res.json());
PHP
<?php
$ch = curl_init();
$data = [
  "type" => "text",
  "message" => "Hello! Your order has been shipped.",
  "contacts" => [["msisdn" => "919887111111"]]
];
curl_setopt_array($ch, [
  CURLOPT_URL => "https://dashboard.noxitel.com/api/v2/whatsapp/message",
  CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($data),
  CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_TOKEN", "Content-Type: application/json"]
]);
echo curl_exec($ch); curl_close($ch);
Python
import requests
r = requests.post(
  "https://dashboard.noxitel.com/api/v2/whatsapp/message",
  headers={"Authorization": "Bearer YOUR_API_TOKEN"},
  json={"type": "text", "message": "Hello!",
      "contacts": [{"msisdn": "919887111111"}]}
)
print(r.json())
Success
{
  "status": "success",
  "message": "Messages Sent Successfully",
  "total_cost": 0.05,
  "total_contacts": 1,
  "message_id": [
    { "msisdn": "919887111111", "msg_id": "msg_abc123" }
  ]
}
Error
{
  "status": "error",
  "message": "You don't have enough credits to send this campaign."
}

WhatsApp Message Reports

GET /whatsapp/report
ParameterTypeRequiredDescription
modestringRequiredmessage — single message report, or campaign — all messages in a campaign.
idstringRequiredA msg_id when mode is message, or a campaign ID when mode is campaign.
cURL
# Single message
curl -X GET "https://dashboard.noxitel.com/api/v2/whatsapp/report?mode=message&id=MSG_ID" \
-H "Authorization: Bearer YOUR_API_TOKEN"

# Full campaign
curl -X GET "https://dashboard.noxitel.com/api/v2/whatsapp/report?mode=campaign&id=CAMPAIGN_ID" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Node.js
const res = await fetch(
  'https://dashboard.noxitel.com/api/v2/whatsapp/report?mode=message&id=MSG_ID',
  { headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' } }
);
console.log(await res.json());
Python
r = requests.get(
  "https://dashboard.noxitel.com/api/v2/whatsapp/report",
  headers={"Authorization": "Bearer YOUR_API_TOKEN"},
  params={"mode": "message", "id": "MSG_ID"}
)
print(r.json())
Success Response (mode: message)
{
  "msg_id": "1f020deb-2669-6060-b900-1fc1c519d2b7",
  "msisdn": "919887111111",
  "phone_id": "12345678909812",
  "direction": "outgoing",
  "timestamp": "2026-05-01T07:35:29.000Z",
  "cost": 0.05,
  "status": "delivered"
}

Check Service Window

Check whether a 24-hour customer service window is currently open for a recipient (i.e., they messaged you within the last 24 hours).

GET /whatsapp/checkwindow
ParameterTypeRequiredDescription
phoneIdstringRequiredYour WhatsApp phone ID.
msisdnstringRequiredThe recipient's mobile number.
cURL
curl -X GET "https://dashboard.noxitel.com/api/v2/whatsapp/checkwindow?phoneId=1234567890&msisdn=919887111111" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Window Open
{ "status": "success", "window_open": true, "expires_at": "2026-05-02T10:00:00Z" }
Window Closed
{ "status": "success", "window_open": false }

WhatsApp Prices

Retrieve per-country per-category pricing for WhatsApp Business conversations.

GET /whatsapp/prices No parameters required
cURL
curl -X GET https://dashboard.noxitel.com/api/v2/whatsapp/prices \
-H "Authorization: Bearer YOUR_API_TOKEN"
Success Response
[
  {
    "country": "India", "zone": "Zone 2", "prefix": "+91",
    "price": {
      "marketing": 0.0492,
      "utility": 0.0147,
      "authentication": 0.0147,
      "authenticationInt": 0.0147,
      "service": 0
    }
  }
]
⚠️ WhatsApp conversation pricing is set by Meta and changes periodically. Always cross-check against Meta's official rate card.

Send RCS Message

POST /rcs/message
ParameterTypeRequiredDescription
typestringRequiredtext | media | rich_card | carousel | template
contentobjectRequired*Message content — shape depends on type. Optional if templateId supplied.
contactsarrayRequired*[{mobile, parameters?}]. Optional if contactGroup supplied.
agentIdintegerOptionalRCS agent ID. Uses default if omitted.
templateIdintegerOptionalSaved RCS template ID.
contactGroupintegerOptionalContact group ID — replaces contacts.
schedulestringOptionalYYYY-MM-DD HH:MM:SS (system timezone).
notifyUrlstringOptionalWebhook for delivery receipts and inbound events.
smsFallbackobjectOptional{enabled, routeId, sender, message} — SMS fallback if device doesn't support RCS.
trafficTypestringOptionalTRANSACTION | PROMOTION | AUTHENTICATION

Content shapes by type

type: text — with suggestions
{
  "text": "Hi #name#, your OTP is #otp#",
  "suggestions": [
    { "type": "reply", "text": "Confirm" },
    { "type": "url", "text": "Open", "url": "https://example.com" },
    { "type": "dial", "text": "Call us", "phone": "+919887000000" }
  ]
}
type: rich_card
{
  "orientation": "VERTICAL",
  "card": {
    "title": "Flash Sale 40% Off",
    "description": "Use FLASH40 at checkout.",
    "media": { "url": "https://cdn.example.com/sale.jpg", "height": "MEDIUM" },
    "suggestions": [{ "type": "url", "text": "Shop Now", "url": "https://brand.com/sale" }]
  }
}
type: carousel
{
  "cardWidth": "MEDIUM",
  "cards": [
    { "title": "Basic", "media": { "url": "..." }, "suggestions": [] },
    { "title": "Pro", "media": { "url": "..." }, "suggestions": [] }
  ]
}
cURL
curl -X POST https://dashboard.noxitel.com/api/v2/rcs/message \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agentId": 3,
"type": "text",
"content": {
"text": "Hi #name#, your OTP is #otp#",
"suggestions": [
{ "type": "reply", "text": "Confirm" },
{ "type": "url", "text": "Learn more", "url": "https://example.com" }
]
},
"contacts": [
{ "mobile": "919887111111", "parameters": { "name": "Sam", "otp": "1234" } }
],
"notifyUrl": "https://yourapp.com/webhook/rcs",
"trafficType": "TRANSACTION"
}'
Node.js
const res = await fetch('https://dashboard.noxitel.com/api/v2/rcs/message', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    agentId: 3, type: "text",
    content: {
      text: "Hi #name#, your OTP is #otp#",
      suggestions: [{ type: "reply", text: "Confirm" }]
    },
    contacts: [{ mobile: "919887111111", parameters: { name: "Sam", otp: "1234" } }],
    trafficType: "TRANSACTION"
  })
});
console.log(await res.json());
PHP
<?php
$data = [
  "agentId" => 3, "type" => "text",
  "content" => ["text" => "Hi #name#, OTP: #otp#", "suggestions" => []],
  "contacts" => [["mobile" => "919887111111", "parameters" => ["otp" => "1234"]]]
];
$ch = curl_init();
curl_setopt_array($ch, [
  CURLOPT_URL => "https://dashboard.noxitel.com/api/v2/rcs/message",
  CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($data),
  CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_TOKEN", "Content-Type: application/json"]
]);
echo curl_exec($ch); curl_close($ch);
Python
r = requests.post(
  "https://dashboard.noxitel.com/api/v2/rcs/message",
  headers={"Authorization": "Bearer YOUR_API_TOKEN"},
  json={"agentId": 3, "type": "text",
      "content": {"text": "Hi Sam, your OTP is 1234", "suggestions": []},
      "contacts": [{"mobile": "919887111111"}]}
)
print(r.json())
Success Response
{
  "status": "success",
  "message": "RCS submitted successfully",
  "batch_id": "rcs_k8a9s2lmnp4xvqr",
  "total_contacts": 1,
  "message_id": [
    { "mobile": "919887111111", "msg_id": "1f134cd4-e08d-6de0-87b5-aefe80a0acca" }
  ]
}

RCS Agent Management

Create and manage RCS Business Messaging agents. An agent must be approved and launched to a carrier before it can send live messages.

Endpoints

MethodPathPurpose
POST/rcs/agentCreate or update a draft agent
POST/rcs/agent/submitSubmit draft for admin review
GET/rcs/agent/{id}Fetch single agent details
GET/rcs/agentsList all owned agents
POST/rcs/agent/launchRequest launch to carriers

Create / Update Agent — request body

POST/rcs/agent
ParameterTypeRequiredDescription
agentNamestringRequiredUnique internal identifier — no spaces.
displayNamestringRequiredName shown to end users.
brandNamestringRequiredBrand this agent represents.
descriptionstringOptionalShort agent description.
logoUrlstringOptionalPublicly accessible brand logo URL.
colorstringOptionalBrand hex color e.g. #00a896.
phone / email / websitestringOptionalSupport contact details.
privacyUrl / termsUrlstringOptionalLegal page URLs.
hostingRegionstringOptionalASIA_PACIFIC | EUROPE | NORTH_AMERICA
agentUseCasestringOptionalMULTI_USE | TRANSACTIONAL | PROMOTIONAL
cURL — create, submit, launch
# Create agent
curl -X POST https://dashboard.noxitel.com/api/v2/rcs/agent \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"agentName":"support_bot","displayName":"Noxitel Support","brandName":"Noxitel"}'

# Submit for review
curl -X POST https://dashboard.noxitel.com/api/v2/rcs/agent/submit \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"agentId": 42}'

# Launch to carriers
curl -X POST https://dashboard.noxitel.com/api/v2/rcs/agent/launch \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"agentId":42,"carriers":["airtel-india","reliance-jio-india"]}'
Node.js
const base = 'https://dashboard.noxitel.com/api/v2/rcs';
const h = { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' };

// Create agent
await fetch(`${base}/agent`, { method: 'POST', headers: h,
  body: JSON.stringify({ agentName: 'support_bot', displayName: 'Noxitel Support', brandName: 'Noxitel' }) });

// Submit for review
await fetch(`${base}/agent/submit`, { method: 'POST', headers: h, body: JSON.stringify({ agentId: 42 }) });

// List all agents
const list = await fetch(`${base}/agents`, { headers: h });
console.log(await list.json());
Python
BASE = "https://dashboard.noxitel.com/api/v2/rcs"
H = {"Authorization": "Bearer YOUR_API_TOKEN"}

# Create agent
requests.post(BASE+"/agent", json={"agentName":"support_bot","displayName":"Noxitel Support","brandName":"Noxitel"}, headers=H)

# Submit for review
requests.post(BASE+"/agent/submit", json={"agentId": 42}, headers=H)

# List all agents
print(requests.get(BASE+"/agents", headers=H).json())

RCS Test Devices

Add or remove test phone numbers for an agent before it goes live. Test messages are free and do not count against quotas.

MethodPathPurpose
POST/rcs/testdeviceAdd a test device
GET/rcs/testdevices?agentId=XList test devices for agent
DELETE/rcs/testdeviceRemove a test device
Both POST and DELETE accept {"agentId": 42, "phoneNumber": "+919887979736"} as the request body.
cURL — all three operations
# Add device
curl -X POST https://dashboard.noxitel.com/api/v2/rcs/testdevice \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"agentId":42,"phoneNumber":"+919887979736"}'

# List devices
curl -X GET "https://dashboard.noxitel.com/api/v2/rcs/testdevices?agentId=42" \
-H "Authorization: Bearer YOUR_API_TOKEN"

# Remove device
curl -X DELETE https://dashboard.noxitel.com/api/v2/rcs/testdevice \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"agentId":42,"phoneNumber":"+919887979736"}'

RCS Capability Check

Check whether a phone number supports RCS and which message features it supports. Results are cached for 24 hours.

GET /rcs/capability
Query ParameterTypeRequiredDescription
mobilestringRequiredPhone number in international format without +, e.g. 919887111111.
agentIdintegerRequiredAgent ID to check capability against.
cURL
curl -X GET "https://dashboard.noxitel.com/api/v2/rcs/capability?mobile=919887111111&agentId=42" \
-H "Authorization: Bearer YOUR_API_TOKEN"
RCS Enabled
{
  "status": "success",
  "mobile": "919887111111",
  "rcsEnabled": true,
  "features": [
    "RICHCARD_STANDALONE",
    "RICHCARD_CAROUSEL",
    "ACTION_OPEN_URL"
  ]
}
RCS Not Supported
{
  "status": "success",
  "mobile": "919887111111",
  "rcsEnabled": false,
  "features": []
}

RCS Conversation Window

Check whether an active P2A (Person-to-Agent) conversation window exists for a recipient. A window is open for 24 hours after the user sends you a message.

GET/rcs/conversation
Query ParameterTypeRequired
agentIdintegerRequired
mobilestringRequired
cURL
curl -X GET "https://dashboard.noxitel.com/api/v2/rcs/conversation?agentId=42&mobile=919887111111" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Active Window Response
{
  "status": "success",
  "conversationId": "1f1328bb-a73a-64e0-a812-cff28c6df66c",
  "active": true,
  "startedAt": "2026-05-01 14:11:53",
  "expiresAt": "2026-05-02 14:11:53",
  "direction": "P2A"
}

RCS Delivery Reports

GET/rcs/dlr
ParameterTypeRequiredDescription
batch_idstringRequired*batch_id from send response. Required if msg_id not supplied.
msg_idstringRequired*Individual msg_id. Required if batch_id not supplied.
cURL
# By batch
curl -X GET "https://dashboard.noxitel.com/api/v2/rcs/dlr?batch_id=rcs_k8a9s2lmnp4xvqr" \
-H "Authorization: Bearer YOUR_API_TOKEN"

# By message
curl -X GET "https://dashboard.noxitel.com/api/v2/rcs/dlr?msg_id=1f134cd4-e08d-6de0-87b5-aefe80a0acca" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Success Response
{
  "status": "success",
  "data": [
    {
      "msg_id": "1f134cd4-e08d-6de0-87b5-aefe80a0acca",
      "mobile": "919887111111",
      "agentId": 42,
      "sent": "2026-05-01 14:11:53",
      "dlr": { "status": "delivered", "delivery_time": "2026-05-01 14:12:01" }
    }
  ]
}

Possible status values: pending, sent, failed, delivered, read, incompatible.

RCS Webhook Events

When you supply a notifyUrl, the platform POSTs events to your endpoint for every status change and inbound reply. Respond with HTTP 200 to acknowledge.

Event types

eventDescription
message.sentMessage dispatched to carrier
message.deliveredDelivered to handset
message.readRecipient opened the message
message.failedDelivery failed
message.receivedInbound text or suggestion reply from user
🔔 postbackData is system-generated — do not set it when sending. When a user taps a suggestion, the platform auto-generates a structured "{msgId}||{ACTION}||{payload}" string and delivers it in the webhook.

postbackData actions

ACTIONTriggerpayload
REPLYReply chip tappedChip display text
CLICKURL action openedThe URL
DIALPhone dial tappedE.164 number
VIEW_LOCMap viewed"lat,lon"
CALENDARCalendar event createdEvent title
Suggestion Postback Payload
{
  "event": "message.received",
  "agentId": "42",
  "msgId": "1f134cd4-e08d-6de0-87b5-aefe80a0acca",
  "from": "919887111111",
  "timestamp": "2026-05-01T14:17:00Z",
  "message": { "type": "suggestion" },
  "suggestionResponse": {
    "postbackData": "1f134cd4-...||REPLY||Confirm",
    "text": "Confirm"
  }
}

// Parse: parts = postbackData.split("||") → [msgId, action, payload]

Minimal Node.js webhook receiver

Node.js / Express
const express = require('express');
const app = express();
app.use(express.json());

app.post('/rcs-webhook', (req, res) => {
  const { event, msgId, from, suggestionResponse, message } = req.body;

  if (event === 'message.received' && suggestionResponse) {
    const [id, action, payload] = suggestionResponse.postbackData.split('||');
    console.log(`Postback: action=${action}, payload=${payload}`);
  } else if (event === 'message.received') {
    console.log(`Text from ${from}: ${message?.text}`);
  } else {
    console.log(`${event}: msgId=${msgId}`);
  }

  res.sendStatus(200);
});
app.listen(3000);

Outbound Voice Call

🚧 The Voice API is coming soon. The specification below reflects the planned interface. Contact us to join the early access list.
POST/voice/call
ParameterTypeRequiredDescription
tostringRequiredDestination number in E.164 format (e.g. 919887111111).
fromstringRequiredYour Noxitel caller ID / outbound number.
ttsobjectRequired*{text, language, voice, repeat} — text-to-speech. Required if audioUrl not supplied.
audioUrlstringRequired*URL to a hosted .mp3 or .wav file to play. Required if tts not supplied.
campaignIdintegerOptionalCampaign ID for grouping calls in reports.
schedulestringOptionalScheduled time: YYYY-MM-DD HH:MM:SS.
notifyUrlstringOptionalWebhook URL for call status events (ringing, answered, completed, failed).
Node.js — TTS OTP Call
const res = await fetch('https://dashboard.noxitel.com/api/v2/voice/call', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    to: "919887111111",
    from: "YOUR_VOICE_NUMBER",
    tts: {
      text: "Your Noxitel OTP is 8 4 7 2 9 1. Do not share this with anyone.",
      language: "en-IN",
      voice: "female",
      repeat: 2
    },
    notifyUrl: "https://yourapp.com/webhook/voice"
  })
});
// Response: { callId: "call_Kx9Ab2", status: "ringing", to: "919887111111" }

Send OTP

Send a one-time password to a mobile number using a pre-configured OTP channel. The channel controls which route, sender ID, and message template are used.

POST/otp
ParameterTypeRequiredDescription
mobilestringRequiredThe mobile number to send the OTP to (include country code, e.g. 919887111111).
channelintegerRequiredOTP channel ID from the dashboard. Channels define the route, sender, and message template.
cURL
curl -X POST https://dashboard.noxitel.com/api/v2/otp \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": 27, "mobile": "919887111111"}'
Node.js
const res = await fetch('https://dashboard.noxitel.com/api/v2/otp', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' },
  body: JSON.stringify({ channel: 27, mobile: "919887111111" })
});
const { reference } = await res.json();
// Store reference — you'll need it for verification
PHP
<?php
$ch = curl_init();
curl_setopt_array($ch, [
  CURLOPT_URL => "https://dashboard.noxitel.com/api/v2/otp",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode(["channel" => 27, "mobile" => "919887111111"]),
  CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_TOKEN", "Content-Type: application/json"]
]);
$result = json_decode(curl_exec($ch), true);
$reference = $result['reference']; // save this
curl_close($ch);
Python
r = requests.post(
  "https://dashboard.noxitel.com/api/v2/otp",
  headers={"Authorization": "Bearer YOUR_API_TOKEN"},
  json={"channel": 27, "mobile": "919887111111"}
)
reference = r.json()["reference"] # store for verification
Success
{
  "status": "success",
  "reference": "036BZDUHIX"
}
Error
{
  "success": false,
  "status": 403,
  "message": "API Key Missing"
}

Verify OTP

Verify an OTP entered by the user against the reference returned from the Send OTP call.

GET/otp/verify
Query ParameterTypeRequiredDescription
referencestringRequiredThe reference value returned by the Send OTP call.
otpintegerRequiredThe one-time password entered by the user.
cURL
curl -G https://dashboard.noxitel.com/api/v2/otp/verify \
-H "Authorization: Bearer YOUR_API_TOKEN" \
--data-urlencode "reference=036BZDUHIX" \
--data-urlencode "otp=847291"
Node.js
const params = new URLSearchParams({ reference: "036BZDUHIX", otp: "847291" });
const res = await fetch(
  `https://dashboard.noxitel.com/api/v2/otp/verify?${params}`,
  { headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' } }
);
const { matched } = await res.json();
if (matched === "yes") { /* verified! */ }
PHP
<?php
$query = http_build_query(["reference" => "036BZDUHIX", "otp" => "847291"]);
$ch = curl_init("https://dashboard.noxitel.com/api/v2/otp/verify?{$query}");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_TOKEN"]
]);
$result = json_decode(curl_exec($ch), true);
if ($result['matched'] === 'yes') { /* verified! */ }
curl_close($ch);
Python
r = requests.get(
  "https://dashboard.noxitel.com/api/v2/otp/verify",
  headers={"Authorization": "Bearer YOUR_API_TOKEN"},
  params={"reference": "036BZDUHIX", "otp": "847291"}
)
data = r.json()
if data["matched"] == "yes":
  print("OTP verified successfully")
OTP Matched
{
  "status": "success",
  "matched": "yes"
}
OTP Wrong / Expired
{
  "status": "error",
  "matched": "no",
  "message": "OTP does not match or has expired"
}

Get your API keys

Start with free trial credits. Full platform access, no commitment required.

Get Started Free →