VASbay · SMS API
v3.0Updated 20 Oct 2026 Download PDF Postman Sign in

SMS API

Send transactional and promotional SMS, check your credits and fetch delivery reports from your website, app, CRM or billing software. The same API answers REST (URL parameters, form posts, JSON or XML bodies) and SOAP calls, and replies in JSON (default), XML or SOAP.

Base URLhttps://vasbay.com/webservice/
InputURL / form parameters, JSON, XML, SOAP 1.1 envelope
Outputformat=json (default), xml or soap
TransportHTTPS recommended; UTF-8 everywhere
EndpointMethodPurpose
smsSimpleApi.phpGET · POSTSend one message to one or more numbers
smsApi.phpPOSTBulk send with your own reference per number, and dynamic (personalised) messages
smsBalanceApi.phpGET · POSTCredits left per route
smsStatusApi.phpGET · POSTDelivery status of a push or a single number
soap.phpPOST (WSDL: GET ?wsdl)SOAP operations sendSms, getBalance, getStatus
New in 3.0: the JSON API v3 at https://vasbay.com/api/v3, one set of endpoints for servers, plugins and mobile apps, and ready-made SDKs and plugins for JavaScript, PHP, Python, Laravel, WordPress and Magento. Use v3 for new integrations; the classic API below keeps working.

Older integrations keep working: sentsms.php behaves as smsSimpleApi.php / smsApi.php, smsBalance.php as smsBalanceApi.php and smsStatus.php as smsStatusApi.php.

Authentication

Every call carries two credentials, as parameters or inside the body (JSON head, XML <head> or the SOAP operation element):

FieldWhere to find it
usersNameYour UID: your login name, hex-encoded. Shown in My Profile › API Access.
keyAn enabled API key from My Profile › API Access. Keep it secret; disable it there if it leaks.

Rules

  • Call the API on your own panel's domain. Accounts are linked to the panel (domain) they were created on; the base URL above is this panel's. A call on another reseller's domain is refused with 601.
  • Allowed IPs. If you set allowed IP addresses on the key, calls from any other address are refused with 601. Separate several addresses with commas.
  • Every failure (wrong key, disabled key or account, wrong domain, IP not allowed) returns the same 601 Authentication Failed, so the response never tells an attacker which part was wrong.

Request & response formats

Sending a request

StyleHow
URL parametersGET …/smsSimpleApi.php?usersName=…&key=…&… – values URL-encoded
Form postPOST with Content-Type: application/x-www-form-urlencoded (or multipart)
JSONPOST a JSON object: flat ({"route":"2","numbers":["98…","97…"],…}) or {"smsRequest":{"head":{…},"request":[…]}}
XMLPOST <smsRequest><head>…</head><request>…</request></smsRequest>
SOAP 1.1POST an envelope to soap.php

URL parameters and body values can be mixed: put the credentials in the URL and the message in the body, for example. A value in the body overrides the same parameter in the URL. Requests must be UTF-8. XML bodies may not contain a DOCTYPE or entity declarations.

Choosing the response format

Add format to the request (URL parameter or body field). Without it, REST calls answer in JSON and SOAP calls in SOAP.

formatContent-TypeShape
json (default)application/jsonthe objects shown in this document
xmlapplication/xmlsame fields under <result>; numeric keys become <n0>, <n1>…
soaptext/xmlthe XML result inside <soap:Envelope><soap:Body><{operation}Response>

An unknown value returns error 603.

Success and error envelopes

Send SMS and delivery status succeed with "data": "0" and the result in msg; credit balance with "status": "0" and the result in response. Every error has the same shape: a non-zero status code and the message in response. HTTP status is 200 for both; always check the code.

Error · JSON
{ "status": "601", "response": "Authentication Failed" }
Error · XML
<?xml version="1.0"?>
<result><status>601</status><response>Authentication Failed</response></result>

API v3 · JSON new

A JSON REST API with one set of endpoints for your servers, the plugins and SDKs, and mobile apps. Replies are always JSON with proper HTTP status codes.

BASEhttps://vasbay.com/api/v3

Sign-in: two ways

ForSendNotes
Servers, SDKs, pluginsX-Api-Username: <UID>
X-Api-Key: <API key>
From My Profile › API Access. Same rules as the classic API: your own panel domain, allowed IPs.
Mobile and desktop appsAuthorization: Bearer vb3_…Token from POST /auth/login with the user's own login; valid 90 days, revocable per device. See Mobile apps.

Credentials go in headers only, never in the URL, so they do not end up in server logs or browser history.

Try it in Postman: download the Postman collection (every v3 and classic endpoint, set up for this panel). In Postman choose Import, pick the file, then fill the collection variables uid, api_key, sender_id, mobile and a future schedule_time. The API key folder adds the headers for you; the app folder signs in with Login first. IDs from replies (push, schedule, template, sender ID) are saved for the follow-up requests.
API key
curl https://vasbay.com/api/v3/balance \
  -H 'X-Api-Username: YOUR_UID' \
  -H 'X-Api-Key: YOUR_API_KEY'

Replies

Success
HTTP/1.1 201 Created
{
  "success": true,
  "data": {
    "push_id": 14349171,
    "scheduled_at": null,
    "numbers": [
      { "id": 20222080, "mobile": "9895XXXXXX", "status": "Sent", "ref": "0" },
      { "id": 20222081, "mobile": "9746XXXXXX", "status": "Sent", "ref": "0" }
    ]
  },
  "meta": { "count": 2 }
}
Error
HTTP/1.1 422 Unprocessable Entity
{ "success": false, "error": { "code": "3076", "message": "Invalid Sender Id" } }
HTTP statusMeaning
200 / 201Success (201 for created: sign-in, send, sender ID request)
401601 wrong key, wrong or expired token, wrong domain or IP; 606 no credentials
404 · 405602 unknown endpoint or record; 405 wrong method
422Validation: 3xxx codes of the error list (3087 names the invalid field)
413 · 429607 body over 20 MB; 429 more than 240 requests a minute (login: 20 a minute)
500Unexpected error; retry later (never retry a send blindly: check status first)

