Unified Messaging

When you integrate messaging into your application, you typically face a fragmented landscape: one API for SMS, another for WhatsApp, a third for RCS. Each has its own authentication flow, payload format, webhook structure, and delivery logic. Maintaining three parallel integrations means three codebases, three webhook handlers, and three sets of delivery-tracking logic.

EnableX Unified Messaging solves this by providing a single API endpoint that routes your message across SMS, WhatsApp, and RCS. You send one request. EnableX handles channel selection, payload adaptation, fallback orchestration, and unified delivery reporting — all through one integration.

Why Unified Messaging?

Instead of building and maintaining three separate integrations, you write one API call. EnableX takes care of channel selection, message formatting, fallback logic, and delivery tracking across all channels.

Problems It Solves

ChallengeWithout Unified MessagingWith Unified Messaging
Channel coverageIntegrate SMS, WhatsApp, RCS separately — three codebasesOne integration covers all channels
Fallback logicBuild and maintain your own retry/failover codeAutomatic cascade handled by EnableX
Delivery reachLimited by single channel coverage and availabilityMaximise delivery by cascading across channels
Webhook handlingThree webhook handlers, three payload formatsSingle unified webhook for all delivery events
Cost optimisationManual routing decisions per messageBudget-based routing selects cheapest channel first

Channel Comparison

Each messaging channel has different strengths. Unified Messaging lets you leverage the best of all three without separate integrations:

CapabilitySMSWhatsAppRCS
ReachUniversal — every phone2B+ users globallyAndroid (Google Messages)
Rich contentText onlyImages, video, documents, buttonsRich cards, carousels, suggested actions
Templates requiredDLT (India), 10DLC (USA)Yes — Meta approval requiredNo
Read receiptsDelivery onlyDelivered + readDelivered + read
Best forOTPs, alerts, broadest reachRich transactional + marketingRich Android-native experiences

How It Works

Unified Messaging acts as an intelligent routing layer between your application and the individual messaging channels. Here is the end-to-end flow:

Message Flow

  1. You send one API request — POST to /messaging/v1/messages with the recipient number, channel preferences, and channel-specific payloads.
  2. EnableX evaluates channels — Based on your preference mode (order, budget, or priority), EnableX determines which channel to attempt first.
  3. Message is routed — EnableX adapts your payload to the selected channel's format and dispatches the message.
  4. Delivery is attempted — If the first channel succeeds, the cascade stops. If it fails (recipient unreachable on that channel), EnableX automatically falls back to the next channel in the list.
  5. Webhook notifications fire — You receive real-time delivery events (queued, sent, delivered, failed, channel-fallback) at your webhook URL.

Preference Modes

The preference field controls how EnableX orders the channels you provide:

ModeBehaviourWhen to Use
orderChannels are tried in the exact order you specify in the channels arrayWhen you want explicit control over channel priority
budgetChannels are re-ordered by cost — cheapest firstWhen minimising cost is the primary goal
priorityChannels are re-ordered by availability and historical delivery performanceWhen fastest, most reliable delivery matters most
Current Availability

Unified Messaging API v1.0 (released February 2026) supports the order delivery mode. The budget and priority modes will be introduced in subsequent releases.

Cascade Fallback Logic

When you list multiple channels, EnableX orchestrates delivery as a cascade:

  1. The first channel in the resolved order is attempted.
  2. If delivery is confirmed (recipient reachable, message accepted by the channel), the cascade stops.
  3. If the channel fails (recipient not reachable, channel unavailable, or delivery error), EnableX moves to the next channel automatically.
  4. This repeats until the message is delivered or all channels are exhausted.

The cascade decision is based on real-time channel capability detection — not just a timed retry. RCS capability is checked against Google's RCS lookup; WhatsApp reachability is checked via Meta's infrastructure. SMS is universally available and typically serves as the final fallback.

RCS Automatic Degradation

When sending RCS, you can include a fallback_text field in the RCS payload. If the recipient's device is not RCS-capable, EnableX automatically sends this text as an SMS — without needing a separate SMS entry in the channels array. This covers the most common RCS degradation case efficiently.

Quick Start

Get a unified message sent in three steps.

