Skip to Content
API ReferenceRCS PanelSend RCS message

Send RCS message

Fire a one-off RCS message from your provisioned sender. For bulk sends use Broadcasts; this endpoint is for the programmatic side — order shipped, OTP, support reply.

POST /api/v1/rcs/messages/send Authorization: Bearer <jwt> Content-Type: application/json { "to": "+919876543210", "message": { "type": "text", "text": "Hi {{1}}, your order #{{2}} has shipped." }, "extra": "order_shipped_acme_42" }

Prerequisites

  • Your account must be in status = active and rcs_active = true (i.e. an admin has provisioned your RCS sender). If not, the endpoint returns 403 with code: "rcs_not_active". Apply at /apply-rcs to start that.
  • Wallet balance must be >= rcs_per_msg_price. The price is debited on a successful gateway accept; rejections refund automatically.

Request body

FieldTypeRequiredNotes
tostringyesE.164 (e.g. +919876543210)
messageobjectyesFree-form RCS payload — text, rich card, carousel, suggestions, media
extrastringnoFree-form passthrough metadata; surfaces on the delivery webhook so you can correlate sends

The sender identity is derived from your JWT — you do not pass bot_name or any sender override in the body.

Message shapes

Plain text

{ "type": "text", "text": "Your order #12345 has shipped. Track at https://acme.com/o/12345" }

Text with suggestions

{ "type": "text", "text": "Anything else?", "suggestions": [ { "type": "reply", "text": "Track order", "postback": "track-12345" }, { "type": "url", "text": "Open site", "url": "https://acme.com" }, { "type": "dial", "text": "Call us", "call_to": "+919876543210" } ] }

Rich card

{ "type": "card", "title": "Order #12345 shipped", "description": "Tap to track. ETA Wed.", "media_url": "https://cdn.acme.com/banners/order-shipped.jpg", "suggestions": [ { "type": "url", "text": "Track", "url": "https://acme.com/o/12345" } ] }
{ "type": "multiple_cards", "cards": [ { "title": "Black tee", "description": "₹499", "media_url": "https://…/tee.jpg", "suggestions": [{"type":"url","text":"Buy","url":"https://acme.com/p/tee"}] }, { "title": "Blue jeans", "description": "₹1299","media_url": "https://…/jeans.jpg", "suggestions": [{"type":"url","text":"Buy","url":"https://acme.com/p/jeans"}] } ] }

Response

200 OK:

{ "success": true, "message_id": "rm_AbCd12…", "cost": 0.95, "sent_at": "2026-05-28T08:00:02Z" }

message_id is what the gateway returned — keep it if you want to correlate against delivery webhooks. cost is the wallet debit.

Error codes

StatusWhenNotes
400Missing to or messageBody validation
402Wallet balance below rcs_per_msg_priceRecharge and retry
403rcs_not_activeApply for RCS sender first
403account suspendedContact support
502Gateway rejected the senddetail carries the upstream response
503Gateway login or transport failureSafe to retry; the wallet is refunded

Idempotency

Every POST is treated as a new send. If you retry on a network error you may get duplicate messages. Put your own idempotency key in extra and dedupe on the delivery callbacks.