Every reply carries X-RateLimit-Limit and X-RateLimit-Remaining. Error codes are the same as the classic API's.

v3 endpoints

EndpointSign-inParameters / returns
POST /auth/loginnoneApp sign-in: login, password, device_name → bearer token (90 days)
POST /auth/logouttokenSign this device out
GET /auth/devices · DELETE /auth/devices/{id}tokenSigned-in devices of the account; sign one out
GET /metoken · keyAccount: id, username, UID, name, e-mail, phone, company, account type, services
GET /balancetoken · keyCredits: transactional, marketing, international (EUR)
POST /sms/sendtoken · keynumbers (array or comma list; strings or JSON numbers) and/or group_ids (contact groups, up to 50; numbers are then extra recipients), message, sender_id, route, sms_type, schedule_time, remove_duplicate, template_id, entity_id, content_id (send DLT ids as strings). A group send lists the first 100 numbers; meta.count is the full count
POST /sms/bulktoken · keyrecipients: [{mobile, ref, fields}] with message, sender_id, route, schedule_time; fields fill #FIELD2#…. Personalised sends go out as one push per distinct text (push_ids, push_id is the first), at most 1000 recipients per request. A scheduled personalised send returns schedule_id (its push_id comes when sent)
GET /sms/statustoken · keypush_id, number_id or page
GET /sms/historytoken · keyfrom, to (YYYY-MM-DD), page, via (web, mobile, api), scheduled
GET /sms/pushes/{push_id}/numberstoken · keyEvery number of one push, paged (page, per_page up to 100): mobile, status, bucket, error, sent and delivered time. status filter (delivered, sent, failed, dnd, unknown, stopped), q (part of a number); meta.counts has the totals of the whole push
GET /groupstoken · keyContact groups with their number of contacts; q (name), page, per_page
GET /groups/{id} · GET /groups/{id}/contactstoken · keyOne group; its contacts paged (q matches number or name)
GET /scheduledtoken · keyScheduled SMS with status and allowed actions; status filter (also failed), type (bulk, dynamic)
POST /scheduled/{push_id}/hold|resume|stoptoken · keyHold, resume or stop a schedule (stop refunds unsent numbers)
POST /scheduled/dynamic/{schedule_id}/stoptoken · keyStop a personalised schedule before it is sent (nothing is charged yet)
GET /sender-idstoken · keyAll sender IDs with status (approved, under_review, with_operator, rejected) and entity ID; filters status, sender_id, route
GET /sender-ids/{id}token · keyStatus of one sender ID request
POST /sender-idstoken · keyRequest a sender ID: sender_id, route, entity_id, company_name, explanation, purpose, sample_sms
GET /templatestoken · keyDLT templates with content ID, entity ID, sender ID and status; type (transactional, marketing), variant (static, dynamic), status (approved by default, or all…), content_id
GET /templates/{id}token · keyStatus of one template
POST /templatestoken · keyRegister a DLT template: type, content_id, text, sender_id, entity_id (defaults to the sender ID's), variant
GET /notificationstoken · keyNotices for the account (HTML and plain text), newest first
GET /noneAPI name and version

schedule_time accepts 2026-12-25 10:30 or ISO 8601 (Indian time when no zone is given); the send is queued and numbers in the reply stays empty until it goes out (see Scheduled SMS). numbers may be strings or JSON numbers; send entity_id and content_id as strings, 19-digit JSON numbers lose precision. Lists accept page and per_page (max 100). SMS sent with an app token show as Mobile in the panel reports, with an API key as API.

Scheduled send
curl -X POST https://vasbay.com/api/v3/sms/send \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"numbers": ["9895XXXXXX"], "message": "Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech",
       "sender_id": "TXAAVY", "route": 2, "schedule_time": "2026-12-25 10:30"}'
Reply
HTTP/1.1 201 Created
{
  "success": true,
  "data": { "push_id": 14349174, "scheduled_at": "2026-12-25T10:30:00+05:30", "numbers": [] },
  "meta": { "count": 0 }
}
Request
curl -X POST https://vasbay.com/api/v3/sms/send \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"numbers": ["9895XXXXXX", "9746XXXXXX"], "message": "Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech",
       "sender_id": "TXAAVY", "route": 2}'

Scheduled bulk & dynamic SMS

Add schedule_time to POST /sms/bulk.

  • Bulk (recipients without fields): queued like any schedule; the reply has the push_id, with hold / resume / stop under /scheduled/{push_id}/….
  • Personalised sends (recipients with fields, now or scheduled) fill in each recipient's text and send it as an ordinary push, one push per distinct text: the reply lists them in push_ids (push_id is the first). At most 1000 recipients per request.
  • Dynamic (recipients with fields): the request is stored now and personalised and sent when due. The reply has a schedule_id and push_id: null; the push_id appears in GET /scheduled?type=dynamic once sent (status completed, or failed with an error). It can be stopped until then with POST /scheduled/dynamic/{schedule_id}/stop.
  • Your balance is checked when the schedule is made and taken when it is sent. Promotional schedules (route 1) must fall between 9:10 AM and 8:45 PM.