Step 1 — Get Your Credentials

In the EnableX Portal, navigate to My Projects → [Your Project] → Overview and note your App ID and App Key. These are the same credentials used across all EnableX messaging APIs.

Channel Provisioning

Your project must have the messaging channels you intend to use provisioned through the EnableX operations team. SMS, WhatsApp, and RCS each require their own setup (sender IDs, WABA connection, RCS agent registration). Only provisioned channels can be included in the channels array.

Step 2 — Send Your First Unified Message

Send a message that tries WhatsApp first, then falls back to SMS:

curl -X POST https://api.enablex.io/messaging/v1/messages \
  -H "Authorization: Basic BASE64(APP_ID:APP_KEY)" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+919876543210",
  "channels": ["whatsapp", "sms"],
  "preference": "order",
  "whatsapp": {
    "type": "text",
    "recipient_type": "individual",
    "text": {
      "body": "Your order #7821 has shipped. Track at: https://yourapp.com/track/7821"
    }
  },
  "sms": {
    "from": "ENABLEX",
    "data_coding": "plain"
  }
}'

Step 3 — Handle the Response

{
  "code": 200,
  "message": "Message accepted",
  "message_id": "65f1a2b3c4d5e6f7a8b9c0d1"
}

The response confirms acceptance. message_id is your unique identifier — use it to correlate delivery webhooks and poll for status. The actual delivery outcome arrives asynchronously via your webhook URL.

Authentication

The Unified Messaging API uses HTTP Basic Authentication. Every API request must include an Authorization header with your project credentials.

Credentials

Your credentials are available in the EnableX Portal under your project settings:

CredentialRole
APP_IDUsername in HTTP Basic authentication
APP_KEYPassword in HTTP Basic authentication

Authorization Header

Encode APP_ID:APP_KEY as a Base64 string and include it in the header:

POST https://api.enablex.io/messaging/v1/messages
Authorization: Basic BASE64_ENCODED_APP_ID:APP_KEY
Content-Type: application/json
Shared Credentials

The same APP_ID and APP_KEY are used across all EnableX messaging APIs — SMS, WhatsApp, RCS, and Unified Messaging. You do not need separate credentials for each channel.

API Host & Base URL

API Host

https://api.enablex.io/messaging/

Version Base URL

https://api.enablex.io/messaging/v1/

The version number (v1) isolates your integration from breaking changes in future releases. All endpoints documented below are relative to this base URL.

Primary Endpoint

https://api.enablex.io/messaging/v1/messages

This single endpoint handles both sending messages and retrieving delivery status (with GET by appending the message_id).

Send Message API

The Send Message API accepts a single POST request that combines channel preferences, delivery mode, and channel-specific payloads. EnableX routes the message across your chosen channels with automatic failover.

Endpoint

MethodURL
POSThttps://api.enablex.io/messaging/v1/messages

Headers

HeaderValue
AuthorizationBasic BASE64(APP_ID:APP_KEY)
Content-Typeapplication/json

Understanding the Payload Structure

Before looking at the JSON, here is what each part of the payload does:

The Unified Messaging payload has two layers: common fields that apply to every message, and channel-specific objects that define the content for each channel.

FieldPurpose
toRecipient phone number (E.164 format). Only one number per request.
channelsArray of channels in preferred order — determines routing sequence
preferenceRouting mode: order, budget, or priority
whatsappWhatsApp-specific payload (message type, template, text, media)
smsSMS-specific payload (sender ID, encoding, template ID)
rcsRCS-specific payload (agent, message type, rich cards, suggestions)
One Recipient Per Request

The Unified Messaging API accepts exactly one phone number in to. For bulk messaging, call the API once per recipient or use the individual channel APIs which support batch sends.

Basic Payload

{
  "to": "+919876543210",
  "channels": [
    "whatsapp",
    "sms",
    "rcs"
  ],
  "preference": "order",
  "whatsapp": {
    ...
  },
  "sms": {
    ...
  },
  "rcs": {
    ...
  }
}

Complete Payload Reference

