Skip to content

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.

API Request Structure 📤

Text Message

Text Message Request Example
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
}

Data Message (v1.40.0+)

Data Message Request Example
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
}

Legacy Text Message (Deprecated)

Legacy Message Request Example
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 and validUntil are mutually exclusive
  • Priorities ≥100 bypass all limits/delays
  • Data messages require app v1.40.0+ and server v1.24.0+

Message Processing Stages 🏗️

The steps apply to Cloud and Private modes. For Local mode, server-side step 2 is skipped.

  1. API Submission
    The external app makes a POST request to the /messages endpoint.

  2. Server Processing

    1. Validate payload.
    2. Add message to the queue.
    3. Send a push notification to the device.
    4. Provide messages to the device, sorted by priority and enqueue time.
  3. Device Handling

    1. Receive messages from the server.
    2. Add messages to the local queue with Pending state.
    3. Get messages one by one from the queue, sorted by priority and enqueue time.
    4. Apply limits/delays. Skip this step for messages with priority >= 100.
    5. Send SMS via Android SMS API and set the message status to Processed.
  4. 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:

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, they are processed in LIFO order (Last-In-First-Out)—the newest messages are delivered first.
This ensures immediate delivery for recent recipients and reduces the chance of message expiration during high-traffic periods.

Use Cases

  • High – time-sensitive messages (OTPs, alerts)
  • Normal – routine communications (notifications, reminders)
  • Low – non-urgent bulk traffic (marketing, backups)

See Also 📚