Request
curl -X POST https://vasbay.com/api/v3/sms/bulk \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{"sender_id": "TXAAVY", "route": 2, "schedule_time": "2026-12-25 10:30",
       "message": "Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech",
       "recipients": [
         {"mobile": "9895XXXXXX", "ref": "CUS-1"},
         {"mobile": "9746XXXXXX", "ref": "CUS-2"}
       ]}'
Reply · bulk
HTTP/1.1 201 Created
{
  "success": true,
  "data": { "push_id": 14349175, "scheduled_at": "2026-12-25T10:30:00+05:30", "numbers": [] },
  "meta": { "count": 0 }
}
Reply · dynamic
HTTP/1.1 201 Created
{
  "success": true,
  "data": {
    "push_id": null,
    "scheduled_at": "2026-12-25T10:30:00+05:30",
    "numbers": [],
    "schedule_id": 42,
    "type": "dynamic"
  },
  "meta": { "count": 0 }
}

Contact groups & delivery numbers

Send to the contact groups of the account (Contacts › Groups in the panel): list them with GET /groups, look inside one with GET /groups/{id}/contacts, then pass their ids as group_ids to POST /sms/send. numbers in the same request are sent as extra recipients, as Include numbers does in Compose SMS. A scheduled group send takes whole groups only (no extra numbers). Groups can hold lakhs of contacts, so the reply lists the first 100 numbers; meta.count is the full count.

List groups
curl 'https://vasbay.com/api/v3/groups?q=customers' \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY'
Reply
{
  "success": true,
  "data": [
    { "id": 9545, "name": "Customers", "contacts": 360, "created_at": "2026-10-15T15:31:01+05:30" }
  ],
  "meta": { "page": 1, "per_page": 20, "total": 1 }
}
Send to a group plus one number
curl -X POST https://vasbay.com/api/v3/sms/send \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"group_ids": [9545], "numbers": ["9895XXXXXX"], "message": "Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech",
       "sender_id": "TXAAVY", "route": 2}'

GET /sms/pushes/{push_id}/numbers pages through every number of a send with its delivery status, so a report of a large group send never has to load everything at once. Filter with status (delivered, sent = awaiting the operator, failed, dnd, unknown, stopped) or search with q; meta.counts always holds the totals of the whole push.

Delivery numbers
curl 'https://vasbay.com/api/v3/sms/pushes/14349171/numbers?status=failed&page=1&per_page=50' \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY'
Reply
{
  "success": true,
  "data": [
    { "id": 20222081, "mobile": "9746XXXXXX", "status": "Failed", "bucket": "failed",
      "error": "Call barred", "ref": "", "sent_at": "2026-10-17T18:38:02+05:30", "delivered_at": null }
  ],
  "meta": { "page": 1, "per_page": 50, "total": 1, "push_id": 14349171,
            "counts": { "total": 361, "delivered": 340, "sent": 12, "unknown": 0, "dnd": 8, "stopped": 0, "failed": 1 } }
}

Sender IDs & DLT templates

Every SMS in India goes out under an approved sender ID (header) and must match a DLT template registered with its content ID under your entity ID. Request sender IDs, register templates and follow their review through the API.

StatusMeaning
under_reviewRequested, waiting for review
with_operatorForwarded to the operator for registration
approvedReady to use in sends
rejectedNot accepted; request again with corrected details

Sender IDs

POST /sender-ids requests one (6 letters or digits, on route 2 transactional or 1 marketing, with your DLT entity ID). The reply has its id; GET /sender-ids/{id} shows its status, GET /sender-ids lists all of them (filters status, sender_id, route).

Request
curl -X POST https://vasbay.com/api/v3/sender-ids \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{"sender_id": "TXAAVY", "route": 2, "entity_id": "1701XXXXXXXXXXXXXXX",
       "company_name": "Texaavy Infotech", "explanation": "TeXAAVY = Texaavy Infotech",
       "purpose": "OTP and order updates", "sample_sms": "Your OTP is 1234. -Texaavy"}'
Reply
{
  "success": true,
  "data": {
    "id": 758, "sender_id": "TXAAVY", "route": 2, "route_name": "Transactional",
    "status": "under_review", "entity_id": "1701XXXXXXXXXXXXXXX",
    "requested_at": "2026-10-24T10:15:00+05:30", "decided_at": null
  }
}

DLT templates

