All API resources
Message classification (AI)
Open Text Shield, the TelecomsXchange SMS classifiers, served from their own host. The threat classifier labels a message as ham, spam or phishing; the category classifier labels what kind of message it is.
Check message safety
POST/predict
Classifies one SMS text as ham, spam or phishing. The text is normalised first, so full-width, look-alike and leetspeak disguises (for example paypa1) are classified as the text they imitate. Returns the label, probability (the model's confidence in that label, 0 to 1), processing_time (server-side seconds) and model_info. Free, and needs no credentials.
Parameters
textstringJSONRequiredThe message to classify, 1 to 512 characters.
modelstringJSONRequiredModel to run. Use
ots-mbert.
Errors
| Message | When |
|---|---|
"String should have at least 1 character" | text is empty (HTTP 422, in detail[].msg). |
curl -X POST \
"https://ots.telecomsxchange.com/predict" \
-H 'Content-Type: application/json' \
-d '{"text": "Your account has been suspended. Verify now at http://secure-login-check.example", "model": "ots-mbert"}'import os
import requests
resp = requests.post(
"https://ots.telecomsxchange.com/predict",
json={"text": "Your account has been suspended. Verify now at http://secure-login-check.example", "model": "ots-mbert"},
)
print(resp.json())$ch = curl_init("https://ots.telecomsxchange.com/predict");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode(['text' => "Your account has been suspended. Verify now at http://secure-login-check.example", 'model' => "ots-mbert"]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);{
"label": "phishing",
"probability": 0.9997455477714539,
"processing_time": 0.1476691383868456,
"model_info": {
"name": "OTS_mBERT",
"version": "2.9",
"architecture": "bert-base-multilingual-cased",
"author": "TelecomsXChange (TCXC)",
"last_training": "2024-03-20"
}
}{
"label": "ham",
"probability": 0.9994045495986938,
"processing_time": 0.155810184776783,
"model_info": {
"name": "OTS_mBERT",
"version": "2.9",
"architecture": "bert-base-multilingual-cased",
"author": "TelecomsXChange (TCXC)",
"last_training": "2024-03-20"
}
}{
"detail": [
{
"type": "string_too_short",
"loc": [
"body",
"text"
],
"msg": "String should have at least 1 character",
"input": "",
"ctx": {
"min_length": 1
}
}
]
}Threat classifier health
GET/health
Returns the threat classifier's status, API version and loaded model version. Suitable as a load-balancer health check. Free, and needs no credentials.
Parameters
No parameters.
curl -X GET \
"https://ots.telecomsxchange.com/health"import os
import requests
resp = requests.get(
"https://ots.telecomsxchange.com/health",
)
print(resp.json())$ch = curl_init("https://ots.telecomsxchange.com/health");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);{
"status": "healthy",
"api_version": "2.11.0",
"version": "2.11.0",
"model": {
"name": "OTS_mBERT",
"version": "2.9",
"architecture": "bert-base-multilingual-cased"
},
"models_loaded": {
"mbert_multilingual": true
},
"timestamp": "2026-10-15T20:22:02.957002+00:00"
}Classify message category
POST/cc/v1/classify
Sorts one SMS text into a category: verification (one-time codes, 2FA and login codes, verification links, "confirm it's you" prompts), marketing (promotions, sales, loyalty pushes, launches, re-engagement, referral offers) or transactional (order, delivery, payment, booking, balance, reminder and account-event notifications). Returns the label, its confidence, all three scores (they sum to 1) and ms, the server-side model time in milliseconds. Free, and needs no credentials.
Parameters
textstringJSONRequiredThe message to classify, 1 to 2,000 characters.
Errors
| Message | When |
|---|---|
"String should have at least 1 character" | text is empty (HTTP 422, in detail[].msg). |
curl -X POST \
"https://ots.telecomsxchange.com/cc/v1/classify" \
-H 'Content-Type: application/json' \
-d '{"text": "Your verification code is 482913. It expires in 10 minutes."}'import os
import requests
resp = requests.post(
"https://ots.telecomsxchange.com/cc/v1/classify",
json={"text": "Your verification code is 482913. It expires in 10 minutes."},
)
print(resp.json())$ch = curl_init("https://ots.telecomsxchange.com/cc/v1/classify");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode(['text' => "Your verification code is 482913. It expires in 10 minutes."]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);{
"label": "verification",
"confidence": 0.9662,
"scores": {
"verification": 0.9662,
"marketing": 0.0162,
"transactional": 0.0176
},
"ms": 16.82
}{
"label": "verification",
"confidence": 0.9649,
"scores": {
"verification": 0.9649,
"marketing": 0.0162,
"transactional": 0.0189
},
"ms": 20.97
}{
"detail": [
{
"type": "string_too_short",
"loc": [
"body",
"text"
],
"msg": "String should have at least 1 character",
"input": "",
"ctx": {
"min_length": 1
}
}
]
}Classify message categories in bulk
POST/cc/v1/classify/batch
Classifies up to 256 SMS texts in one request. results is in the same order as texts; each result has the same fields as the single-message call except that its ms is null, and the top-level ms is the model time for the whole batch. count is the number of messages classified. Free, and needs no credentials.
Parameters
textsarrayJSONRequiredMessages to classify: up to 256 strings, each 1 to 2,000 characters.
curl -X POST \
"https://ots.telecomsxchange.com/cc/v1/classify/batch" \
-H 'Content-Type: application/json' \
-d '{"texts": ["50% off everything this weekend", "Your parcel has been delivered"]}'import os
import requests
resp = requests.post(
"https://ots.telecomsxchange.com/cc/v1/classify/batch",
json={"texts": ["50% off everything this weekend", "Your parcel has been delivered"]},
)
print(resp.json())$ch = curl_init("https://ots.telecomsxchange.com/cc/v1/classify/batch");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode(['texts' => ["50% off everything this weekend", "Your parcel has been delivered"]]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);{
"results": [
{
"label": "marketing",
"confidence": 0.9383,
"scores": {
"verification": 0.0276,
"marketing": 0.9383,
"transactional": 0.0341
},
"ms": null
},
{
"label": "transactional",
"confidence": 0.9722,
"scores": {
"verification": 0.0146,
"marketing": 0.0132,
"transactional": 0.9722
},
"ms": null
}
],
"count": 2,
"ms": 19.15
}List categories
GET/cc/v1/labels
Returns the three labels the category classifier can return and the definition of each. Free, and needs no credentials.
Parameters
No parameters.
curl -X GET \
"https://ots.telecomsxchange.com/cc/v1/labels"import os
import requests
resp = requests.get(
"https://ots.telecomsxchange.com/cc/v1/labels",
)
print(resp.json())$ch = curl_init("https://ots.telecomsxchange.com/cc/v1/labels");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);{
"labels": [
"verification",
"marketing",
"transactional"
],
"definitions": {
"verification": "One-time codes, 2FA/login codes, verification links, 'confirm it's you' prompts.",
"marketing": "Promotions, offers, sales, loyalty pushes, product launches, re-engagement, surveys-for-rewards.",
"transactional": "Order, delivery, payment, booking, balance, reminder and account-event notifications triggered by something the user did or holds."
}
}Category classifier health
GET/cc/health
Returns the category classifier's status, service and model versions, supported languages and labels, uptime, and whether an API key is required. Suitable as a load-balancer health check. Free, and needs no credentials.
Parameters
No parameters.
curl -X GET \
"https://ots.telecomsxchange.com/cc/health"import os
import requests
resp = requests.get(
"https://ots.telecomsxchange.com/cc/health",
)
print(resp.json())$ch = curl_init("https://ots.telecomsxchange.com/cc/health");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);{
"status": "ok",
"service": "ots-cc",
"name": "Open Text Shield Category Classifier",
"version": "0.2.2",
"model_name": "OTS Category Classifier",
"model_version": "v8",
"model_base": "mmBERT small",
"languages": [
"en",
"es",
"id",
"… 6 more items"
],
"model": "model_int8.onnx",
"base": "jhu-clsp/mmBERT-small",
"labels": [
"verification",
"marketing",
"transactional"
],
"api_key_required": false,
"uptime_s": 221088.3
}