RCS Business Messaging API

The EnableX RCS Business Messaging (RBM) API lets you send rich, interactive messages to users through their native Android messaging app. Unlike SMS — which is limited to plain text — RCS supports rich cards with images and video, carousels for product browsing, and interactive suggestions that let users tap to reply, open a URL, dial a phone number, share a location, or create a calendar event.

RCS messages are delivered through the user's default messaging app on Android devices. There is no separate app to install — the experience is native and seamless. Your business appears as a verified RBM Agent with a branded identity (name, logo, description) that the user sees in the conversation thread.

Important: Every RCS API call requires authentication. You must include either HTTP Basic credentials or a Bearer Token in the Authorization header. See the Authentication section below before making any API calls.

▶  Run in Postman Collection last updated Aug 12, 2024

When to Use RCS vs. SMS vs. WhatsApp

RCS, SMS, and WhatsApp each serve different messaging scenarios. Understanding when to use each channel helps you design the right communication strategy.

CapabilitySMSRCSWhatsApp
Rich media (images, video)NoYesYes
Interactive buttons / suggestionsNoYes (6 types)Yes (buttons, lists)
CarouselsNoYes (2–10 cards)No
Requires separate app installNoNo (native Android)Yes
Delivery receiptsLimitedYes (SENT → DELIVERED → READ)Yes
Template approval requiredDLT (India)RBM (India only)Meta (global)
Fallback mechanismNativeSMS fallback textN/A
Tip: RCS is ideal when you need rich, interactive messaging on Android without requiring users to install a separate app. Use the fallback_text parameter in every RCS API call to ensure users on non-RCS devices still receive your message as SMS.

The RBM Agent Concept

In RCS, your business communicates through an RBM Agent — a verified identity registered with Google's RCS Business Messaging platform. The agent has a name, logo, description, and contact information that appear in the user's messaging app.

Every API call you make includes an agent parameter — this is the name of your registered RBM Agent. EnableX provisions and manages the agent registration on your behalf. You reference the agent name when sending messages, creating templates, and processing webhooks.

Base URL

All RCS API endpoints use the following base URL:

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

All API routes documented on this page are relative to this base URL. For example, the messaging endpoint is https://api.enablex.io/rcs/v1/messages.

Authentication

EnableX supports two authentication mechanisms for the RCS API. You can use either one — choose based on your architecture.

HTTP Basic Authentication

Each EnableX RCS project is assigned an APP ID and APP Key. These credentials are used for HTTP Basic Authentication:

How it works: Create a base64-encoded string of APP_ID:APP_KEY (note the colon separator) and pass it in the Authorization header.

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

Bearer Token Authentication

If you prefer token-based auth, you can generate a Bearer Token that is valid for 60 minutes. During this window, use the token for any number of API calls. When it expires, generate a new one.

Step 1 — Request a token by calling the Token API with your project credentials:

POST https://api.enablex.io/rcs/v1/token
Content-Type: application/json
{
  "app_id": "your-app-id",
  "app_key": "your-app-key"
}

Step 2 — Receive the token with its expiry timestamp:

{
  "code": 200,
  "token": "eyJhbGciOiJIUz...",
  "expiry": 1719212536
}
KeyTypeDescription
tokenStringBearer token for subsequent API calls
expiryNumberUnix timestamp (UTC) when the token expires

Step 3 — Use the token in the Authorization header:

POST https://api.enablex.io/rcs/v1/messages
Authorization: Bearer eyJhbGciOiJIUz...
Content-Type: application/json
Important: Track the expiry value and regenerate a new token before it expires. If you call any API with an expired token, you will receive error code 1002 — "Invalid/Expired Token used."

Authentication Error Responses

If authentication fails — whether due to invalid credentials or an expired token — the API returns:

{
  "message": "Authentication failed",
  "status": "Unauthorized",
  "reason": "Invalid credentials or the account has been deactivated"
}

Core Messaging Flow

The RCS messaging lifecycle follows this pattern:

