Sending Messages 🚀
The Sending Messages feature provides a comprehensive API for delivering both traditional text messages and binary data messages via SMS. This guide covers the API structure, request parameters, message processing flow, and best practices for reliable message delivery across different scenarios and priorities.
Message Types 📱
-
Text Messages
- Standard SMS text content
- Auto-split for messages >160 chars
- Supports Unicode characters
-
Data Messages
- Binary data transmission
- Base64 encoded content
- Port-based delivery
API Request Structure 📤
POST /3rdparty/v1/messages?skipPhoneValidation=true&deviceActiveWithin=12
Content-Type: application/json
Authorization: Basic <credentials>
{
"textMessage": {
"text": "Your OTP is 1234"
},
"deviceId": "yVULogr4Y1ksRfnos1Dsw",
"phoneNumbers": ["+1234567890"],
"simNumber": 1,
"ttl": 3600,
"priority": 100
}
POST /3rdparty/v1/messages?skipPhoneValidation=true&deviceActiveWithin=12
Content-Type: application/json
Authorization: Basic <credentials>
{
"dataMessage": {
"data": "SGVsbG8gRGF0YSBXb3JsZCE=",
"port": 53739
},
"phoneNumbers": ["+1234567890"],
"simNumber": 1,
"ttl": 3600,
"priority": 100
}
POST /3rdparty/v1/messages
Content-Type: application/json
Authorization: Basic <credentials>
{
"id": "custom-id-123",
"message": "Your OTP is 1234",
"phoneNumbers": ["+1234567890"],
"simNumber": 1,
"ttl": 3600,
"withDeliveryReport": true,
"priority": 100,
"isEncrypted": false
}
Query Parameters
Parameter | Type | Description | Default | Example |
---|---|---|---|---|
skipPhoneValidation | boolean | Disable E.164 phone-number validation | false | true |
deviceActiveWithin | integer | Only target devices active within the last N hours (0 = off) | 0 | 12 |
Request Fields
Parameter | Type | Description | Default | Example |
---|---|---|---|---|
id | string | Optional unique message ID | auto-generated | "order-1234" |
deviceId | string | Device ID | null | "dev_abc123" |
textMessage | object | Text message content | null | { "text": "Hello" } |
textMessage.text | string | Text content (auto-split if >160 chars) | required | "Hello World" |
dataMessage | object | Data message content | null | { "data": "SGVsbG8=", "port": 53739 } |
dataMessage.data | string | Base64-encoded data | required | "SGVsbG8=" |
dataMessage.port | integer | Destination port (0-65535) | required | 53739 |
message | string | ⚠️ Deprecated: Use textMessage.text instead | null | "Hello World" |
phoneNumbers | array | Recipient numbers | required | ["+1234567890"] |
simNumber | integer | SIM card selection (1-3) | see here | 1 |
ttl /validUntil | integer/RFC3339 | Message expiration (mutually exclusive) | never | 3600 or "2024-12-31T23:59:59Z" |
withDeliveryReport | boolean | Delivery confirmation | true | true |
priority | integer (-128-127) | Send priority (-128 to 127) | 0 | 100 |
isEncrypted | boolean | Message is encrypted | false | true |
Mutual Exclusivity
Only one of textMessage
, dataMessage
, or the deprecated message
field may be specified per request
Additional Notes
- Phone numbers must be E.164-compatible—except when the message is encrypted or
skipPhoneValidation=true
ttl
andvalidUntil
are mutually exclusive- Priorities ≥100 bypass all limits/delays
- Data messages require app v1.40.0+ and server v1.24.0+
Code Examples 💻
Text Message
Send Your OTP is 1234
to +1234567890
without phone number validation via device with ID yVULogr4Y1ksRfnos1Dsw
if it was active within the last 12 hours. Skip phone number validation and expire the message after 1 hour. Use SIM card slot #1 and set priority to 100 to bypass all limits/delays.
curl -X POST "https://api.sms-gate.app/3rdparty/v1/messages?skipPhoneValidation=true&deviceActiveWithin=12" \
-u "username:password" \
--json '{
"textMessage": {
"text": "Your OTP is 1234"
},
"deviceId": "yVULogr4Y1ksRfnos1Dsw",
"phoneNumbers": ["+1234567890"],
"simNumber": 1,
"ttl": 3600,
"priority": 100
}'
import requests
from requests.auth import HTTPBasicAuth
url = "https://api.sms-gate.app/3rdparty/v1/messages"
params = {"skipPhoneValidation": True, "deviceActiveWithin": 12}
payload = {
"textMessage": {"text": "Your OTP is 1234"},
"deviceId": "yVULogr4Y1ksRfnos1Dsw",
"phoneNumbers": ["+1234567890"],
"simNumber": 1,
"ttl": 3600,
"priority": 100,
}
headers = {
"Content-Type": "application/json",
}
response = requests.post(
url,
params=params,
json=payload,
headers=headers,
auth=HTTPBasicAuth("username", "password"),
)
print(response.json())
const axios = require('axios');
const url = 'https://api.sms-gate.app/3rdparty/v1/messages';
const params = {
skipPhoneValidation: true,
deviceActiveWithin: 12
};
const payload = {
textMessage: {
text: 'Your OTP is 1234'
},
deviceId: 'yVULogr4Y1ksRfnos1Dsw',
phoneNumbers: ['+1234567890'],
simNumber: 1,
ttl: 3600,
priority: 100
};
const headers = {
'Content-Type': 'application/json',
};
axios.post(url, payload, {
params,
headers,
auth: { username: 'username', password: 'password' }
})
Data Message
Send SGVsbG8gRGF0YSBXb3JsZCE=
(base64-encoded Hello Data World!
) to +1234567890
without phone number validation and expire the message after 1 hour. Use SIM card slot #1 and set priority to 100 to bypass all limits/delays.
curl -X POST "https://api.sms-gate.app/3rdparty/v1/messages?skipPhoneValidation=true&deviceActiveWithin=12" \
-u "username:password" \
--json '{
"dataMessage": {
"data": "SGVsbG8gRGF0YSBXb3JsZCE=",
"port": 53739
},
"phoneNumbers": ["+1234567890"],
"simNumber": 1,
"ttl": 3600,
"priority": 100
}'
import requests
from requests.auth import HTTPBasicAuth
url = "https://api.sms-gate.app/3rdparty/v1/messages"
params = {"skipPhoneValidation": True, "deviceActiveWithin": 12}
# Sample data: "Hello Data World!" encoded as base64
message_data = "SGVsbG8gRGF0YSBXb3JsZCE="
payload = {
"dataMessage": {"data": message_data, "port": 53739},
"phoneNumbers": ["+1234567890"],
"simNumber": 1,
"ttl": 3600,
"priority": 100,
}
headers = {
"Content-Type": "application/json",
}
response = requests.post(
url,
params=params,
json=payload,
headers=headers,
auth=HTTPBasicAuth("username", "password"),
)
print(response.json())
const axios = require('axios');
const url = 'https://api.sms-gate.app/3rdparty/v1/messages';
const params = {
skipPhoneValidation: true,
deviceActiveWithin: 12
};
// Sample data: "Hello Data World!" encoded as base64
const messageData = 'SGVsbG8gRGF0YSBXb3JsZCE=';
const payload = {
dataMessage: {
data: messageData,
port: 53739
},
phoneNumbers: ['+1234567890'],
simNumber: 1,
ttl: 3600,
priority: 100
};
const headers = {
'Content-Type': 'application/json',
};
axios.post(url, payload, {
params,
headers,
auth: { username: 'username', password: 'password' }
})
Message Processing Stages 🏗️
The steps apply to Cloud and Private modes. For Local mode, server-side step 2 is skipped.
-
API Submission
The external app makes aPOST
request to the/messages
endpoint. -
Server Processing
- Validate payload.
- Add message to the queue.
- Send a push notification to the device.
- Provide messages to the device, sorted by priority, then by enqueue time (descending by default for LIFO; ascending if FIFO is configured).
-
Device Handling
- Receive messages from the server.
- Add messages to the local queue with
Pending
state. - Get messages one by one from the queue, sorted by priority, then by enqueue time (descending by default for LIFO; ascending if FIFO is configured).
- Apply limits/delays. Skip this step for messages with priority >= 100.
- Send SMS via Android SMS API and set the message status to
Processed
.
-
Status Tracking
Refer to the Status Tracking guide to monitor the message status.
Best Practices
- Batch Sending:
- Split large batches into small groups
- Add delays between batches
- Use priority ≥100 to bypass rate limits
- Message Handling:
- Use unique IDs for idempotency
- Always set TTL values
- Implement exponential backoff for retries
- Monitoring:
- Use webhooks for real-time status updates
- Monitor for
RESULT_ERROR_LIMIT_EXCEEDED
errors
Message Priority ⚡
Control message processing order using the priority
field. Higher priority messages are processed first.
Level | Range | Description |
---|---|---|
High | 100 to 127 | Highest priority, bypasses rate limits |
Normal | 0 to 99 | Standard processing (default) |
Low | -128 to -1 | Low priority |
Equal Priority Handling
When messages share the same priority
value, the processing order can be configured. By default, messages are processed in LIFO order (Last-In-First-Out), but FIFO order (First-In-First-Out) can be chosen in the application settings.
Use Cases
- High – time-sensitive messages (OTPs, alerts)
- Normal – routine communications (notifications, reminders)
- Low – non-urgent bulk traffic (marketing, backups)
See Also 📚
- Status Tracking - Monitor message delivery status
- Data SMS Support - Sending binary data via SMS
- Message Encryption - Securing message content
- Multi-SIM Support - Managing multiple SIM cards
- API Documentation - Complete API reference