POST /templates registers a template exactly as approved on the DLT portal: type (transactional or marketing), content_id, text ({#var#} for variable parts; #FIELD2#… makes it a dynamic template), sender_id and entity_id. The sender ID must be one of yours on the same route (requested or approved); entity_id is taken from it when left out and must match it when given. A content ID can be registered once. Templates registered this way are approved at once, as in the panel; their status can change later on review.

GET /templates lists approved templates; add status=all (or under_review, with_operator, rejected) for the others, content_id to find one. GET /templates/{id} shows one with its status.

Request
curl -X POST https://vasbay.com/api/v3/templates \
  -H 'X-Api-Username: YOUR_UID' -H 'X-Api-Key: YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{"type": "transactional", "content_id": "1707XXXXXXXXXXXXXXX",
       "sender_id": "TXAAVY", "entity_id": "1701XXXXXXXXXXXXXXX",
       "text": "Your OTP is {#var#}. -Texaavy"}'
Reply
HTTP/1.1 201 Created
{
  "success": true,
  "data": {
    "id": 8130, "type": "transactional", "variant": "static", "route": 2, "status": "approved",
    "content_id": "1707XXXXXXXXXXXXXXX", "entity_id": "1701XXXXXXXXXXXXXXX", "sender_id": "TXAAVY",
    "text": "Your OTP is {#var#}. -Texaavy", "characters": 29, "sms_parts": 1, "variables": 1,
    "added_at": "2026-10-24T10:20:00+05:30", "decided_at": null
  }
}

Errors: see Sender IDs & templates in the error codes. The SDKs and plugins have the same functions (below).

Voice calls (voice broadcast)

Play a recorded message to many mobile numbers at once (OBD voice broadcast): payment and appointment reminders, alerts, announcements and offers. Every call reports whether it was answered, how long it lasted and the keys the person pressed (DTMF, e.g. 1 for "interested"). Voice calls need the voice service on your account and voice credits.

ConceptHow it works
Audio fileUpload MP3 / WAV recordings (up to 5 MB, 10 minutes) in the panel under Voice Call › Audio files. GET /voice/files lists the ready ones with their id.
PulseCalls are charged per pulse of audio: 15 s (billing types 1, 3) or 30 s (2, 4). Credits = numbers × pulses of the file.
Billing1/2 charge every number called; 3/4 charge answered calls only: credits are reserved when sending and refunded automatically for calls that are not answered.
Route1 promotional, 2 transactional. Left out, the first route / billing type you have credits for is used (GET /voice/balance).
Caller IDThe number shown to the person called: one of yours after approval (GET /voice/caller-ids), or the platform default.

Endpoints

MethodPathPurpose
GET/voice/balanceVoice credits per route and billing type
GET/voice/filesReady audio files: id, name, seconds, pulses per billing type
GET/voice/caller-idsYour approved caller IDs and the default
POST/voice/callsSend now, or schedule with schedule_time
GET/voice/callsYour campaigns (from, to, state, q, page, per_page) with totals
GET/voice/calls/{id}One campaign and the result of every number (100 per page)
POST/voice/calls/{id}/cancelCancel a scheduled campaign; the reserved credits are refunded

Send or schedule

POST /voice/calls with file_id (required), numbers (array or comma list; Indian mobiles with or without +91, duplicates removed, up to 100,000), and optionally route, billing_type, caller_id, name and schedule_time (e.g. 2026-11-01 10:30 or ISO 8601, at least a minute ahead). The reply (HTTP 201) is the campaign; meta.ignored_numbers counts entries that were not valid mobile numbers.

curl
curl -X POST https://vasbay.com/api/v3/voice/calls \
  -H "X-Api-Username: YOUR_UID" -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_id": 42, "numbers": ["9876543210", "+91 98450 12345"], "name": "Payment reminder"}'
Reply of GET /voice/calls/1287
{
  "success": true,
  "data": {
    "id": 1287, "name": "Payment reminder", "state": "completed",
    "route": "Promotional", "billing": "Answered · 15 s pulse", "billing_type": 3, "caller_id": "",
    "pulses": 2, "credits": 4, "refunded": 2, "numbers": 2,
    "answered": 1, "no_answer": 1, "busy": 0, "failed": 0, "pending": 0, "talk_seconds": 24,
    "scheduled_at": null, "created_at": "2026-10-25T10:30:04+05:30", "source": "API",
    "calls": [
      {"mobile": "9876543210", "status": "Answered", "duration": 24, "dtmf": "1", "started_at": "…", "ended_at": "…"},
      {"mobile": "9845012345", "status": "No answer", "duration": 0, "dtmf": "", "started_at": null, "ended_at": null}
    ]
  },
  "meta": {"page": 1, "per_page": 100, "pages": 1}
}
Campaign stateNumber status
scheduled waiting for its time · queued about to be sent · in_progress calls running · completed every result in · failed not accepted (see reason; credits refunded) · cancelled Queued · Submitted (ringing / waiting for the result) · Answered · No answer · Busy · Failed · Cancelled
Results usually arrive within a few minutes of the call. Errors: 403 voice service not enabled, 4020 not enough voice credits, 4021 the voice operator did not accept the campaign (credits refunded), 3087 invalid input (the message says which field).

Mobile apps

Apps never contain an API key. Each user signs in with their own panel login; the app receives a token for that device only.

Sign-in flow
curl -X POST https://vasbay.com/api/v3/auth/login -H 'Content-Type: application/json' \
  -d '{"login": "your-login", "password": "your-password", "device_name": "Pixel 8"}'

# reply (HTTP 201): keep the token in the device's secure storage
{ "success": true, "data": { "token": "vb3_…", "token_type": "Bearer",
  "expires_at": "2027-01-18T10:30:00+05:30", "user": { "id": 1024, "username": "…", "account_type": "customer" } } }

# every later call
curl https://vasbay.com/api/v3/me -H 'Authorization: Bearer vb3_…'
  • Store the token securely: iOS Keychain, Android Keystore / EncryptedSharedPreferences. Never in plain preferences or logs.
  • On 401 (expired or signed out) show the sign-in screen again; tokens last 90 days.
  • Sign-in rules are those of the panel: the account must belong to this panel's domain; 8 wrong passwords lock the login for 15 minutes; at most 20 sign-in requests a minute per address.
  • Devices: GET /auth/devices lists the account's signed-in devices (up to 10; the oldest is signed out first) and DELETE /auth/devices/{id} signs one out. POST /auth/logout signs out the current one.
  • Everything else (send, status, history, scheduled SMS, sender IDs, templates, notifications) is the same API as for servers.

SDKs & plugins · v3.0

Ready-made integrations on the v3 API, prepared for this panel (VASbay). They contain no credentials: each customer enters their own Username (UID) and API key from My Profile › API Access.

JavaScript SDKNode.js 18+
Download v3.1.0 SHA-256 705ddd0d79442763… · 7.7 KB
PHP SDKPHP 7.4+
Download v3.1.0 SHA-256 89d03c1a2bd88209… · 6.5 KB
Python SDKPython 3.8+
Download v3.1.0 SHA-256 ebcc35d7b3753c70… · 12.2 KB
Laravel packageLaravel 9–12, PHP 8.1+
Download v3.1.0 SHA-256 21726c34288632e6… · 9.7 KB
WordPress pluginWordPress 5.8+, WooCommerce
Download v3.1.0 SHA-256 82b661b9e6d8a602… · 10.6 KB
Magento 2 moduleMagento 2.4
Download v3.1.0 SHA-256 00c79cb0d6696e37… · 12.8 KB
VASbay mobile appAndroid 7.0+ · ready to use
Download v1.1.0 94.0 MB · How to install
Setup
// npm install ./sms-gateway-js            (Node.js 18+, server only)
import { SmsGateway } from '@texaavy/sms-gateway';

const sms = new SmsGateway({ username: process.env.SMS_USERNAME, apiKey: process.env.SMS_API_KEY });
const r = await sms.send({ numbers: ['9895XXXXXX'], message: 'Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech', senderId: 'TXAAVY' });
console.log(r.push_id, await sms.balance());
PackageIncludes
JavaScript · PHP · Python SDKsEvery v3 endpoint: send, bulk, status, history, balance, account, sender IDs (request, list, status), DLT templates (register, list, status), notifications, scheduled SMS (hold / resume / stop, dynamic stop), app sign-in. Typed errors with the API code.
LaravelAuto-discovered service provider, SmsGateway facade, sms-gateway notification channel, config in .env; includes the PHP SDK.
WordPressSettings page with connection test and balance, test SMS, WooCommerce order SMS for processing, completed, on hold, cancelled and refunded (sent in the background); sender IDs and DLT templates with their status, register a template, request a sender ID.
Magento 2Admin configuration with encrypted key and connection test, order placed and order shipped SMS, results in the order comments; client methods for sender IDs and DLT templates (request, register, status).
Security built in: HTTPS with certificate checks (plain http only for local testing), credentials in headers and stored encrypted (WordPress, Magento) or in environment variables, keys never logged or shown again, no automatic retry of sends (no duplicate SMS), admin screens protected by permissions and CSRF tokens. The JavaScript SDK refuses to run in a browser. Versions and checksums for update checks: manifest.json.

Send SMS

GET/POSThttps://vasbay.com/webservice/smsSimpleApi.php

Sends one message to one or more numbers. Accepts every input style; the numbers go in numbers.

Parameters

ParameterDescription
usersNamerequiredYour UID (hex)
keyrequiredAPI key
routerequired1 promotional (marketing) · 2 transactional · 4 international
senderIdroutes 1, 2An approved sender id (header) of your account, case-sensitive, e.g. TXAAVY
messagerequiredThe text. Must match one of your approved DLT templates unless your account has an open route. URL-encode it in a URL.
numbersrequiredMobile numbers separated by commas (JSON: also an array). 10 digits; a leading 0 or + is removed.
smsTypeoptional1 normal (default) · 2 flash · 3 unicode (any language)
removeDuplicateoptional1 send once to a repeated number · 0 (default) send to every entry
creditBackoptional1 normal (default) · 2 credit back, where your account has it enabled
scheduleTypeoptional1 send now (default) · 2 send once at scheduleTime. Repeating schedules are made in the panel.
scheduleTimewith scheduleType 2DD-MM-YYYY hh:mm AM, Indian time, in the future, e.g. 25-12-2026 10:30 AM; in a URL encode the spaces: 25-12-2026%2010:30%20AM
smsTemplateIdoptionalId of the approved template to use; found automatically from the message when left out
entityId, contentIdoptionalDLT entity id and content (template) id, numeric; looked up from the template when left out
includeNumber, excludeNumberoptionalExtra numbers to add / numbers to leave out, comma separated
formatoptionaljson (default) · xml · soap

Examples

Request
https://vasbay.com/webservice/smsSimpleApi.php?usersName=YOUR_UID&key=YOUR_API_KEY&route=2&senderId=TXAAVY&numbers=9895XXXXXX,9746XXXXXX&message=Dear%20Customer%2C%20Your%20SMS%20account%20has%20been%20activated%20successfully.Texaavy%20Infotech

Response

pushId identifies the whole send (use it for delivery status); each number gets a smsHistoryNumberId. apirefSmsId is your own reference (idno, bulk sends) or 0. The list holds the numbers created so far; large sends are queued and appear in delivery status as they are processed.

200 OK
{
  "data": "0",
  "msg": {
    "pushId": 14349171,
    "response": {
      "0": { "smsHistoryNumberId": 20222080, "status": "Sent", "apirefSmsId": "30", "phone": 9895XXXXXX },
      "1": { "smsHistoryNumberId": 20222081, "status": "Sent", "apirefSmsId": "31", "phone": 9746XXXXXX },
      "count": 2
    }
  }
}

Bulk & dynamic SMS

POSThttps://vasbay.com/webservice/smsApi.php?usersName=…&key=…

Send the same message to many numbers with your own reference per number (idno, returned as apirefSmsId), or a personalised message per number. The body is JSON or XML; the head takes the parameters of Send SMS (except numbers).

Entry fieldDescription
mobileThe number. Entries without a valid 10-digit number are skipped.
idnoYour reference for this number, returned as apirefSmsId
field1 … fieldNfield1 is the number, field2… replace #FIELD2#… in the message
Request
curl -X POST 'https://vasbay.com/webservice/smsApi.php?usersName=YOUR_UID&key=YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "smsRequest": {
    "head": {
      "route": "2",
      "senderId": "TXAAVY",
      "smsType": "1",
      "removeDuplicate": "1",
      "message": "Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech"
    },
    "request": [
      { "mobile": "9895XXXXXX", "idno": "30" },
      { "mobile": "9746XXXXXX", "idno": "31" }
    ]
  }
}'