1. Business sends a message → The API accepts the request and returns a message_id.
2. RBM delivers the message → Delivery status updates (SENT, DELIVERED, READ, FAILED) are posted to your webhook.
3. User interacts → If the message includes suggestions, user taps are posted to your webhook as incoming events.
4. User replies → Free-form text, files, or location shares arrive on your webhook as incoming messages.

Note: Every webhook notification must be acknowledged with an HTTP 200 response. See RCS Webhooks for complete payload details.

Template System (India Requirement)

The RCS platform mandates that businesses in India must use a pre-approved message template to initiate conversations. Once a user responds, a 24-hour session window opens, and the business can send any message type without a template.

Outside India, there is no template requirement — you can send any message type at any time.

Template Messages vs. Session Messages

ScenarioMessage TypeAPI Endpoint
Initiating conversation (India)Template MessagePOST /rcs/v1/messages/templates
Initiating conversation (outside India)Any message typePOST /rcs/v1/messages
Within 24-hour session windowAny message typePOST /rcs/v1/messages
Important: Template creation and template sending use different API endpoints. You create templates via POST /rcs/v1/templates. You send a message using a template via POST /rcs/v1/messages/templates.

Template Types

Templates can be created for three content types:

TypeDescription
textPlain text message with optional suggestions
cardRich card with media, title, description, and suggestions
carouselCarousel of 2–10 rich cards

Placeholders in Templates

Text templates can include dynamic placeholders that are replaced with actual values when the message is sent. Placeholders use square bracket syntax — for example:

Hi [name], your order [order_id] has been shipped to [location].

Variable naming rules: must start with a letter, can contain alphanumeric characters and underscores, are case-sensitive, and cannot contain spaces or special characters.

Note: RCS uses [variable] square bracket placeholders — not the {{variable}} curly brace syntax used by WhatsApp. Ensure your integration uses the correct format.

Creating a Template

Submit a template for RBM approval. Templates are typically reviewed and approved within minutes to 24 hours.

POST https://api.enablex.io/rcs/v1/templates
Authorization: Bearer {token}
Content-Type: application/json

Text Template with Placeholders

This example creates a text template named order_update with two placeholder variables:

{
  "name": "order_update",
  "type": "text",
  "text": "Hi [name], your order [order_id] is out for delivery.",
  "suggestions": [
    {
      "type": "reply",
      "text": "Track Order",
      "postback": "track_order"
    }
  ],
  "templateDetails": {
    "username": "your-account-username",
    "agent": "your-agent-name",
    "variables": [
      "name",
      "order_id"
    ],
    "category": "text"
  }
}

The templateDetails object provides metadata required by RBM for the approval process:

KeyTypeRequiredDescription
usernameStringYesYour account username
agentStringYesRBM Agent name
variablesArrayConditionalList of placeholder variable names used in the text. Required if the text contains [variable] placeholders
categoryStringYesMust match the type field: text, card, or carousel

Success Response:

{
  "code": 200,
  "message": "Template request has been created",
  "data": { }
}

Rich Card Template

To create a template with a rich card (image/video + text + suggestions):

{
  "name": "product_promo",
  "type": "card",
  "card": {
    "title": "Summer Sale",
    "description": "Up to 50% off on selected items",
    "url": "https://example.com/promo-banner.jpg",
    "suggestions": [
      {
        "type": "open_url",
        "text": "Shop Now",
        "url": "https://example.com/sale",
        "postback": "shop_summer_sale"
      }
    ]
  },
  "templateDetails": {
    "username": "your-account-username",
    "agent": "your-agent-name",
    "category": "card"
  }
}

Carousel Template

To create a template with a carousel of multiple rich cards:

