> For the complete documentation index, see [llms.txt](https://www.docpartner.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.docpartner.dev/en/api/sms-partner/rcs.md).

# RCS

{% hint style="info" %}
To enable this feature, please [contact the technical team](https://www.smspartner.fr/contact/)
{% endhint %}

## URL

<mark style="color:green;">`POST`</mark> `https://api.smspartner.fr/v1/rcs/send`

{% hint style="warning" %}
The platform does not send commercial SMS messages between **8 PM and 8 AM on weekdays and on Sundays and public holidays** (legal restriction). If a commercial SMS is sent, the message is **paused until the next working day at 8 AM**.\
Not sending commercial SMS messages? Contact us to disable this restriction: <help@smspartner.fr>
{% endhint %}

Rate limit: 30 requests / 60 seconds

#### Required parameters

<table><thead><tr><th width="220">Name</th><th>Value</th></tr></thead><tbody><tr><td><code>apiKey</code></td><td>Your API key.</td></tr><tr><td><code>phoneNumbers</code></td><td>Recipient phone numbers. To send multiple messages, the numbers must be separated by commas. The limit per request is 500 numbers. They can be: in national format (06xxxxxxxx) or international format (+336xxxxxxxx), for French numbers; in international format (+496xxxxxxxx), for non-French numbers.</td></tr><tr><td><code>isUnicode</code></td><td><code>1</code></td></tr><tr><td><code>richContent</code></td><td>The rich content of the RCS message. See the <a href="#rich-content">Rich content</a> section. Required, unless <code>modelToken</code> is provided (see <a href="#send-from-a-template-modeltoken">Send from a template</a>).</td></tr></tbody></table>

#### Optional parameters

<table><thead><tr><th width="220">Name</th><th>Value</th></tr></thead><tbody><tr><td><code>modelToken</code></td><td>Identifier (32 characters) of an RCS template saved on the platform. Use it <strong>instead of</strong> <code>richContent</code>: the message content then comes from the template. See the <a href="#send-from-a-template-modeltoken">Send from a template</a> section. Available in <a href="https://my.smspartner.fr/dashboard/model/list">Message templates</a> (“Identifier” column) or in the template editor (“API Identifier” panel). Only <code>RCS</code> templates (text, rich card, carousel, file) have an identifier; <code>SMS</code> templates cannot be used here. <code>modelToken</code> and <code>richContent</code> are mutually exclusive.</td></tr><tr><td><code>scheduledDeliveryDate</code></td><td>Send date of the SMS, in <code>dd/mm/YYYY</code> format. Only set this if you want the SMS to be sent later.</td></tr><tr><td><code>time</code></td><td>Send time of the SMS (0-24 format), required if <code>scheduledDeliveryDate</code> is set.</td></tr><tr><td><code>minute</code></td><td>Send minute of the SMS (0-55 format, in five-minute intervals), required if <code>scheduledDeliveryDate</code> is set.</td></tr><tr><td><code>urlResponse</code></td><td>Callback URL for RCS events (e.g. http://www.myresponseurl) — Clicks — Reads — Opt-out requests (STOP) — Recipient replies.</td></tr><tr><td><code>urlDlr</code></td><td>Callback URL for delivery receipts (e.g. http://www.mydlrurl).</td></tr><tr><td><code>scheduledAt</code></td><td>Lets you schedule the SMS send, as a single value, in two possible forms:<br><br><strong>1. Absolute date</strong> — accepted formats:<br>– <code>2026-05-20 10:15</code> or <code>2026-05-20 10:15:00</code><br>– <code>2026-05-20T10:15:00</code> (ISO 8601)<br>– <code>20/05/2026 10:15</code><br>– <code>2026-05-20</code> or <code>20/05/2026</code> (sends at midnight that day)<br><br><strong>2. Relative delay</strong> — send in X time units from now:<br>– <code>+10 minutes</code>, <code>+2 hours</code>, <code>+3 days</code>, <code>+1 week</code>, <code>+1 month</code> (English)<br>– <code>+10 minutes</code>, <code>+2 heures</code>, <code>+3 jours</code>, <code>+1 semaine</code>, <code>+1 mois</code>, <code>+1 an</code> (French, abbreviations tolerated: min, mn, h, j, hrs)<br>– The <code>+</code> is optional (<code>10 minutes</code> is equivalent to <code>+10 minutes</code>)<br><br><strong>Behavior:</strong><br>– If <code>scheduledAt</code> is set, it replaces the older <code>scheduledDeliveryDate</code> / <code>time</code> / <code>minute</code> parameters (kept for backward compatibility, but <code>scheduledAt</code> is now recommended).<br>– The computed time is rounded up to the next 5-minute slot (a send can only be scheduled every 5 minutes: 10:15, 10:20, 10:25...).<br>– The resulting date must be in the future, and at most 3 months ahead.<br><br><strong>Example:</strong> <code>{ "apiKey": "xxxxx", "phoneNumbers": "+33600000000", "message": "Your appointment is coming up", "scheduledAt": "+2 hours" }</code><br><br><strong>Errors:</strong> if the format is not recognized either as an absolute date or a relative delay, or if the resolved date is in the past / more than 3 months ahead, the API returns error code <code>49</code> with an explicit message.</td></tr></tbody></table>

## Rich content

{% tabs %}
{% tab title="Send a text" %}

```json
{
    "apiKey": "",
    "isUnicode": 1,
    "phoneNumbers": [
        "+33....."
    ],
    "richContent": {
        "conversation": {
            "text": "",
            "suggestions": [
                //See the suggestions section (4 maximum)
            ]
        }
    },

    //optional: Lets you send an SMS if RCS is not accepted on the recipient's device
    "failover": {
        "sender": "...",
        "message": "this is a fallback SMS"
    }
}
```

{% endtab %}

{% tab title="Send a file" %}

```json
{
    "apiKey": "",
    "phoneNumbers": [
        ""
    ],
    "isUnicode": 1,
    "richContent": {
        "conversation": {
            "file": {
                "media": {
                    "fileUrl": ""
                }
            },
            "suggestions": [
                //See the suggestions section (4 maximum)
            ]
        }
    },
    //optional: Lets you send an SMS if RCS is not accepted on the recipient's device
    "failover": {
        "sender": "...",
        "message": "this is a fallback SMS"
    }
}
```

{% endtab %}

{% tab title="Send a rich card" %}

```json
{
    "apiKey": "",
    "phoneNumbers": [
        ""
    ],
    "isUnicode": 1,
    "richContent": {
        "conversation": {
            "richCard": {
                "orientation": "VERTICAL", //VERTICAL or HORIZONTAL
                "thumbnailImageAlignment": "LEFT", //Only if orientation == HORIZONTAL, LEFT or RIGHT
                "title": "", //200 characters maximum
                "description": "", //500 characters maximum
                "media": {
                    "height": "MEDIUM", //only if orientation == VERTICAL
                    "mediaUrl": ""
                },
                "suggestions": [
                    //See the suggestions section (4 maximum)
                ]
            },

            //global suggestions (8 maximum)
            "suggestions": [
                //See the suggestions section (8 maximum)
            ]
        }
    },

    //optional: Lets you send an SMS if RCS is not accepted on the recipient's device
    "failover": {
        "sender": "...",
        "message": "this is a fallback SMS"
    }
}
```

{% endtab %}

{% tab title="Send a carousel" %}

```json
{
    "apiKey": "",
    "phoneNumbers": [
        ""
    ],
    "isUnicode": 1,
    "richContent": {
        "conversation": {
            "carousel": {
                "cardWidth": "MEDIUM", //MEDIUM or SMALL

                // 8 cards maximum
                "cards": [
                    {
                        "title": "", //200 characters maximum
                        "description": "", //500 characters maximum
                        "media": {
                            "height": "MEDIUM",
                            "mediaUrl": ""
                        },
                        "suggestions": [
                            //See the suggestions section (4 maximum)
                        ]
                    },
                    {
                        "title": "", //200 characters maximum
                        "description": "", //500 characters maximum
                        "media": {
                            "height": "MEDIUM",
                            "mediaUrl": ""
                        },
                        "suggestions": [
                            //See the suggestions section (4 maximum)
                        ]
                    }
                ]
            },

            //global suggestions (8 maximum)
            "suggestions": [
                //See the suggestions section (8 maximum)
            ]
        }
    },

    //optional: Lets you send an SMS if RCS is not accepted on the recipient's device
    "failover": {
        "sender": "...",
        "message": "this is a fallback SMS"
    }
}
```

{% endtab %}
{% endtabs %}

## Suggestions

{% tabs %}
{% tab title="Reply" %}

```json
{
    "reply": {
        "text": "Reply 2",
        "postbackData": "postback_..." //Unique value that will be sent back in response to a suggestion.
    }
}
```

{% endtab %}

{% tab title="Action: Open a URL" %}

```json
{
    "action": {
        "text": "Open SMSPartner",
        "postbackData": "postback_...", //Unique value that will be sent back in response to a suggestion.
        "openUrlAction": {
            "url": "https://www.smspartner.fr", //URL that will open on the phone when the suggestion is selected. Valid URI as defined in RFC 3986. Not all URI formats are supported by every network.
            "application": "WEBVIEW", //optional: BROWSER (default, external browser) or WEBVIEW (window embedded in the conversation)
            "webviewViewMode": "FULL", //required if WEBVIEW: FULL (full screen), HALF (half) or TALL (3/4)
            "description": "SMSPartner website" //optional: accessibility text, 100 characters maximum, recommended with WEBVIEW
        }
    }
}
```

See the [Opening a URL in a WebView](#opening-a-url-in-a-webview) section for details on the parameters.
{% endtab %}

{% tab title="Action: Call" %}

```json
{
    "action": {
        "text": "Call SMSPartner",
        "postbackData": "postback_...", //Unique value that will be sent back in response to a suggestion.
        "dialAction": {
            "phoneNumber": "+33......." //Valid phone number
        }
    }
}
```

{% endtab %}

{% tab title="Action: Location" %}

```json
{
    "action": {
        "text": "Location",
        "postbackData": "postback_...", //Unique value that will be sent back in response to a suggestion.
        "viewLocationAction": {
            "label": "Here !!!", //Label for the location.
            "latLong": {
                "latitude": 2.4220188, //Latitude of the location
                "longitude": -122.0844786 //Longitude of the location
            }
        }
    }
}
```

{% endtab %}
{% endtabs %}

### Opening a URL in a WebView

The "Open a URL" action (`openUrlAction`) can open the link **in a WebView embedded in the conversation** instead of the external browser, thanks to optional parameters.

{% hint style="info" %}
These parameters are optional and backward-compatible: without them, the link opens in the browser (`application` = `BROWSER`).
{% endhint %}

<table><thead><tr><th width="220">Name</th><th>Value</th></tr></thead><tbody><tr><td><code>url</code></td><td><strong>Required.</strong> URL to open. Must be a valid URL (http/https).</td></tr><tr><td><code>application</code></td><td>Optional. How the link opens: <code>BROWSER</code> (default, external browser) or <code>WEBVIEW</code> (window embedded in the conversation).</td></tr><tr><td><code>webviewViewMode</code></td><td>WebView size: <code>FULL</code> (full screen), <code>TALL</code> (3/4) or <code>HALF</code> (half). <strong>Required</strong> when <code>application</code> = <code>WEBVIEW</code>, and must not be provided otherwise.</td></tr><tr><td><code>description</code></td><td>Optional. Accessibility text describing the WebView (recommended in <code>WEBVIEW</code> mode). 100 characters maximum.</td></tr></tbody></table>

These parameters are valid everywhere an `openUrlAction` suggestion is accepted: text message suggestions, rich-card buttons and buttons of each carousel card.

If a value is invalid, the API returns an error with one of the following codes: `24` (invalid `application`), `25` (invalid `webviewViewMode`), `26` (`webviewViewMode` provided without `application` = `WEBVIEW`), `27` (`webviewViewMode` missing while `application` = `WEBVIEW`), `28` (`description` longer than 100 characters).

## Send from a template (modelToken) <a href="#send-from-a-template-modeltoken" id="send-from-a-template-modeltoken"></a>

Instead of providing the full content in `richContent` on every call, you can save that content **once** as an **RCS template** on the platform, then send it through the API by simply passing its identifier (`modelToken`). Every send uses the **current version** of the template.

The identifier can also be pasted into our modules and connectors (PrestaShop, WooCommerce, Zapier, Make…) wherever an "RCS template identifier" is requested.

{% hint style="info" %}
The identifier only designates the template to use. It does not expire, is not an authentication secret, and is recognized only for the account that owns the template (resolution based on the `apiKey`). The `apiKey` remains mandatory.
{% endhint %}

{% hint style="danger" %}
`modelToken` and `richContent` are **mutually exclusive**. If both are present in the same request, the API returns an **HTTP 400 error (code 62)** and the message is not sent. An empty `richContent` (`{}` or `null`) is treated as not provided.
{% endhint %}

{% tabs %}
{% tab title="Minimal example" %}

```json
{
    "apiKey": "",
    "phoneNumbers": [
        "+33....."
    ],
    "modelToken": "9f8c2b1a7d4e6f30a1b2c3d4e5f60718"
}
```

{% endtab %}

{% tab title="Full example" %}

```json
{
    "apiKey": "",
    "phoneNumbers": [
        "+33....."
    ],
    "modelToken": "9f8c2b1a7d4e6f30a1b2c3d4e5f60718",
    "tag": "summer-campaign",
    "scheduledAt": "+2 hours",
    "sandbox": false,
    "urlDlr": "https://example.com/callback/dlr",
    "urlResponse": "https://example.com/callback/response",

    //optional: Lets you send an SMS if RCS is not accepted on the recipient's device
    "failover": {
        "sender": "MyBrand",
        "message": "Your RCS could not be delivered. Find our offer at https://example.com"
    }
}
```

{% endtab %}
{% endtabs %}

The `modelToken` provides **the content**, the API call still drives everything else (recipients, fallback sender, scheduling, tag, sandbox, callbacks…). All other validations (numbers, scheduling, field sizes, suggestions…) are identical to a standard RCS send and are applied after the template content has been injected.

<table><thead><tr><th width="234">Response code</th><th>Response</th></tr></thead><tbody><tr><td><code>60</code></td><td>RCS template not found: the identifier does not match any RCS template in your account, or it points to an SMS template.</td></tr><tr><td><code>61</code></td><td>The RCS template is empty: the template exists but its content is empty or invalid (re-save it on the platform).</td></tr><tr><td><code>62</code></td><td><code>modelToken</code> and <code>richContent</code> were sent in the same request (mutually exclusive).</td></tr></tbody></table>

## RCS Scenario

An **RCS scenario** is an automated dialogue configured on the platform: an entry message, clickable suggestions and bot replies depending on the recipient's choices. To start a scenario from its identifier (`scenarioToken`), use the dedicated route:

{% content-ref url="/pages/CiTRVFLUgbSgVWrffAi5" %}
[RCS Scenario](/en/api/sms-partner/rcs/rcs-scenario.md)
{% endcontent-ref %}

## Response

```json
{
    "success": true,
    "code": 200,
    "message_id": 1,
    "nb_rcs": 1,
    "cost": 0.12,
    "currency": "EUR"
}
```

## Supported media file types

RBM supports the following media types:

| Content Type    | Document Type     | Extension   | Compatible with Rich Cards |
| --------------- | ----------------- | ----------- | -------------------------- |
| application/ogg | OGG Audio         | .ogx        | No                         |
| application/pdf | PDF               | .pdf        | No                         |
| audio/aac       | AAC Audio         | .aac        | No                         |
| audio/mp3       | MP3 Audio Format  | .mp3        | No                         |
| audio/mpeg      | MPEG Audio        | .mpeg       | No                         |
| audio/mpg       | MPG Audio         | .mp3        | No                         |
| audio/mp4       | MP4 Audio         | .mp4        | No                         |
| audio/mp4-latm  | MP4-latm Audio    | .mp4        | No                         |
| audio/3gpp      | 3GPP Audio        | .3gp        | No                         |
| image/jpeg      | JPEG              | .jpeg, .jpg | Yes                        |
| image/gif       | GIF               | .gif        | Yes                        |
| image/png       | PNG               | .png        | Yes                        |
| video/h263      | H263 Video        | .h263       | Yes                        |
| video/m4v       | M4V Video         | .m4v        | Yes                        |
| video/mp4       | MP4 Video         | .mp4        | Yes                        |
| video/mpeg4     | MPEG-4 Video      | .mp4, .m4p  | Yes                        |
| video/mpeg      | MPEG Video        | .mpeg       | Yes                        |
| video/webm      | WebM Video Format | .webm       | Yes                        |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://www.docpartner.dev/en/api/sms-partner/rcs.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
