Overview
The BroadNet API is a REST API over HTTPS. You authenticate with a Bearer token, send a JSON or multipart request to a channel endpoint, and get back a message ID or a batch summary. Delivery status is pushed to the webhook URL configured on your account. The complete API, 329 paths and 376 operations across eight channels, is published as an OpenAPI 3.1 spec. The examples on this page use curl, Node.js, Python, Java, C#, Go, Ruby and the official TypeScript SDK.
Environments
The samples on this page call the production base URL. Test credentials, and where to send test traffic, come with your test access: request it at /signup and we reply within one business day.
| Environment | Base URL |
|---|---|
| Production | https://api.broadnet.me |
Authentication
Every request carries your access token in an HTTP header. The token is issued per account and comes from your BroadNet account. The examples on this page read it from an environment variable called BROADNET_TOKEN.
Authorization: Bearer $BROADNET_TOKENIf the token is missing or invalid, the API answers with HTTP 401 and a JSON error body in the standard error format described below. There is no call that exchanges a username and password for a token.
Send an SMS
Send one SMS with a JSON body. The four required fields are the sender, the destination, the text and the encoding.
Required fields
| Field | Data type | Description |
|---|---|---|
| senderId | string | Your approved Sender ID, shown to the recipient as the sender. |
| destinationNumber | string | Recipient number with country code, digits only, no plus sign. |
| message | string | The message text. |
| messageType | string | Encoding: TEXT for GSM-7 text, UNICODE for Arabic, emoji and other scripts. |
Optional fields
| Field | Data type | Description |
|---|---|---|
| charCount | integer | Character count, as returned by /sms/identify. |
| smsParts | integer | Number of segments, as returned by /sms/identify. |
| charLimit | integer | Characters per segment, as returned by /sms/identify. |
| expiryHour | integer | Validity period in hours. |
| isSchedule | boolean | Set to true to schedule the message instead of sending now. |
| delay | number | Delay before sending. |
| gmt | string | GMT offset used for scheduling. |
| time | — | Scheduled send time (with isSchedule). |
| repeat | — | Repeat setting for scheduled sends. |
| peId | string | Principal entity ID, where a regulator requires one. |
| templateId | string | Registered template ID, where a regulator requires one. |
| telemarketerId | string | Telemarketer ID, where a regulator requires one. |
| campaignName | string | Your label for reporting. |
curl -X POST https://api.broadnet.me/sms/sendSms \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"senderId": "BroadNet",
"destinationNumber": "447700900123",
"message": "Your verification code is 482913",
"messageType": "TEXT"
}'
# 200 OK → response body is the message ID, e.g. 2603121407537573731// Node.js 18+ (fetch)
const res = await fetch("https://api.broadnet.me/sms/sendSms", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BROADNET_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
senderId: "BroadNet",
destinationNumber: "447700900123",
message: "Your verification code is 482913",
messageType: "TEXT",
}),
});
console.log(await res.text()); // message IDimport os, requests
r = requests.post(
"https://api.broadnet.me/sms/sendSms",
headers={"Authorization": f"Bearer {os.environ['BROADNET_TOKEN']}"},
json={
"senderId": "BroadNet",
"destinationNumber": "447700900123",
"message": "Your verification code is 482913",
"messageType": "TEXT",
},
)
print(r.status_code, r.text) # message ID// Java 11+ — java.net.http is built in, nothing to install
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class SendSms {
public static void main(String[] args) throws Exception {
String json = "{"
+ "\"senderId\": \"BroadNet\", "
+ "\"destinationNumber\": \"447700900123\", "
+ "\"message\": \"Your verification code is 482913\", "
+ "\"messageType\": \"TEXT\""
+ "}";
HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.broadnet.me/sms/sendSms"))
.header("Authorization", "Bearer " + System.getenv("BROADNET_TOKEN"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.statusCode() + " " + res.body()); // 200 + message ID
}
}// .NET 6+ console app (Program.cs) — HttpClient is built in, no NuGet package
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Bearer", Environment.GetEnvironmentVariable("BROADNET_TOKEN"));
// PostAsJsonAsync sends Content-Type: application/json
var res = await http.PostAsJsonAsync("https://api.broadnet.me/sms/sendSms", new
{
senderId = "BroadNet",
destinationNumber = "447700900123",
message = "Your verification code is 482913",
messageType = "TEXT",
});
var id = await res.Content.ReadAsStringAsync();
Console.WriteLine($"{(int)res.StatusCode} {id}"); // 200 + message IDpackage main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body := []byte(`{
"senderId": "BroadNet",
"destinationNumber": "447700900123",
"message": "Your verification code is 482913",
"messageType": "TEXT"
}`)
req, err := http.NewRequest(http.MethodPost, "https://api.broadnet.me/sms/sendSms", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("BROADNET_TOKEN"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
id, _ := io.ReadAll(res.Body)
fmt.Println(res.StatusCode, string(id)) // 200 + message ID
}require "net/http"
require "json"
uri = URI("https://api.broadnet.me/sms/sendSms")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch('BROADNET_TOKEN')}"
req["Content-Type"] = "application/json"
req.body = {
senderId: "BroadNet",
destinationNumber: "447700900123",
message: "Your verification code is 482913",
messageType: "TEXT"
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts "#{res.code} #{res.body}" # 200 + message ID// npm install @broadnet/cpaas-sdk axios
import { Configuration, SMSSMSApi } from "@broadnet/cpaas-sdk";
const sms = new SMSSMSApi(
new Configuration({
basePath: "https://api.broadnet.me",
accessToken: process.env.BROADNET_TOKEN!,
}),
);
const res = await sms.smsSendsmsPost({
sMSSmsRequest: {
senderId: "BroadNet",
destinationNumber: "447700900123",
message: "Your verification code is 482913",
messageType: "TEXT",
},
});
console.log(res.data); // message IDA successful call returns HTTP 200 and the message ID as the response body, with no JSON envelope:
HTTP/1.1 200 OK
2603121407537573731Encoding & segments
The messageType field sets the encoding, and the encoding sets how many characters fit in one SMS segment. Longer messages are split into segments and reassembled on the handset.
| messageType | Single SMS | Per segment (long message) | Use for |
|---|---|---|---|
| TEXT | 160 | 153 | GSM-7 characters only. |
| UNICODE | 70 | 67 | Any other script: Arabic, Cyrillic, emoji, accented characters outside GSM-7. |
Not sure which encoding to use? Ask the API. The identify endpoint analyses a message and returns its encoding, character count, number of segments and characters per segment, which you can pass straight into the send request.
curl -X POST https://api.broadnet.me/sms/identify \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "message": "Your verification code is 482913" }'{
"message": "Your verification code is 482913",
"messageType": "TEXT",
"smscount": 1,
"charCount": 32,
"charLimit": 160
}Try it without writing code in the SMS character counter.
Phone number formats
Destination numbers are the country code followed by the national number, in digits only. Do not add a leading plus sign, a 00 prefix, spaces, hyphens or brackets.
| Example | Result | Why |
|---|---|---|
| 447700900123 | Valid | Country code 44 plus the national number, digits only. |
| +44 7700 900123 | Reject | Contains a plus sign and spaces. Strip them first. |
| 07700900123 | Reject | National format with a leading zero and no country code. |
Bulk SMS
To send one message to many recipients, upload a file of numbers in a multipart form request. The request has two parts. The first, destinationNumberFile, is a CSV or TXT file of numbers. The second, bulkRequest, is a JSON string with the sender, text, encoding and campaign name.
curl -X POST https://api.broadnet.me/sms/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F destinationNumberFile=@recipients.csv \
-F 'bulkRequest={"senderId":"BroadNet","message":"Your statement is ready","messageType":"TEXT","campaignName":"statements"}'{
"status": "success",
"bulkSessionId": "1_20260228105000887",
"credits": "9966465.42850",
"deductcredits": "0.60000",
"bulkListInfo": {
"total": 4,
"validCount": 3,
"invalidCount": 0,
"duplicate": 1
}
}The bulkListInfo object tells you how many numbers were accepted, how many were invalid and how many were duplicates. Once a job is running, you can manage it by its batch ID:
| HTTP method | Endpoint path | Description |
|---|---|---|
| GET | /sms/list | List your bulk jobs with processed and pending counts. |
| GET | /sms/pause?batch_Id=… | Pause a running job. |
| GET | /sms/resume?batch_Id=… | Resume a paused job. |
| DELETE | /sms/abort?batch_Id=… | Abort a job; pending messages are not sent. |
| POST | /sms/resend | Resend messages from an earlier job. |
| POST | /sms/send-now | Release a scheduled job immediately. |
| POST | /sms/auto-schedule | Schedule a bulk job automatically. |
# List your bulk jobs (each entry's id is the batch_Id below)
curl https://api.broadnet.me/sms/list \
-H "Authorization: Bearer $BROADNET_TOKEN"
# Pause, then resume, a running job
curl "https://api.broadnet.me/sms/pause?batch_Id=1024" \
-H "Authorization: Bearer $BROADNET_TOKEN"
curl "https://api.broadnet.me/sms/resume?batch_Id=1024" \
-H "Authorization: Bearer $BROADNET_TOKEN"Number lookup
Check the status of a number (HLR and MNP) before you send, for example to clean a list or to handle ported numbers. Pass the number as the destinationNumber query parameter. The optional reqType parameter selects the kind of lookup.
curl -X POST "https://api.broadnet.me/sms/lookup?destinationNumber=447700900123" \
-H "Authorization: Bearer $BROADNET_TOKEN"Delivery status
Delivery status is pushed to the webhook URL configured on your BroadNet account as each message moves through its lifecycle. Message statuses follow this lifecycle:
SUBMITTED· Accepted by BroadNet and queued for the network.SENT· Handed to the operator or channel.DELIVERED· Confirmed on the handset.READ· Opened by the recipient, on channels that report reads, such as WhatsApp.FAILED / REJECTED· Not delivered.
You can also poll for status. For WhatsApp, the bulk-insights endpoint returns the status of each recipient in a batch. For SMS bulk jobs, the list endpoint returns processed and pending counts.
Errors
A missing or invalid Bearer token is rejected at the API gateway before the request reaches the API. The gateway returns HTTP 401 with a JSON body of two fields, error and message:
{
"error": "Unauthorized",
"message": "Missing Authorization token"
}Errors raised by the API itself, such as a 400 validation error, return a JSON body called ExceptionResponse, with five fields: status, error, message, errorCode and requestUri. The values below are placeholders.
{
"status": 400,
"error": "Bad Request",
"message": "…",
"errorCode": "…",
"requestUri": "/sms/sendSms"
}| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | Bad request: a validation error or a missing required field. |
| 401 | Missing or invalid Bearer token. |
| 403 | The token is valid but not allowed to call this operation. |
| 500 | Unexpected server error. Retry later with backoff. |
Retry only on network errors and 5xx responses, with exponential backoff. Fix 4xx errors instead of retrying them. If your account also binds over SMPP, submissions there return standard SMPP status codes, listed in the SMPP Protocol Guide.
Other messaging channels
The same token and base URL work for every channel. These are the send endpoints; the OpenAPI spec documents their fields and the management endpoints around them (templates, contacts, reports).
| Messaging channel | HTTP method | Endpoint path | Description |
|---|---|---|---|
| SMS | POST | /sms/sendSms | Single message (JSON). |
| SMS | POST | /sms/sendbulk | Bulk from a file (multipart). |
| POST | /whatsapp/message/sendbulk | Text, media, templates, interactive (multipart). | |
| RCS | POST | /rcs/message/sendbulk | RCS messages (multipart). |
| Telegram | POST | /telegram-sms/send | Telegram messages. |
| POST | /email/email-service/send | Email with subject, body and recipients. | |
| Messenger | POST | /messenger/message/sendbulk | Facebook Messenger messages (multipart). |
| POST | /instagram/message/sendbulk | Instagram messages (multipart). | |
| Push | POST | /push/message/send | Push notifications (JSON). |
A WhatsApp template send, for example:
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F campaignName=order-updates \
-F destinationNo=447700900123 \
-F messageType=TEMPLATE \
-F templateName=order_update \
-F templateLanguage=en_US \
-F bodyTemplateVariables=INV-400Set batchId to 0 to start a new batch. The destinationNo field accepts several numbers separated by commas. The response carries the batch ID you use to read the status of each recipient.
TypeScript SDK
BroadNet publishes one official SDK, for TypeScript and Node.js: @broadnet/cpaas-sdk on npm. It is generated from the BroadNet OpenAPI specification, ships CommonJS and ES modules with full type definitions, and has one API class per channel feature. Its one runtime dependency is axios, which npm installs with it.
npm install @broadnet/cpaas-sdk axiosimport { Configuration, WhatsAppWhatsAppMessagingAPIApi } from "@broadnet/cpaas-sdk";
const wa = new WhatsAppWhatsAppMessagingAPIApi(
new Configuration({
basePath: "https://api.broadnet.me",
accessToken: process.env.BROADNET_TOKEN!,
}),
);
const res = await wa.whatsappMessageSendbulkPost({
campaignName: "order-updates",
messageType: "TEXT",
destinationNo: "447700900123",
content: "Your order has shipped.",
});
console.log(res.data); // batchId + per-file acceptance countsFor any other language, call the REST API directly (the Node.js, Python, Java, C#, Go and Ruby examples above use no BroadNet library) or generate a client from the OpenAPI spec.
OpenAPI spec
The full API is described in one OpenAPI 3.1 file: 329 paths and 376 operations across eight channels. This is a public copy of the spec with internal examples removed. Import it into Postman or Insomnia, browse it in Swagger UI, or generate a client.
curl -O https://www.broadnet.me/developers/openapi.yaml
# Generate a client in any language, e.g. Python
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml -g python -o broadnet-pythonPrefer Postman? Import the spec to get every operation, or start with a small collection of the essential calls.
Legacy HTTP API (/websmpp)
Accounts that started on the SMPP-era BroadNet platform may use the legacy HTTP API under the /websmpp path. It is kept running for those existing integrations and is documented in the OpenAPI spec. It takes credentials as request parameters (user and pass, or accesskey) instead of a Bearer token. New integrations should use the REST API described above.
| HTTP method | Endpoint path | Description |
|---|---|---|
| GET | /websmpp/websms | Send an SMS. Add a schedule time and GMT offset to schedule it.user, pass (or accesskey), sid, mno, type, text, schtime, gmt |
| POST | /websmpp/json/sms | Send with a JSON campaign object that carries the credentials, sender, numbers and text.campaign { username, password, sender, gsm, text, type } |
| GET | /websmpp/websmsstatus | Status of a submitted message, by its response ID.respid, format |
| POST | /websmpp/api/dlrreport | Delivery report for a date range, as a spreadsheet.username, pass, from_date, to_date |
| GET | /websmpp/hlr/lookup | HLR lookup for one number.username, password, destination |
# Legacy HTTP API — credentials as query parameters (existing integrations only)
curl "https://api.broadnet.me/websmpp/websms?user=USERNAME&pass=PASSWORD&sid=BroadNet&mno=447700900123&type=1&text=Hello"
# Status of a submitted message
curl "https://api.broadnet.me/websmpp/websmsstatus?respid=MESSAGE_ID&format=json"Frequently asked questions
How do I authenticate?
Send your access token in an Authorization: Bearer header on every request. The token comes from your BroadNet account; there is no token-minting call in the API. A missing or invalid token is rejected at the API gateway with HTTP 401 and a JSON body of two fields, error and message. Keep the token in an environment variable or a secrets manager, never in source control or client-side code.
What is the base URL?
Every sample calls production, https://api.broadnet.me. Test credentials, and where to send test traffic, come with your test access: request it at /signup and we reply within one business day.
How do I send Arabic or other Unicode text?
Set messageType to UNICODE. Use TEXT only when every character is in the GSM-7 alphabet. If you are not sure, call POST /sms/identify with the message: it returns the messageType, character count, number of segments and characters per segment.
What does a successful send return?
POST /sms/sendSms returns HTTP 200 and the message ID as the response body. Bulk sends return a JSON object with status, bulkSessionId, credits, deductcredits and bulkListInfo.
How do I send an SMS to many recipients?
Use POST /sms/sendbulk with a multipart upload: destinationNumberFile is a CSV or TXT file of numbers and bulkRequest is a JSON string with senderId, message, messageType and campaignName. Jobs can then be listed, paused, resumed or aborted by batch ID.
How do I get delivery status?
Delivery status is pushed to the webhook URL configured on your account. For WhatsApp, the status of each recipient can also be read from /whatsapp/message/bulk-insights.
Is there an SDK?
Yes, one: the official TypeScript/Node.js SDK, @broadnet/cpaas-sdk on npm, generated from the BroadNet OpenAPI specification. For any other language, call the REST API directly or generate a client from the OpenAPI 3.1 spec at /developers/openapi.yaml.
What is the /websmpp API?
The legacy HTTP API, kept for existing SMPP-era integrations. It takes credentials as request parameters. New integrations should use the Bearer-token REST API documented on this page.