{
  "name": "product_catalog",
  "type": "carousel",
  "carousel": [
    {
      "title": "Product A",
      "description": "Premium quality widget",
      "url": "https://example.com/product-a.jpg",
      "suggestions": [
        {
          "type": "open_url",
          "text": "View Details",
          "url": "https://example.com/product-a",
          "postback": "view_product_a"
        }
      ]
    },
    {
      "title": "Product B",
      "description": "Best-selling gadget",
      "url": "https://example.com/product-b.jpg",
      "suggestions": [
        {
          "type": "open_url",
          "text": "View Details",
          "url": "https://example.com/product-b",
          "postback": "view_product_b"
        }
      ]
    }
  ],
  "templateDetails": {
    "username": "your-account-username",
    "agent": "your-agent-name",
    "category": "carousel"
  }
}

Managing Templates

List Templates

Retrieve your templates with optional filters:

GET https://api.enablex.io/rcs/v1/templates?status=approved&type=text&page_no=1&page_length=10
Authorization: Bearer {token}
Query ParameterTypeDescription
nameStringFilter by template name (returns single template)
typeStringtext, card, or carousel
statusStringpending, approved, or rejected
page_noNumberPage number (default: 1)
page_lengthNumberResults per page (default: 10)

Response:

{
  "code": 200,
  "message": "Success",
  "page_no": 1,
  "page_length": 10,
  "total": 25,
  "data": [
    { }
  ]
}

Update a Template

PATCH https://api.enablex.io/rcs/v1/templates/:template_name
Authorization: Bearer {token}
Content-Type: application/json

Send the complete updated template definition in the request body. The payload format is the same as the create template request.

Delete a Template

DELETE https://api.enablex.io/rcs/v1/templates/:template_name
Authorization: Bearer {token}
{
  "code": 200,
  "message": "Template is deleted"
}

Sending a Template Message

Once a template is approved, send it to a user with the template messaging endpoint. If the template contains placeholders, provide the variable values in the variables object.

POST https://api.enablex.io/rcs/v1/messages/templates
Authorization: Bearer {token}
Content-Type: application/json
{
  "type": "template",
  "phone": "+919876543210",
  "agent": "your-agent-name",
  "template": {
    "name": "order_update",
    "variables": {
      "name": "Rahul",
      "order_id": "ORD-78432"
    }
  },
  "fallback_text": "Hi Rahul, your order ORD-78432 is out for delivery.",
  "ttl": 3600
}

The top-level fields used in every template message:

KeyTypeRequiredDescription
typeStringYesMust be "template"
phoneStringYesRecipient phone with country code (e.g., +919876543210)
agentStringYesYour RBM Agent name
templateObjectYesContains name (template name) and optional variables object
fallback_textStringOptionalSMS fallback if RCS is unavailable
ttlNumberOptionalTime-to-live in seconds. Cannot be used with expire_time
expire_timeStringOptionalExpiry timestamp (YYYY-MM-DD HH:MM:SS UTC). Cannot be used with ttl

Success Response:

{
  "code": 200,
  "message": "Message request has been created",
  "message_id": "msg_abc123def456"
}

The message_id is used to track delivery status updates received on your webhook.

Session Messages (Without Template)

When you are within a 24-hour session window (user has responded), or when operating outside India where templates are not mandatory, you can send messages directly without a template. All session messages use a single endpoint with different type values.

POST https://api.enablex.io/rcs/v1/messages
Authorization: Bearer {token}
Content-Type: application/json

The type field determines the content type:

Type ValueDescriptionKey Content Fields
textPlain text messagetext, suggestions
cardRich card with mediacard object
carouselCarousel of 2–10 rich cardscarousel array

Sending a Text Message

A text message can contain up to 2,500 characters and optionally include interactive suggestions.

{
  "type": "text",
  "phone": "+919876543210",
  "agent": "your-agent-name",
  "text": "Hi Rahul! Your appointment is confirmed for tomorrow at 10:00 AM.",
  "suggestions": [
    {
      "type": "reply",
      "text": "Confirm",
      "postback": "appointment_confirmed"
    },
    {
      "type": "reply",
      "text": "Reschedule",
      "postback": "appointment_reschedule"
    }
  ],
  "fallback_text": "Your appointment is confirmed for tomorrow at 10:00 AM."
}
KeyTypeRequiredDescription
typeStringYesUse "text"
textStringYesMessage text (max 2,500 characters)
suggestionsArrayNoArray of suggestion objects (max 4 per message)