The response is the same as for Send SMS.

Scheduled SMS

Add scheduleType=2 and scheduleTime (DD-MM-YYYY hh:mm AM/PM, Indian time) to any send. The time must be in the future; in a URL encode its spaces (%20). Promotional SMS (route 1) are only sent between 9:10 AM and 8:45 PM, so a promotional schedule must fall in that window too.

A scheduled send is queued, not sent: the reply carries the pushId and the time, with no numbers yet ("count": 0). The numbers and their status appear under smsStatusApi.php?pushId= once the time has come.

Bulk and dynamic: request entries (mobile, or field1… for personalised messages, see Bulk & dynamic SMS) are scheduled the same way. A personalised schedule replies with a scheduleId and pushId 0: its pushId is created when it is sent. List it with GET /api/v3/scheduled?type=dynamic and stop it with POST /api/v3/scheduled/dynamic/{scheduleId}/stop. Repeating schedules are made in the panel.

Request
https://vasbay.com/webservice/smsSimpleApi.php?usersName=YOUR_UID&key=YOUR_API_KEY&route=2&senderId=TXAAVY&numbers=9895XXXXXX&message=Dear%20Customer%2C%20Your%20SMS%20account%20has%20been%20activated%20successfully.Texaavy%20Infotech&scheduleType=2&scheduleTime=25-12-2026%2010%3A30%20AM
Reply
{
  "data": "0",
  "msg": {
    "pushId": 14349174,
    "scheduleTime": "25 December 2026 10:30 AM",
    "response": { "count": 0 }
  }
}
Your balance is checked when the schedule is created; the credits are taken when it is sent. Scheduled sends can be followed, put on hold, resumed or stopped in the panel under Delivery Reports › Scheduled SMS (or with /api/v3/scheduled); stopping returns the credits of numbers not yet sent. Every SMS sent through the API is marked API in the panel reports.

