Splashify RCS

Docs

Open panel
Panel

Send RCS message

Fire a one-off RCS message to one recipient. For bulk sends use Broadcasts. This endpoint is for the programmatic side (order shipped, OTP, support reply).

One endpoint, two body shapes. Presence of template_id in the body picks the send path:

text
POST /api/v1/rcs/messages/send
│
├── body has template_id  →  stored-template path
│                              (loads your approved template, fills
│                               its variables, sends)
│
└── body has message      →  composed path
                               (sends the content you built in
                                the body)
  • Auth: Authorization: Bearer <token>, a session JWT or an API key with the messages:send scope. See Authentication.
  • Operators and owners can send; viewers get 403 not_operator.
  • Billing: prepaid balance is checked before the send, and the message is charged once the network accepts it. A message the network refuses is not charged; one that fails after it was accepted is refunded automatically.

There is no /api/v1/rcs/send

Earlier versions of this page named POST /api/v1/rcs/send and a /rcs/send-template alias. Neither exists on the RCS Panel API. Use POST /api/v1/rcs/messages/send for both shapes.

Picking a bot (multi-bot accounts)

Pass bot_id in the body to choose which bot sends:

json
{
  "to":      "+919876543210",
  "bot_id":  "9c1b7f4e-2a11-4c8e-8e0e-3f5d1b2c9e01",
  "message": { "type": "text", "text": "..." }
}
  • With template_id, bot_id is optional: the template's own bot sends it. If you do pass one and it is a different bot, the request is refused with 400 template_bot_mismatch.
  • With message, leaving bot_id out uses your default bot.

The bot must be active, or you get 403 with code = "bot_not_active". Team members can only send from bots assigned to them.

Prerequisites

  • An active bot. Any active bot works here, whatever it is registered for. Unlike the broadcast endpoints, this one is not restricted by the bot's carrier registration, a Transactional or OTP bot can use it without limitation, and it is the endpoint those bots are meant to be driven through. See What your bot is registered to send.
  • A Promotional bot can only send between 7:00am and 10:00pm IST. Outside that window you get 403 outside_promotional_window.
  • Enough wallet balance for one message (or postpaid billing).

For messages that fit a template you have already submitted and had approved. You author and review the template once, and every send is a tiny payload.

http
POST /api/v1/rcs/messages/send
Authorization: Bearer <token>
Content-Type: application/json

{
  "to":          "+919876543210",
  "template_id": "1f7a2c4e-9b0d-4e1a-8c3f-5d6e7f8a9b0c",
  "variables":   ["Rahul", "A-1042"]
}

Body fields

How variables are filled

A template with this message text:

text
Hi {{1}}, your order {{2}} has shipped.

can be sent with variables in either form:

and the recipient gets Hi Rahul, your order A-1042 has shipped.

Variables are filled in the message text, card titles and descriptions, button labels, and at the end of a button link. A value in a link is encoded for a web address (A 1/2 becomes A%201%2F2 in the path, a query value after a ?). Numbers and booleans are sent as text.

Rules

  • Every variable the template uses needs a non-empty value. If one is missing, nothing is sent or charged:

    json
    {
      "success": false,
      "code":    "missing_variables",
      "missing": ["{{2}}"],
      "message": "This template needs a value for {{2}}. Send them in 'variables'."
    }
  • The limits apply after filling: message text 2,000 characters, card title 200, card description 2,000, button label 25. A value that pushes a field over returns 400 variable_too_long.

  • A variables value that is neither a list nor an object, or an object key that is not a number from 1 to 10, returns 400 invalid_variables.

  • The template must be approved. A pending or rejected template returns 403 with code = "template_not_approved".

Shape 2, Composed message

For content that varies structurally per send. Put the content in message, in the same shape as a template's components.

http
POST /api/v1/rcs/messages/send
Authorization: Bearer <token>
Content-Type: application/json

{
  "to":      "+919876543210",
  "message": { "type": "text", "text": "Your OTP is 483920. Valid for 5 minutes." }
}

Body fields

The content is checked against the same limits as a template. A violation returns 400 with an errors[] array listing every problem.

Response (both shapes)

json
{
  "success":    true,
  "message_id": "d8a7…",
  "bot_id":     "9c1b7f4e-2a11-4c8e-8e0e-3f5d1b2c9e01",
  "cost":       0.3,
  "sent_at":    "2026-09-19T10:12:03Z"
}

If you send faster than the bot's speed, the extra messages are accepted and queued instead of refused. That response is 202 with "status": "queued", and it goes out within seconds. Only when the queue is full do you get 429 with a Retry-After header.

Errors

See the Errors reference for the full list.

Examples, curl

Stored template with variables:

bash
curl -X POST https://api.splashifypro.com/api/v1/rcs/messages/send \
  -H "Authorization: Bearer $SPLASHIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to":          "+919876543210",
    "template_id": "1f7a2c4e-9b0d-4e1a-8c3f-5d6e7f8a9b0c",
    "variables":   {"1": "Rahul", "2": "A-1042"}
  }'

Composed text:

bash
curl -X POST https://api.splashifypro.com/api/v1/rcs/messages/send \
  -H "Authorization: Bearer $SPLASHIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to":      "+919876543210",
    "message": { "type": "text", "text": "Your OTP is 483920. Valid for 5 minutes." }
  }'

Examples, Node.js

text
// Send an approved template to one recipient with variable values.
const res = await fetch("https://api.splashifypro.com/api/v1/rcs/messages/send", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SPLASHIFY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to:          order.customer_phone,          // "+919876543210"
    template_id: "1f7a2c4e-9b0d-4e1a-8c3f-5d6e7f8a9b0c",
    variables:   [order.customer_name, order.id],
  }),
});
const { success, message_id, message } = await res.json();
if (!success) throw new Error(message);
console.log("Sent, message id:", message_id);

Examples, Python

text
import os, requests

resp = requests.post(
    "https://api.splashifypro.com/api/v1/rcs/messages/send",
    headers={"Authorization": f"Bearer {os.environ['SPLASHIFY_API_KEY']}"},
    json={
        "to":          order["customer_phone"],
        "template_id": "1f7a2c4e-9b0d-4e1a-8c3f-5d6e7f8a9b0c",
        "variables":   [order["customer_name"], str(order["id"])],
    },
    timeout=30,
)
data = resp.json()
assert data["success"], data["message"]

When to use which shape