ParameterTypeRequiredDescription
toStringYesCountry-code-qualified phone number (E.164). Single recipient only.
channelsArrayYesChannel order: "whatsapp", "sms", "rcs". Minimum 1, maximum 3.
preferenceStringNoorder (default), budget, or priority
whatsappObjectConditionalRequired if whatsapp is in channels. Uses the same payload structure as the WhatsApp Messaging API, except to is omitted (uses top-level to).
smsObjectConditionalRequired if sms is in channels. Uses the same payload as the SMS API, except to, recipient, type, type_details, scheduled_dt, and created_dt are excluded.
rcsObjectConditionalRequired if rcs is in channels. Uses the same payload as the RCS Messaging API, except phone is omitted (uses top-level to).
country_channelsObjectNoCountry-specific channel overrides. Keys are ISO2 country codes (e.g., IN, US).
multi_channel_deliveryBooleanNoDefault: false. Set true to send across all channels simultaneously (no cascade).

Channel-Specific Payload Details

Each channel object follows the same structure as its individual channel API, with a few exclusions to avoid duplication with the top-level fields:

SMS Object

Follows the SMS API payload. Excluded fields: to, recipient, type, type_details, scheduled_dt, created_dt. Scheduling is not available through Unified Messaging.

{
  "sms": {
    "from": "ENABLEX",
    "data_coding": "plain",
    "template_id": "12345"
  }
}

WhatsApp Object

Follows the WhatsApp Messaging API payload. Excluded fields: to (uses top-level to). Supports template messages, session text, media, and interactive messages.

{
  "whatsapp": {
    "type": "template",
    "template": {
      "name": "order_shipped",
      "language": "en",
      "components": [
        {
          "type": "body",
          "parameters": [
            {
              "type": "text",
              "text": "7821"
            }
          ]
        }
      ]
    }
  }
}

RCS Object

Follows the RCS Messaging API payload. Excluded fields: phone (uses top-level to). Supports text, rich cards, carousels, and suggested actions.

{
  "rcs": {
    "type": "text",
    "agent": "MY_RCS_AGENT",
    "text": "Your order #7821 has shipped.",
    "fallback_text": "Your order #7821 has shipped. Track: https://yourapp.com/track/7821",
    "ttl": 60
  }
}

Send Variations

The Unified Messaging API supports several send modes beyond the basic cascade.

Unified Text Message

When you want to send the same plain text content across all channels (no rich media, no templates), use the unified object instead of providing separate payloads for each channel. This is the simplest possible unified send.

When Unified Text Works

Unified text works for WhatsApp and RCS session messaging (plain text, no templates or rich content). For SMS, it works only if the destination country does not require a registered template or if the text matches an approved template.

{
  "to": "+919876543210",
  "channels": ["whatsapp", "sms", "rcs"],
  "preference": "order",
  "unified": {
    "body": "Your appointment is confirmed for Monday at 10:30 AM."
  },
  "rcs": {
    "agent": "MY_RCS_AGENT"
  },
  "sms": {
    "from": "CLINICX"
  }
}

The unified.body field sets the text content for all channels. Channel-specific objects (rcs, sms) are still needed for required fields like agent name and sender ID, but you do not need to repeat the message body.

Country-Specific Channel Preferences

Different countries have different channel availability and regulatory requirements. The country_channels object lets you define per-country channel preferences that override the global channels array.

{
  "to": "+919876543210",
  "channels": ["whatsapp", "sms", "rcs"],
  "country_channels": {
    "IN": ["sms", "whatsapp"],
    "US": ["rcs", "sms"]
  },
  "preference": "order",
  "whatsapp": { ... },
  "sms": { ... },
  "rcs": { ... }
}

How it works: EnableX detects the country from the to phone number. If the number matches a country in country_channels, that country's channel array is used. Otherwise, the global channels array applies. The preference mode applies to both global and country-specific arrays.

Parallel Delivery (All Channels Simultaneously)

By default, Unified Messaging uses cascade delivery — try one channel, fall back to the next. If you want the message delivered across all channels at the same time (no failover, just broadcast), set multi_channel_delivery to true.

{
  "to": "+919876543210",
  "channels": ["whatsapp", "sms", "rcs"],
  "multi_channel_delivery": true,
  "whatsapp": { ... },
  "sms": { ... },
  "rcs": { ... }
}
Parallel Mode Behaviour

