> ## Documentation Index
> Fetch the complete documentation index at: https://www.vobiz.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Send RCS with Vobiz

> Send RCS business messages with the Vobiz Messaging API - register an RCS sender, send text and media with suggestion buttons, fall back to SMS automatically, check reachability, and receive button taps as inbound messages.

RCS (Rich Communication Services) delivers branded messages with media and tappable suggestion buttons to Android handsets that have RCS enabled. You send RCS through the same [Send a message](/docs/sms/api/messages/send-message) endpoint as SMS, from an RCS sender that has been approved on the RCS platform.

## What you need

<Steps>
  <Step title="An approved RCS sender">
    An RCS sender is the branded identity (name, logo, colour, contact details) that recipients see. Create one with [Create an RCS sender](/docs/sms/api/senders/create-sender) and poll [Sender status](/docs/sms/api/senders/get-sender-status) until it is approved. The [RCS senders](/docs/sms/rcs-senders) page walks through the registration.
  </Step>

  <Step title="Use the sender as the from value">
    For `channel: "rcs"`, `from` is the sender's `senderName`, not a phone number.
  </Step>

  <Step title="Decide on SMS fallback">
    Recipients without RCS cannot receive the rich message. Set `failoverToSms: true` to deliver the `text` as SMS instead - this needs an SMS-capable number on your account for the route. See [SMS](/docs/sms/channels/sms).
  </Step>
</Steps>

## Send an RCS message with buttons

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.vobiz.ai/api/v1/sms/messages" \
    -H "X-Auth-ID: MA_XXXXXXXX" \
    -H "X-Auth-Token: YOUR_AUTH_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "from": "AcmeStore",
      "to": ["+14155550123"],
      "channel": "rcs",
      "text": "Your order #4821 is ready for pickup. What would you like to do?",
      "mediaUrls": ["https://example.com/media/order-4821.jpg"],
      "rcsSuggestions": [
        { "type": "REPLY", "text": "I am on my way", "postbackData": "pickup_now_4821" },
        { "type": "REPLY", "text": "Hold until tomorrow", "postbackData": "pickup_tomorrow_4821" },
        { "type": "OPEN_URL", "text": "View order", "postbackData": "view_4821", "url": "https://example.com/orders/4821" },
        { "type": "DIAL_PHONE", "text": "Call the store", "postbackData": "call_store", "phoneNumber": "+14155550100" },
        { "type": "SHOW_LOCATION", "text": "Store location", "postbackData": "show_store", "latitude": 37.7749, "longitude": -122.4194, "label": "Acme Store, Market St" }
      ],
      "failoverToSms": true,
      "tag": "pickup"
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://api.vobiz.ai/api/v1/sms/messages",
      headers={
          "X-Auth-ID": "MA_XXXXXXXX",
          "X-Auth-Token": "YOUR_AUTH_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "from": "AcmeStore",
          "to": ["+14155550123"],
          "channel": "rcs",
          "text": "Your order #4821 is ready for pickup. What would you like to do?",
          "mediaUrls": ["https://example.com/media/order-4821.jpg"],
          "rcsSuggestions": [
              {"type": "REPLY", "text": "I am on my way", "postbackData": "pickup_now_4821"},
              {"type": "REPLY", "text": "Hold until tomorrow", "postbackData": "pickup_tomorrow_4821"},
              {"type": "OPEN_URL", "text": "View order", "postbackData": "view_4821",
               "url": "https://example.com/orders/4821"},
              {"type": "DIAL_PHONE", "text": "Call the store", "postbackData": "call_store",
               "phoneNumber": "+14155550100"},
              {"type": "SHOW_LOCATION", "text": "Store location", "postbackData": "show_store",
               "latitude": 37.7749, "longitude": -122.4194, "label": "Acme Store, Market St"},
          ],
          "failoverToSms": True,
          "tag": "pickup",
      },
  )
  resp.raise_for_status()
  message = resp.json()
  print(message["id"], message["channel"], message["status"])
  ```

  ```javascript Node theme={null}
  const resp = await fetch("https://api.vobiz.ai/api/v1/sms/messages", {
    method: "POST",
    headers: {
      "X-Auth-ID": "MA_XXXXXXXX",
      "X-Auth-Token": "YOUR_AUTH_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      from: "AcmeStore",
      to: ["+14155550123"],
      channel: "rcs",
      text: "Your order #4821 is ready for pickup. What would you like to do?",
      mediaUrls: ["https://example.com/media/order-4821.jpg"],
      rcsSuggestions: [
        { type: "REPLY", text: "I am on my way", postbackData: "pickup_now_4821" },
        { type: "REPLY", text: "Hold until tomorrow", postbackData: "pickup_tomorrow_4821" },
        { type: "OPEN_URL", text: "View order", postbackData: "view_4821", url: "https://example.com/orders/4821" },
        { type: "DIAL_PHONE", text: "Call the store", postbackData: "call_store", phoneNumber: "+14155550100" },
        { type: "SHOW_LOCATION", text: "Store location", postbackData: "show_store", latitude: 37.7749, longitude: -122.4194, label: "Acme Store, Market St" },
      ],
      failoverToSms: true,
      tag: "pickup",
    }),
  });
  const message = await resp.json();
  console.log(message.id, message.channel, message.status);
  ```
</CodeGroup>

```json Response - 201 Created theme={null}
{
  "id": "9b2e1c40-8a3d-4f5e-9c1a-7d6b2e8f4a01",
  "accountId": "MA_XXXXXXXX",
  "direction": "out",
  "channel": "rcs",
  "from": "AcmeStore",
  "to": "+14155550123",
  "text": "Your order #4821 is ready for pickup. What would you like to do?",
  "mediaUrls": ["https://example.com/media/order-4821.jpg"],
  "status": "sent",
  "tag": "pickup",
  "conversationId": "3c1d7e52-6f4b-4a8e-b2d9-0e5f1a7c9b34",
  "createdAt": "2026-10-18T09:30:00.123456Z",
  "updatedAt": "2026-10-18T09:30:00.123456Z"
}
```

<Warning>
  Every RCS send reaches a real handset and is billed at the RCS rate, or at the SMS rate when it falls back. Run the examples only with your own credentials and numbers you intend to message.
</Warning>

## Request fields for RCS

| Field | Notes |
| - | - |
| `from` | The `senderName` of an approved RCS sender on your account. |
| `to` | One or more recipient numbers in E.164 format. Each becomes its own message record. |
| `channel` | `rcs`. |
| `text` | The message body. |
| `mediaUrls` | The **first** URL is attached to the message as its media file. Use a public `https` URL. |
| `rcsSuggestions` | Up to the platform's button limit, in display order. See the table below. |
| `failoverToSms` | `true` to resend the `text` as SMS when the RCS send fails. Default `false`. |
| `tag`, `idempotencyKey`, `scheduledAt` | Behave exactly as for [SMS](/docs/sms/channels/sms). |

## Suggestion buttons

Each entry in `rcsSuggestions` is one button under the message. `text` is the label the recipient sees and `postbackData` is the value returned to you when the button is tapped. The remaining fields depend on `type`:

| `type` | What happens on tap | Extra fields |
| - | - | - |
| `REPLY` | Sends `text` back to you as a reply. | none |
| `OPEN_URL` | Opens `url` in the handset browser. | `url` |
| `DIAL_PHONE` | Starts a call to `phoneNumber`. | `phoneNumber` |
| `SHOW_LOCATION` | Opens the map at the given point. | `latitude`, `longitude`, `label` |
| `REQUEST_LOCATION` | Asks the recipient to share their current location. | none |

The `rcsSuggestions` array is passed to the RCS platform as sent.

## Fall back to SMS

With `failoverToSms: true`, when the RCS send is rejected - typically because the handset is not RCS-enabled - Vobiz sends the same `text` as SMS on the same route. The result is a single message record with `channel: "sms"` and `status: "sent"`, and the call returns `201 Created`. Buttons and media are RCS features and are left out of the SMS.

Without `failoverToSms`, a rejected RCS send is stored with `status: "failed"` and the reason in `errorMessage`, and the call returns `202 Accepted`.

An RCS message that falls back to SMS is billed as SMS.

## Check reachability first

[RCS reachability](/docs/sms/api/messages/rcs-reachability) asks the RCS platform whether a number can receive RCS from your sender. Use it to pick RCS or SMS before you send, or to decide whether to spend on rich media.

```bash cURL theme={null}
curl -G "https://api.vobiz.ai/api/v1/sms/messages/rcs-reachability" \
  -H "X-Auth-ID: MA_XXXXXXXX" \
  -H "X-Auth-Token: YOUR_AUTH_TOKEN" \
  --data-urlencode "from=AcmeStore" \
  --data-urlencode "to=+14155550123"