Sending a Rich Card

A rich card combines media (image or video), text, and interactive suggestions into a single visually rich message. This is ideal for product showcases, promotional content, or any message that benefits from visual context.

{
  "type": "card",
  "phone": "+919876543210",
  "agent": "your-agent-name",
  "card": {
    "title": "Premium Wireless Headphones",
    "description": "Noise-cancelling, 30-hour battery life. Now $79.99",
    "url": "https://example.com/headphones.jpg",
    "thumbnail_url": "https://example.com/headphones-thumb.jpg",
    "suggestions": [
      {
        "type": "open_url",
        "text": "Buy Now",
        "url": "https://example.com/headphones",
        "postback": "buy_headphones"
      },
      {
        "type": "reply",
        "text": "More Info",
        "postback": "info_headphones"
      }
    ]
  },
  "fallback_text": "Premium Wireless Headphones - $79.99. Visit https://example.com/headphones"
}

The card object fields:

KeyTypeRequiredDescription
titleStringYesCard title text
descriptionStringNoCard description text
urlStringConditionalPublic HTTPS URL for the media file. Cannot be used with id
idStringConditionalPre-uploaded file ID. Cannot be used with url
thumbnail_urlStringNoHTTPS URL for thumbnail image. Cannot be used with thumbnail_id
thumbnail_idStringNoPre-uploaded thumbnail file ID. Cannot be used with thumbnail_url
suggestionsArrayNoUp to 4 suggestion objects per card
Tip: Always include a thumbnail_url for video content. This gives users a preview image before the video loads. See RCS Rich Media for full media specifications, card heights, and orientation details.

A carousel lets you present multiple options as a horizontally scrollable set of rich cards. Users can swipe through the cards and interact with each one individually. Carousels are ideal for product catalogs, plan comparisons, or multi-option menus.

{
  "type": "carousel",
  "phone": "+919876543210",
  "agent": "your-agent-name",
  "carousel": [
    {
      "title": "Basic Plan",
      "description": "$9.99/mo — 10 GB storage",
      "url": "https://example.com/plan-basic.jpg",
      "suggestions": [
        {
          "type": "open_url",
          "text": "Select Plan",
          "url": "https://example.com/plans/basic",
          "postback": "select_basic"
        }
      ]
    },
    {
      "title": "Pro Plan",
      "description": "$19.99/mo — 100 GB storage",
      "url": "https://example.com/plan-pro.jpg",
      "suggestions": [
        {
          "type": "open_url",
          "text": "Select Plan",
          "url": "https://example.com/plans/pro",
          "postback": "select_pro"
        }
      ]
    },
    {
      "title": "Enterprise Plan",
      "description": "Custom pricing — Unlimited storage",
      "url": "https://example.com/plan-enterprise.jpg",
      "suggestions": [
        {
          "type": "reply",
          "text": "Contact Sales",
          "postback": "contact_sales"
        }
      ]
    }
  ],
  "fallback_text": "Check out our plans at https://example.com/plans"
}
KeyTypeRequiredDescription
typeStringYesUse "carousel"
carouselArrayYesArray of 2–10 rich card objects (same structure as the card object above)
Important: A carousel must contain at least 2 and at most 10 cards. Each card in the carousel follows the same object structure as a standalone rich card. The height of the first few cards determines the height of all cards — keep content roughly equivalent across cards to avoid truncation.

Interactive Suggestions

Suggestions are interactive buttons that appear below a message or within a rich card. They allow users to respond with a single tap rather than typing a free-form reply. Each message or card can have up to 4 suggestions.

There are two categories of suggestions, and they cannot be mixed on a single card:

CategoryWhat It DoesTypes
Suggested RepliesSends a predefined text/postback value back to the businessreply
Suggested ActionsTriggers a native device action (open URL, dial, view map, etc.)open_url, dial, view_location, share_location, create_calendar_event
Important: A single card cannot contain a mix of suggested replies and suggested actions. Choose one category per card. The suggestion text is limited to 25 characters.