When multi_channel_delivery is true, the preference mode and channel order have no effect — the message is dispatched to all listed channels simultaneously. You will receive separate delivery webhooks for each channel.

Complete Request Example

This example sends a message that tries WhatsApp first (with a template), then SMS (with sender ID), then RCS (with a rich text and fallback). The preference is order, so channels are tried in the sequence listed:

POST https://api.enablex.io/messaging/v1/messages
Authorization: Basic BASE64(APP_ID:APP_KEY)
Content-Type: application/json

{
  "to": "+919876543210",
  "channels": [
    "whatsapp",
    "sms",
    "rcs"
  ],
  "preference": "order",
  "whatsapp": {
    "type": "text",
    "recipient_type": "individual",
    "text": {
      "body": "Hi there! Your verification code is 847291."
    }
  },
  "sms": {
    "from": "ENABLX",
    "data_coding": "plain",
    "template_id": "99999"
  },
  "rcs": {
    "type": "text",
    "agent": "MY_AGENT",
    "text": "Hi there! Your verification code is 847291.",
    "fallback_text": "Hi there! Your verification code is 847291.",
    "ttl": 60
  }
}

Success Response

{
  "code": 200,
  "message": "Message accepted",
  "message_id": "65f1a2b3c4d5e6f7a8b9c0d1"
}
FieldTypeDescription
codeNumber200 indicates the message was accepted for processing
messageStringHuman-readable status — "Message accepted"
message_idStringUnique identifier. Use this to poll delivery status and correlate webhook events.
Accepted ≠ Delivered

A 200 response means EnableX has accepted the message for processing. Actual delivery status is reported asynchronously through webhooks or the delivery status API. Always implement webhook handling for reliable delivery tracking.

Channel Routing

Understanding how EnableX selects and routes channels is critical for designing your messaging strategy.

How Channel Selection Works

  1. Channel list resolved — EnableX checks if the to number matches any country in country_channels. If yes, that country's channel array is used. Otherwise, the global channels array applies.
  2. Preference mode applied — If preference is order, the array order is preserved. If budget or priority, EnableX re-orders channels by cost or performance.
  3. Capability check — For the first channel in the resolved order, EnableX performs a real-time capability check:
    • RCS: Checks Google's RCS capability lookup for the recipient's device
    • WhatsApp: Checks recipient reachability via Meta's infrastructure
    • SMS: Universally available — no capability check needed
  4. Dispatch or fallback — If the recipient is reachable on the selected channel, the message is dispatched. If not, EnableX moves to the next channel in the list.

Routing Examples

ScenarioChannelsOutcome
Recipient has WhatsApp["whatsapp", "sms"]Delivered via WhatsApp; SMS not attempted
Recipient does not have WhatsApp["whatsapp", "sms"]WhatsApp fails → SMS fallback delivers
Recipient has RCS-capable device["rcs", "whatsapp", "sms"]Delivered via RCS; others not attempted
Indian number, country overridechannels: ["rcs", "sms"], country_channels.IN: ["sms"]Only SMS attempted (country override takes effect)
Parallel mode["whatsapp", "sms"], multi_channel_delivery: trueBoth WhatsApp and SMS sent simultaneously

Delivery Status API

Poll for the current delivery status of any message using its message_id.

Endpoint

MethodURL
GEThttps://api.enablex.io/messaging/v1/messages/{message_id}

Request

GET https://api.enablex.io/messaging/v1/messages/65f1a2b3c4d5e6f7a8b9c0d1
Authorization: Basic BASE64(APP_ID:APP_KEY)
Content-Type: application/json

Response

The response includes the overall delivery status and per-channel status objects for every channel that was attempted:

{
  "code": 200,
  "message_id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "to": "+919876543210",
  "channels": ["whatsapp", "sms", "rcs"],
  "preference": "order",
  "delivery": {
    "status": "DELIVERED",
    "channel": "whatsapp",
    "whatsapp": {
      "message_id": "wamid_abc123",
      "status": "DELIVERED",
      "queued": "2026-04-09T10:00:00Z",
      "sent": "2026-04-09T10:00:01Z",
      "delivered": "2026-04-09T10:00:03Z",
      "business_phone": "+6531234567"
    }
  }
}