```

```json Response - 200 OK theme={null}
{
  "to": "+14155550123",
  "reachable": true,
  "carrier": "Example Mobile"
}
```

| Field | Meaning |
| - | - |
| `to` | The number you asked about. |
| `reachable` | `true` when the handset can receive RCS from this sender. |
| `carrier` | The recipient's carrier, when the platform reports it. |
| `capability` | A capability label, when the platform reports one. |

`from` and `to` are both required (`400 {"error":"from and to are required"}`). `from` must be an RCS sender so the request can be routed to the RCS platform.

## Receive button taps and replies

When a recipient taps a `REPLY` button or types a reply, Vobiz stores an inbound message with `direction: "in"` and `status: "received"` in the [conversation](/docs/sms/conversations) between your sender and that number. For a button tap the inbound message carries the button's `postbackData`, so you can branch on the value you set (`pickup_now_4821`) instead of parsing free text.

Receive these in real time with the `message.received` [webhook](/docs/sms/webhooks) event or over the [WebSocket](/docs/sms/websocket).

## Statuses

RCS uses the same statuses as SMS: `sent`, `delivered`, `failed`, `unknown` for outbound and `received` for inbound, with `statusHistory` on [Retrieve a message](/docs/sms/api/messages/get-message). An RCS send is a single segment. See [SMS statuses](/docs/sms/channels/sms#message-statuses).

## Before you go live

<CardGroup cols={2}>
  <Card title="RCS senders" icon="id-badge" href="/docs/sms/rcs-senders">
    Create and verify the sender you send from.
  </Card>

  <Card title="Compliance overview" icon="shield-check" href="/docs/sms/compliance/overview">
    Register the numbers your SMS fallback uses.
  </Card>
</CardGroup>

## Related

<CardGroup cols={2}>
  <Card title="RCS senders" icon="id-badge" href="/docs/sms/rcs-senders">
    Register and manage the branded sender your messages come from.
  </Card>

  <Card title="Send a message" icon="paper-plane" href="/docs/sms/api/messages/send-message">
    Every request field, response and error code.
  </Card>

  <Card title="RCS reachability" icon="signal" href="/docs/sms/api/messages/rcs-reachability">
    Endpoint reference for the reachability check.
  </Card>

  <Card title="Conversations" icon="comments" href="/docs/sms/conversations">
    Where replies and button taps are stored.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.