BroadNet
Developer Guide · REST API·OpenAPI 3.1

The BroadNet API.

One REST API for SMS, WhatsApp, RCS, Telegram, email, Messenger, Instagram and push notifications. Every request is sent over HTTPS and authenticated with a Bearer token. Each channel has its own group of paths, and the whole API is described in a downloadable OpenAPI 3.1 spec. This page covers the calls most integrations start with, beginning with a single SMS.

12 min read·Updated September 2026Developer Hub

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.

EnvironmentBase URL
Productionhttps://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.

HTTP
Authorization: Bearer $BROADNET_TOKEN

If 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.

POSThttps://api.broadnet.me/sms/sendSms

Required fields

FieldData typeDescription
senderIdstringYour approved Sender ID, shown to the recipient as the sender.
destinationNumberstringRecipient number with country code, digits only, no plus sign.
messagestringThe message text.
messageTypestringEncoding: TEXT for GSM-7 text, UNICODE for Arabic, emoji and other scripts.

Optional fields

FieldData typeDescription
charCountintegerCharacter count, as returned by /sms/identify.
smsPartsintegerNumber of segments, as returned by /sms/identify.
charLimitintegerCharacters per segment, as returned by /sms/identify.
expiryHourintegerValidity period in hours.
isSchedulebooleanSet to true to schedule the message instead of sending now.
delaynumberDelay before sending.
gmtstringGMT offset used for scheduling.
time—Scheduled send time (with isSchedule).
repeat—Repeat setting for scheduled sends.
peIdstringPrincipal entity ID, where a regulator requires one.
templateIdstringRegistered template ID, where a regulator requires one.
telemarketerIdstringTelemarketer ID, where a regulator requires one.
campaignNamestringYour label for reporting.
curl
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
// 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 ID
Python · requests
import 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
// 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
    }
}
C# · .NET 6+ HttpClient
// .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 ID
Go · net/http
package 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
}
Ruby · Net::HTTP
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
TypeScript SDK · @broadnet/cpaas-sdk
// 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 ID

A successful call returns HTTP 200 and the message ID as the response body, with no JSON envelope:

200 OK
HTTP/1.1 200 OK

2603121407537573731

Encoding & 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.

messageTypeSingle SMSPer segment (long message)Use for
TEXT160153GSM-7 characters only.
UNICODE7067Any 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 · /sms/identify
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" }'
200 OK
{
  "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.

ExampleResultWhy
447700900123ValidCountry code 44 plus the national number, digits only.
+44 7700 900123RejectContains a plus sign and spaces. Strip them first.
07700900123RejectNational 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.

POSThttps://api.broadnet.me/sms/sendbulk
curl · /sms/sendbulk
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"}'
200 OK
{
  "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 methodEndpoint pathDescription
GET/sms/listList 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/resendResend messages from an earlier job.
POST/sms/send-nowRelease a scheduled job immediately.
POST/sms/auto-scheduleSchedule a bulk job automatically.
curl · batch control
# 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.

POSThttps://api.broadnet.me/sms/lookup
curl · /sms/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:

401 Unauthorized
{
  "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.

400 · ExceptionResponse
{
  "status": 400,
  "error": "Bad Request",
  "message": "…",
  "errorCode": "…",
  "requestUri": "/sms/sendSms"
}
StatusMeaning
200Success.
400Bad request: a validation error or a missing required field.
401Missing or invalid Bearer token.
403The token is valid but not allowed to call this operation.
500Unexpected 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 channelHTTP methodEndpoint pathDescription
SMSPOST/sms/sendSmsSingle message (JSON).
SMSPOST/sms/sendbulkBulk from a file (multipart).
WhatsAppPOST/whatsapp/message/sendbulkText, media, templates, interactive (multipart).
RCSPOST/rcs/message/sendbulkRCS messages (multipart).
TelegramPOST/telegram-sms/sendTelegram messages.
EmailPOST/email/email-service/sendEmail with subject, body and recipients.
MessengerPOST/messenger/message/sendbulkFacebook Messenger messages (multipart).
InstagramPOST/instagram/message/sendbulkInstagram messages (multipart).
PushPOST/push/message/sendPush notifications (JSON).

A WhatsApp template send, for example:

curl · /whatsapp/message/sendbulk
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-400

Set 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.

terminal
npm install @broadnet/cpaas-sdk axios
TypeScript · WhatsApp
import { 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 counts

For 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.

terminal
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-python

Prefer 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 methodEndpoint pathDescription
GET/websmpp/websmsSend 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/smsSend with a JSON campaign object that carries the credentials, sender, numbers and text.campaign { username, password, sender, gsm, text, type }
GET/websmpp/websmsstatusStatus of a submitted message, by its response ID.respid, format
POST/websmpp/api/dlrreportDelivery report for a date range, as a spreadsheet.username, pass, from_date, to_date
GET/websmpp/hlr/lookupHLR lookup for one number.username, password, destination
curl · legacy
# 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.

Start sending

Ready to send your first SMS?