Credit balance

GET/POSThttps://vasbay.com/webservice/smsBalanceApi.php

Parameters: usersName, key, optional format. Credits are returned as strings.

Request
https://vasbay.com/webservice/smsBalanceApi.php?usersName=YOUR_UID&key=YOUR_API_KEY&format=json
200 OK
{
  "status": "0",
  "response": {
    "transactional": "20000",
    "marketing": "30000",
    "international": { "eur": "0" }
  }
}

Delivery status

GET/POSThttps://vasbay.com/webservice/smsStatusApi.php
ParameterDescription
usersName, keyrequiredCredentials
pushIdone ofEvery number of one send
smsHistoryNumberIdone ofOne number (with or without pushId)
pageone ofYour latest numbers, 10 per page (1, 2, …); combine with pushId to page through a large send
formatoptionaljson · xml · soap
Request
https://vasbay.com/webservice/smsStatusApi.php?usersName=YOUR_UID&key=YOUR_API_KEY&format=json&pushId=14349171
200 OK · JSON
{
  "data": "0",
  "msg": {
    "0": {
      "smsHistoryNumberId": 20222080,
      "smsHistoryId": 14349171,
      "phone": 9895XXXXXX,
      "status": "Delivered",
      "apirefSmsId": "30",
      "countSms": 2
    },
    "count": 1,
    "totalCount": 2
  }
}

count is the number of entries in this answer, totalCount the numbers of the push, countSms the numbers of the entry's push.

Status values

statusMeaning
Sent / SubmittedHanded to the operator, delivery report not received yet
DeliveredDelivered to the handset
Not Delivered, Failed, operator codesNot delivered (switched off, invalid number, …)
DND, Message RejectedBlocked by DND preference or rejected by the operator / DLT scrubbing
StoppedThe send was stopped in the panel before this number went out; it was not charged
0 or emptyPending – no status from the operator yet

SOAP API

POSThttps://vasbay.com/webservice/soap.php
GEThttps://vasbay.com/webservice/soap.php?wsdlservice description for code generators

SOAP 1.1, document/literal, namespace urn:vasbay:sms. The operation is the first element of the Body; its children are the same fields as the REST API (namespace prefixes are optional). Repeat <request> for bulk / dynamic recipients. The answer is <{operation}Response><result>…</result> with the same fields as the REST JSON; add format=json or format=xml to the URL to get those instead.

OperationFields
sendSmsas Send SMS / Bulk & dynamic SMS
getBalanceusersName, key
getStatusas Delivery status
SOAP
POST /webservice/soap.php HTTP/1.1
Host: vasbay.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:vasbay:sms#sendSms"

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sms="urn:vasbay:sms">
  <soap:Body>
    <sms:sendSms>
      <sms:usersName>YOUR_UID</sms:usersName>
      <sms:key>YOUR_API_KEY</sms:key>
      <sms:route>2</sms:route>
      <sms:senderId>TXAAVY</sms:senderId>
      <sms:message>Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech</sms:message>
      <sms:request><sms:mobile>9895XXXXXX</sms:mobile><sms:idno>30</sms:idno></sms:request>
      <sms:request><sms:mobile>9746XXXXXX</sms:mobile><sms:idno>31</sms:idno></sms:request>
    </sms:sendSms>
  </soap:Body>