Delivery Status Values

StatusDescription
PENDINGMessage accepted, not yet queued on any channel
QUEUEDMessage queued for delivery on a channel
SENTMessage sent to the channel provider
DELIVEREDMessage confirmed delivered to the recipient
FAILEDDelivery failed on the current channel (may cascade to next)
Polling vs Webhooks

While the delivery status API is useful for on-demand checks, webhooks provide real-time notifications as delivery events occur. Configure a webhook URL in your project settings for production use. See Unified Messaging Webhooks for setup and payload details.

Per-Channel Status Objects

The delivery object contains a sub-object for each channel that was attempted. Each sub-object includes channel-specific fields:

ChannelKey Fields
SMSmessage_id, status, queued, sent, delivered, sender, failure_reason
WhatsAppmessage_id, recipient_id, status, queued, sent, delivered, business_phone, conversation
RCSevent_type, message_id, message_status, queued, sent, delivered, agent, failure_reason

Error Codes

CodeHTTPDescription
INVALID_NUMBER400to is not a valid E.164 phone number
SENDER_NOT_APPROVED403Sender ID not approved for the target country
TEMPLATE_NOT_APPROVED403WhatsApp template not yet approved by Meta
WABA_NOT_CONNECTED403WhatsApp Business Account not connected to this project
RCS_AGENT_NOT_REGISTERED403RCS business agent not registered with Google
INSUFFICIENT_BALANCE402Account balance too low for the requested send
RATE_LIMIT_EXCEEDED429Request rate limit exceeded — retry with exponential backoff
CHANNEL_UNAVAILABLE503Requested channel temporarily unavailable
ALL_CHANNELS_FAILEDWebhook event — all channels in the cascade exhausted without delivery

API Quick Reference

OperationMethodEndpoint
Send Unified MessagePOST/messaging/v1/messages
Get Delivery StatusGET/messaging/v1/messages/{message_id}
Send SMS (direct)POST/sms/v1/messages
Send WhatsApp (direct)POST/whatsapp/v1/messages
Send RCS (direct)POST/rcs/v1/messages

Best Practices

Design Your Channel Order Thoughtfully

Place the richest channel first (RCS or WhatsApp) and SMS last. Rich channels provide better user experience (read receipts, interactive elements), while SMS serves as the universal safety net. A common cascade is: ["rcs", "whatsapp", "sms"].

Always Include Fallback Text for RCS

When sending RCS rich content, include the fallback_text field. This ensures non-RCS devices receive an SMS equivalent automatically, without needing a separate SMS entry in the cascade.

Implement Webhooks for Production

The delivery status API is useful for testing and ad-hoc checks, but always configure a webhook URL for production. Webhooks provide real-time delivery updates without polling overhead.

Store the message_id

Map the message_id from the API response to your internal transaction or order ID. This is your primary key for correlating all delivery events back to the original send.

Use Country-Specific Routing for Regulated Markets

Markets like India (DLT requirements) and the US (10DLC) have channel-specific regulations. Use country_channels to route regulated markets through compliant channels while keeping the richer cascade for other regions.

Use Parallel Mode Sparingly

Parallel delivery (multi_channel_delivery: true) sends across all channels simultaneously. This maximises reach but also maximises cost. Use it only for critical alerts where delivery speed is paramount.

Release Notes

v1.0 — February 24, 2026

Initial release of the Unified Messaging API with support for SMS, WhatsApp, and RCS channels. Delivery mode: order (channels tried in the sequence provided). The budget and priority delivery modes will be introduced in subsequent releases.

What's Next

  • Unified Messaging Webhooks — Webhook setup, delivery notification payloads, and handler examples
  • SMS Guide — Sender IDs, DLT registration, campaign setup, delivery receipts
  • WhatsApp Guide — Template management, interactive messages, media, session messaging
  • RCS Guide — Rich cards, carousels, suggested actions, capability check
  • Messaging Prerequisites — WABA setup, RCS agent registration, sender ID provisioning