Suggested Reply

When a user taps a suggested reply, the app sends the postback data back to your webhook. Use this for quick response options like "Yes/No", "Confirm/Cancel", or menu selections.

{
  "type": "reply",
  "text": "Confirm Booking",
  "postback": "booking_confirmed_12345"
}

Open URL

Opens the specified URL in the user's browser or the default app registered for that URL scheme.

{
  "type": "open_url",
  "text": "View Invoice",
  "url": "https://example.com/invoices/INV-789",
  "postback": "view_invoice_789"
}

Dial a Phone Number

Opens the phone dialer with the specified number pre-filled. The phone number must include a leading +, country code, and area code with no separators.

{
  "type": "dial",
  "text": "Call Support",
  "phone": "+18005551234",
  "postback": "call_support"
}

View a Location

Opens the default map application with a pin at the specified coordinates.

{
  "type": "view_location",
  "text": "See on Map",
  "latitude": "28.4595",
  "longitude": "77.0266",
  "label": "EnableX Office, Gurugram",
  "fallback": "https://maps.google.com/?q=28.4595,77.0266",
  "postback": "view_office_location"
}

Share Location

Prompts the user to share a location (not necessarily their current location). The shared coordinates are posted to your webhook.

{
  "type": "share_location",
  "text": "Share Delivery Address",
  "postback": "share_delivery_location"
}

Create Calendar Event

Opens the user's calendar app with a pre-filled event.

{
  "type": "create_calendar_event",
  "text": "Add to Calendar",
  "title": "Doctor Appointment",
  "description": "Annual health checkup at City Hospital",
  "start_time": "2025-03-15T10:00:00Z",
  "end_time": "2025-03-15T11:00:00Z",
  "fallback": "https://calendar.google.com/calendar/event?action=TEMPLATE",
  "postback": "calendar_appointment_added"
}

For the complete field reference for each suggestion type, see RCS Rich Media — Suggestions Reference.

Utility APIs

Revoke a Sent Message

If a message is still queued (not yet delivered), you can revoke it. RBM keeps undelivered messages in queue for up to 30 days unless you specified a ttl or expire_time.

DELETE https://api.enablex.io/rcs/v1/messages/revoke/{message_id}
Authorization: Bearer {token}
Note: A 200 OK response confirms the revocation request was received — it does not guarantee the message was revoked. If revocation succeeds, the message is deleted from the user's queue. If it was already delivered, the revocation has no effect.

Mark an Incoming Message as Read

Notify the end user that your business has read their incoming message. This displays a "read" indicator in their messaging app.

POST https://api.enablex.io/rcs/v1/messages/read
Authorization: Bearer {token}
Content-Type: application/json
{
  "request_id": "incoming-message-request-id",
  "phone": "+919876543210",
  "agent": "your-agent-name"
}
KeyTypeRequiredDescription
request_idStringYesThe request_id of the incoming message to mark as read
phoneStringYesUser's phone number with country code
agentStringYesRBM Agent name

Send a Typing Indicator

Show the user that your business is composing a response. This displays a typing animation in the user's messaging app.

POST https://api.enablex.io/rcs/v1/indicators/typing
Authorization: Bearer {token}
Content-Type: application/json
{
  "request_id": "incoming-message-request-id",
  "phone": "+919876543210",
  "agent": "your-agent-name"
}
Tip: Send a typing indicator immediately after receiving an incoming message and before processing the response. This gives the user visual feedback that their message was received and you are working on a reply.

Error Handling

All RCS API errors follow a consistent JSON format:

{
  "code": 1003,
  "message": "Authentication failed",
  "description": "Invalid credentials or the account has been deactivated"
}
Error CodeMeaningAction
1002Invalid/Expired TokenRegenerate a Bearer Token using the Token API
1003Authentication FailedVerify your APP ID and APP Key credentials