</soap:Envelope>

Errors come back inside the same response element: <result><status>601</status><response>Authentication Failed</response></result> (HTTP 200, no SOAP Fault).

SMPP connectivity SMPP 3.4

High-volume senders (SMS platforms, aggregators, banks) can connect over SMPP v3.4 instead of HTTP. Messages sent over SMPP are sent under your VASbay account exactly like API sends: your credits are debited, your approved sender IDs and DLT templates apply, and every message appears in your delivery reports.

ConnectionValue
Host and portShared securely with your SMPP account (never published)
System ID / passwordOne account per route (e.g. ACME_OTP, ACME_TRANS); password up to 8 characters
Bind typesTransceiver (recommended), transmitter, receiver
Interface version0x34 (SMPP 3.4); system_type may be empty
ThroughputAgreed TPS per account, shared by all its binds
Simultaneous bindsSet per account (typically 2–4)
Allowed IPsYour SMPP client's public IPs must be whitelisted on the account
Keep-aliveSend enquire_link every 30–60 s; an idle bind is closed after 120 s
To get an SMPP account, contact VASbay support with the routes you need (transactional, OTP, promotional, international), your expected TPS and the public IP addresses of your SMPP client.

SMPP · submit_sm

FieldValue
source_addrAn approved sender ID (header) of your account, e.g. TXAAVY; TON 5 / NPI 0 for alphanumeric
destination_addrMobile number with country code, digits only: 919876543210 (a leading + is accepted)
esm_class0x00, or 0x40 when short_message starts with a UDH (long SMS)
registered_delivery1 receipt always, 2 only on failure, 0 none
data_coding0 default text (ASCII / Latin-1), 1 ASCII, 3 Latin-1, 8 UCS-2 (Unicode, all Indian languages); flash: 0x10 / 0x18. Binary codings are refused.
short_messageUp to 254 octets; for longer text use UDH parts or message_payload
TLV 0x1400DLT entity (PE) ID, optional
TLV 0x1401DLT content template ID, optional – without it the text must match one of your approved templates
TLV 0x1402DLT telemarketer ID chain, optional
TLV 0x0424message_payload (with sm_length 0) for long messages

submit_sm_resp returns a message_id (16 hex characters) at once; the message is then queued and sent by priority (OTP accounts first). Long SMS sent in UDH parts (8-bit or 16-bit reference) are joined into one message; each part gets its own message_id and its own receipt. Parts that have not all arrived after 120 s are sent as received.

Other PDUs: enquire_link, unbind, query_sm (returns message_state and final date). cancel_sm, replace_sm and submit_multi are not supported.

Bind and send
import smpplib.client, smpplib.consts, smpplib.gsm

client = smpplib.client.Client('SMPP_HOST', SMPP_PORT)   # from your account details
client.set_message_received_handler(lambda pdu: print('receipt:', pdu.short_message))
client.connect()
client.bind_transceiver(system_id='ACME_OTP', password='********')

parts, coding, esm = smpplib.gsm.make_parts('482913 is your login OTP. Valid for 10 minutes. -Texaavy')
for part in parts:
    client.send_message(
        source_addr_ton=smpplib.consts.SMPP_TON_ALNUM, source_addr='TXAAVY',
        dest_addr_ton=smpplib.consts.SMPP_TON_INTL, destination_addr='919876543210',
        short_message=part, data_coding=coding, esm_class=esm,
        registered_delivery=True)
    # DLT IDs (optional): add TLV 0x1400 = entity ID and 0x1401 = template ID
    # with your library's custom optional-parameter support, or rely on template matching
client.listen()

SMPP · delivery receipts

Receipts arrive as deliver_sm with esm_class 0x04 on a receiver or transceiver bind of the same account (round-robin when several are open). Answer each with deliver_sm_resp; unanswered receipts are sent again every 60 s, up to 10 times.

short_message of a receipt
id:71c4ab54b3af3fd9 sub:001 dlvrd:001 submit date:2611011025 done date:2611011025 stat:DELIVRD err:000 text:482913 is your login
statmessage_state TLV (0x0427)Meaning
DELIVRD2Delivered to the handset
UNDELIV5Not delivered (switched off, invalid, DND for promotional…); err is the operator code
EXPIRED3No final status within 72 hours
REJECTD8Refused before sending: err is the API error code (e.g. 076 = 3076 sender ID not approved, 018 = 3018 credits low, 082 = 3082 no matching template)

The receipt also carries receipted_message_id (TLV 0x001E) with the message_id from submit_sm_resp.

SMPP · command status codes

StatusNameWhen
0x00ESME_ROKAccepted
0x0EESME_RINVPASWDWrong password
0x0FESME_RINVSYSIDUnknown or disabled system ID
0x0DESME_RBINDFAILIP not whitelisted, or the account's maximum simultaneous binds reached
0x05ESME_RALYBNDBind sent twice on one connection
0x04ESME_RINVBNDSTSsubmit_sm on a receiver bind or before binding
0x58ESME_RTHROTTLEDAbove your TPS – pause briefly and retry
0x14ESME_RMSGQFULToo many messages queued for the account – retry later
0x0AESME_RINVSRCADRSender missing or invalid
0x0BESME_RINVDSTADRNumber not 8–15 digits
0x104ESME_RINVDCSBinary data coding
0x08ESME_RSYSERRTemporary server error – retry
An accepted submit_sm can still be REJECTD later (credits, sender ID, template): always request receipts and handle them. Do not resubmit a message after a timeout without checking with query_sm, or it may go out twice.

Error codes

0 means success; any other code is an error. The message is the exact text the API returns.

Request

CodeMessageWhen
601Authentication FailedusersName / key wrong, key disabled, account inactive, request not on your panel domain, or caller IP not allowed
602Error Request Api Not Foundunknown SOAP operation
603Invalid Response Format Supported Formats Are json, xml, soapformat is not json, xml or soap
604Error No Contacts Foundno valid mobile number in numbers / request entries
605Invalid Request Body Send Url Parameters, json, xml Or soapthe body is not valid JSON, XML or SOAP (or contains a DOCTYPE)
606usersName And key Are RequiredusersName or key missing
607Request Too Large (Max 20 MB)request body larger than 20 MB
500Internal Error Please Try Again Laterunexpected server error; retry later

Send SMS

CodeMessageWhen
3001Invalid Sms Routeroute missing or not 1 / 2 / 4
3002Invalid Sms Credit BackcreditBack is not 1 or 2
3003Invalid Sms TypesmsType is not 1, 2 or 3
3004Invalid Shedule TypescheduleType is not 1 or 2 (repeating schedules are made in the panel)
3006Number Must be Numerica number is not numeric
3007Number Must be Have 10 Digita number does not have 10 digits
3012Message Feild is Emptymessage empty
3013Sms Service Deactivated Please Contact Support To Activate ServiceSMS service not active on the account
3014Operator Downtime...Please Try Again Laterroute under operator downtime
3017Please Add Ateast One Mobile Number to Proceedno number left to send to
3018Your sms Credit Balance is Low Please Credit Smsnot enough credits on the route (a schedule is checked when it is created)
3019Sms DownTIme Please Try After Some Timeroute temporarily unavailable
3021Invalid Sender Idsender id not approved for the account
3022Invalid Time FormatscheduleTime not readable
3030Schedule Not Possible In Between 8:45 PM AND 9:10 AMpromotional SMS (now or scheduled) outside 9:10 AM – 8:45 PM
3031Schedule Date And Time Must Greather Than Current Time (IST)scheduleTime is in the past
3036Empty SenderIDsenderId missing (routes 1 and 2)
3075Remove Duplicate Must 1 or 0removeDuplicate is not 0 or 1
3076Invalid Sender IdsenderId is not one of your approved sender ids
3077Requested Template Not Approved Please Request Template From Panelno approved template on the account (accounts without open route)
3080Please Select valid templatesmsTemplateId is not an approved template
3081please select a template for Transaction smstransactional SMS without a template
3082Selected template Not Match with the enter templatemessage does not match any approved template
3084scheduleTime Is Required For Scheduled Sms (Eg 22-03-2018 11:12 PM)scheduleType 2 without scheduleTime
3087Invalid {parameter}a parameter has a value that is not allowed (the message names it), message is longer than 2000 characters
3088Too Many Recipients In One Request (Max 100000)more than 100000 request entries in one call
3301Invalid Entity IdentityId not numeric
3302Invalid Content IdcontentId not numeric

Sender IDs & templates (v3)

CodeMessageWhen
3036The sender ID must be exactly 6 letters or digits (for example TXAAVY).sender ID request incomplete or invalid (the message names the field), or already requested on that route
3076Sender ID TXAAVY is not one of your sender IDs on the transactional route (requested or approved).sender_id of a template is not one of your sender IDs on its route
3301entity_id does not match the DLT entity ID of sender ID TXAAVY (1701…).entity_id of a template differs from its sender ID's DLT entity ID
3087Content ID 1707… is already saved as template #8130.template field missing or invalid, dynamic template without #FIELD#, or content ID already saved
602Template not foundGET /sender-ids/{id} or /templates/{id} of an ID that is not yours

Status

CodeMessageWhen
3006smsHistoryNumberId Must be NumericsmsHistoryNumberId not numeric
3032Invalid Push IdpushId not numeric or not one of your pushes
3078Please Provide pushId or smsHistoryNumberId to get Statusneither pushId, smsHistoryNumberId nor page given
3085Invalid page Numberpage is not a positive number
3086No Sms Foundno SMS found for the given smsHistoryNumberId / page

Code samples

Send SMS
<?php
// Send an SMS (JSON response)
$query = http_build_query([
    'usersName' => 'YOUR_UID',
    'key'       => 'YOUR_API_KEY',
    'route'     => 2,
    'senderId'  => 'TXAAVY',
    'numbers'   => '9895XXXXXX,9746XXXXXX',
    'message'   => 'Dear Customer, Your SMS account has been activated successfully.Texaavy Infotech',
]);
$ch = curl_init('https://vasbay.com/webservice/smsSimpleApi.php');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => $query,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 30,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);

if (($result['data'] ?? null) === '0') {
    echo 'Accepted, push id ' . $result['msg']['pushId'];
} else {
    echo 'Error ' . $result['status'] . ': ' . $result['response'];
}

Notes & limits

  • Templates (DLT). Transactional and promotional messages must match an approved template of your account, including the sender id. Request templates and sender ids in the panel.
  • Message length. 160 characters per SMS part (153 when split); unicode 70 (67 when split). Credits are charged per part and number.
  • Credits are checked before sending; a send larger than your balance is refused with 3018.
  • Timeouts. Allow at least 30 seconds for a send; do not retry a send automatically on a timeout without checking delivery status first, or the SMS may go out twice.
  • Delivery reports usually arrive within minutes, but some operators take much longer. Poll smsStatusApi.php sparingly (for example every few minutes).
  • Security. Use HTTPS, keep the key on your server (never in a mobile app or web page), and restrict it to your server IPs.