Send RCS
The transactional RCS operation consists of sending an RCS message to one or more recipients who do not belong to the organization’s audience. As such, it does not depend on a schema previously defined for the audience of contacts.
There is a limit of 10 RCS messages per HTTP request to the Arpoone API, configured through the messages field.
Each element of the messages array represents an independent RCS message and may specify a different recipient, sender, expiration date and content.
Special attention must be given to the to field in the transactional RCS payload. The destination phone number must be a valid MSISDN and include the country calling code. For example, a Portuguese MSISDN must start with 351 (e.g. 351913462111).
Request structure
{
"organizationId": "<uuid>",
"messages": [
{
"to": "<msisdn>",
"expirationDateTime": "<dateTime>",
"contentMessage": {
"<contentType>": {}
},
"customPayload": "<string>",
"fallbacks": {
"smsFallback": {
"to": "<string>",
"from": "<string>",
"text": "<string>",
"expirationDateTime": "<datetime>",
"smsWebhooks": {
"delivered": {
"url": "<string>",
"enabled": "<bool>"
},
"not_delivered": {
"url": "<string>",
"enabled": "<bool>"
},
"pending": {
"url": "<string>",
"enabled": "<bool>"
},
"customPayload": "<string>"
}
}
}
}]
}
The structure above is a simplified representation of the request. The properties accepted by contentMessage depend on the selected RCS content type.
Alternatively to passing contentMessage as an argument, it is possible to pass the identifier of an RCS template that has been previously created in the platform, as well as substitution variable, in case the template contains placeholders:
{
"organizationId": "<uuid>",
"messages": [
{
"to": "<msisdn>",
"expirationDateTime": "<dateTime>",
"template": {
"templateId": "<uuid>",
"parameters": [
{
"name": "<string>",
"value": "<string>"
}
]
},
"customPayload": "<string>",
"fallbacks": {
"smsFallback": {
"to": "<string>",
"from": "<string>",
"text": "<string>",
"expirationDateTime": "<datetime>",
"smsWebhooks": {
"delivered": {
"url": "<string>",
"enabled": "<bool>"
},
"not_delivered": {
"url": "<string>",
"enabled": "<bool>"
},
"pending": {
"url": "<string>",
"enabled": "<bool>"
},
"customPayload": "<string>"
}
}
}
}]
}
Fallback SMS
It is also possible to define a fallback SMS message, which will be sent in case the RCS message is not delivered to the recipient. One should note that the fallback message will not be triggered in case the scheduling of the RCS message or respective fallback is rejected by the current endpoint. The fallback will be automatically triggered by the system after being notified about the impossibility of delivering the message to the recipient, for reasons such as the device having the RCS feature set as disabled, or the message expiration date being exceeded. The deduction of the balance relative to the fallback scheduling will be performed only when the fallback is triggered.
Request properties
Root object
| Property | Type | Required | Description |
|---|---|---|---|
organizationId | UUID | Yes | Unique identifier of the Arpoone Organization where the operation will take place, as a user may have access to more than one Organization. |
messages | Array | Yes | Collection of RCS messages to send. The array must contain between 1 and 10 elements. |
Message object
| Property | Type | Required | Description |
|---|---|---|---|
to | String | Yes | Recipient's mobile number, including the country calling code. |
expirationDateTime | DateTime | No | Date and time after which the message must no longer be delivered. The value must use ISO 8601 format, including the applicable UTC offset. |
contentMessage | String | No | RCS content to send. The object must contain one supported primary content type. |
template | Object | No | RCS template data to use in the scheduling. This template must have been previously created in the Arpoone platform . This field is required if no contentMessage is set in the message. |
customPayload | String | No | String value that will be relayed in the events (webhooks) related to this message |
fallbacks | Object | No | Object that contains the definition for fallback schedulings, in case the original RCS message is not delivered |
Template object
| Property | Type | Required | Description |
|---|---|---|---|
template.templateId | Object | Yes | RCS template identifier which must have been created in the Arpoone platform |
template.parameters | Array | No | Object array which contain the parameters that should replace the placeholders in the template content. |
Template parameter object
| Property | Type | Required | Description |
|---|---|---|---|
template.parameters[].name | String | Yes | Name of the placeholder which should be replaced. This comparison is case insensitive. |
template.parameters[].value | String | Yes | The value which will replace the placeholder in the template content. |
Fallback object
| Property | Type | Required | Description |
|---|---|---|---|
smsFallback | Object | No | Object that contains the definition for a fallback SMS scheduling, in case the original RCS message is not delivered |
SMS fallback object
| Property | Type | Required | Description |
|---|---|---|---|
to | String | No | Recipient of the SMS. If ommitted, the recipient of the original RCS message will be assumed |
from | String | Yes | The name of the sender to be used in the fallback scheduling, which must be pre-configured via the Arpoone platform |
text | String | Yes | Content of the message |
expirationDateTime | DateTime | No | Expiration date and time in UTC timezone when the SMS is sent. If there is any delay in sending SMS by the platform, and the current date exceeds the configured value in this field, the SMS will not be sent |
smsWebhooks | Object | No | Webhook configurations for the fallback SMS message. Consult the definition here |
Response
Similarly to the request body of the transactional RCS endpoint, the response also contains an array messages. There is a matching index between each item in the array of the request and the array of the response, where each object contains the result of the scheduling.
The transactional RCS endpoint returns Status Code 200 (HTTP OK) if no error prevents the processing of the request. The success/error indication for each message is made in the response body, within each item in the messages array, under the status property.
For each item, the scheduling status will be indicated in the status property (which reflects whether the RCS message was sent successfully or not), the RCS message identifier (messageId), the cost of sending it (cost, deducted from the organization’s balance), along with the recipient's country code and error description (error, if any). In case a fallback message was defined, its character count and encoding (GSM-7 or UCS2) is also returned in the fallbacks.smsFallback object.
Example:
{
"error": null,
"messages": [
{
"status": "SUCCESS",
"messageId": "3f22f963-155b-4853-b8fb-0d1944345321",
"cost": {
"amount": 1,
"countryCode": "PT"
},
"fallbacks": {
"smsFallback": {
"segmentCount": 1,
"encoding": 0
}
},
"error": null
},
...
]
}
Content rules
Each message must contain one contentMessage.
The supported primary content types are:
textcontentInforichCard
Only one primary content type should be included in the same contentMessage. For example, a message must not contain both text and richCard.
The suggestions property is not considered a primary content type and can be combined with text content.
Examples
{
"contentMessage": {
"text": "Your order is ready."
}
}
{
"contentMessage": {
"contentInfo": {
"fileUrl": "https://cdn.example.com/order-confirmation.pdf",
"mimeType": "application/pdf"
}
}
}
{
"contentMessage": {
"richCard": {
"standaloneCard": {}
}
}
}
Request limits
| Limit | Value |
|---|---|
| Maximum messages per HTTP request | 10 |
| Maximum size per message | 250 KB |
| Maximum text message length | 3,072 characters |
| Maximum message-level suggestions | 11 |
| Maximum suggestions per rich card | 4 |
| Maximum cards in a carousel | 10 |
| Minimum cards in a carousel | 2 |
The 250 KB limit applies individually to each element of the messages array and not to the complete HTTP request.
Batch submission does not combine the elements into a single RCS message. Each message is validated and processed independently.
Text messages
A text message is sent using the text property.
The maximum text length is 3,072 characters.
Text message example
curl --location 'https://api.arpoone.com/v1.2/rcs/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--data '{
"organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
"messages": [
{
"to": "351912345678",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {
"text": "Your order is ready for collection."
}
}
]
}'
Text message with suggested replies
Text messages can include suggested replies and suggested actions through the suggestions array.
A message can contain up to 11 message-level suggestions.
curl --location 'https://api.arpoone.com/v1.2/rcs/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--data '{
"organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
"messages": [
{
"to": "351912345678",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {
"text": "Would you like to confirm your appointment?",
"suggestions": [
{
"reply": {
"text": "Confirm",
"postbackData": "appointment-confirm"
}
},
{
"reply": {
"text": "Reschedule",
"postbackData": "appointment-reschedule"
}
}
]
}
}
]
}'
Media messages
A media-only message is sent using contentInfo.
The Arpoone API does not accept media files as Base64 content or as multipart file uploads for this operation. The media file must be made available by the client through a URL before submitting the message.
Content information properties
| Property | Type | Required | Description |
|---|---|---|---|
fileUrl | String | Yes | Publicly accessible HTTPS URL from which the media file can be retrieved. |
thumbnailUrl | String | No | Publicly accessible HTTPS URL of the thumbnail associated with the media file. Maximum length: 2,048 characters. |
mimeType | String | Yes | MIME type of the media resource. The value must correspond to one of the supported media types. |
Media URL requirements
For media referenced by URL, Arpoone requires the following conditions to ensure that the file can be retrieved and processed reliably:
- use HTTPS;
- be externally accessible through an HTTP GET request;
- return the media content directly;
- not require an authenticated user session;
- remain accessible while the message is being processed and delivered;
- return content consistent with the declared
mimeType.
The client is responsible for hosting the file and ensuring its continued availability.
Supported media types
Images
image/jpegimage/jpgimage/gifimage/png
Video
video/h263video/m4vvideo/mp4video/mpegvideo/mpeg4video/webm
Documents
application/pdf
These are the media types currently identified as supported by the Arpoone integration.
Google notes that PDF support in rich cards may depend on geography and the recipient's messaging client. Specifically, its current rich-card documentation states that PDF rich cards are only available in India on the Google Messages client.
Media message example
curl --location 'https://api.arpoone.com/v1.2/rcs/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--data '{
"organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
"messages": [
{
"to": "351912345678",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {
"contentInfo": {
"fileUrl": "https://cdn.example.com/media/product.jpg",
"thumbnailUrl": "https://cdn.example.com/media/product-thumbnail.jpg",
"mimeType": "image/jpeg"
}
}
}
]
}'
Rich cards
Rich cards can combine media, a title, a description and suggestions in a single message.
The API supports:
- standalone rich cards;
- rich card carousels.
Rich cards can combine media, title text, description text, suggested replies and suggested actions. Support and rendering may vary depending on the capabilities of the recipient’s device.
Card content properties
A rich card must contain meaningful card content. At least one title, description or media should be provided.
The integration material additionally specifies that when a horizontal card contains media, it must also include at least a title, description or suggestion.
| Property | Type | Required | Description |
|---|---|---|---|
title | String | Conditional | Rich card title. Maximum length: 200 characters. |
description | String | Conditional | Rich card description. Maximum length: 2,000 characters. |
media | Object | Conditional | Media displayed in the rich card. It follows the same media restrictions as a media-only message. |
suggestions | Array | No | Suggested replies or actions associated with the card. Maximum: 4 elements per card. |
Standalone rich card
Standalone card properties
| Property | Type | Required | Description |
|---|---|---|---|
cardOrientation | Enum | Yes | Card orientation. Accepted values: VERTICAL or HORIZONTAL. |
thumbnailImageAlignment | Enum | Conditional | Thumbnail alignment for a horizontal card. Accepted values: LEFT or RIGHT. |
cardContent | Object | Yes | Content displayed in the card. |
Media properties in a rich card
| Property | Type | Required | Description |
|---|---|---|---|
height | Enum | No | Media preview height. Accepted values: SHORT, MEDIUM or TALL. |
contentInfo | Object | Yes | Media URL, optional thumbnail URL and MIME type. |
The API defines the following media preview heights: 112 DP for SHORT, 168 DP for MEDIUM and 264 DP for TALL. If the media dimensions do not match the selected height, the image may be zoomed and centrally cropped.
Standalone rich card example
curl --location 'https://api.arpoone.com/v1.2/rcs/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--data '{
"organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
"messages": [
{
"to": "351912345678",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {
"richCard": {
"standaloneCard": {
"cardOrientation": "VERTICAL",
"thumbnailImageAlignment": "LEFT",
"cardContent": {
"title": "New product available",
"description": "Discover the latest product in our catalogue.",
"media": {
"height": "MEDIUM",
"contentInfo": {
"fileUrl": "https://cdn.example.com/media/product.jpg",
"thumbnailUrl": "https://cdn.example.com/media/product-thumbnail.jpg",
"mimeType": "image/jpeg"
}
},
"suggestions": [
{
"openUrlAction": {
"text": "View product",
"url": "https://www.example.com/products/123",
"postbackData": "view-product-123"
}
}
]
}
}
}
}
}
]
}'
Rich card carousel
A carousel contains between 2 and 10 cards.
Each element of cardContents follows the rich card content rules, including a maximum of four suggestions per card.
Carousel properties
| Property | Type | Required | Description |
|---|---|---|---|
cardWidth | Enum | Yes | Width applied to the cards in the carousel. Accepted values: SMALL or MEDIUM. |
cardContents | Array | Yes | Cards displayed in the carousel. The array must contain between 2 and 10 elements. |
Carousel example
curl --location 'https://api.arpoone.com/v1.2/rcs/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--data '{
"organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
"messages": [
{
"to": "351912345678",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {
"richCard": {
"carouselCard": {
"cardWidth": "MEDIUM",
"cardContents": [
{
"title": "Product A",
"description": "Description of product A.",
"media": {
"height": "MEDIUM",
"contentInfo": {
"fileUrl": "https://cdn.example.com/media/product-a.jpg",
"mimeType": "image/jpeg"
}
},
"suggestions": [{"reply": {"text": "Select A", "postbackData": "select-product-a"}}]
},
{
"title": "Product B",
"description": "Description of product B.",
"media": {
"height": "MEDIUM",
"contentInfo": {
"fileUrl": "https://cdn.example.com/media/product-b.jpg",
"mimeType": "image/jpeg"
}
},
"suggestions": [{"reply": {"text": "Select B", "postbackData": "select-product-b"}}]
}
]
}
}
}
}
]
}'
Suggestions
Suggestions allow the recipient to reply or perform a predefined action directly from the RCS conversation.
The following suggestion types are supported:
- suggested reply;
- open URL;
- dial a phone number;
- view a location;
- share the recipient's location;
- create a calendar event.
Each element of the suggestions array must contain exactly one suggestion type.
Common suggestion limits
These limits apply to all supported RCS suggestion types.
| Property | Maximum length |
|---|---|
| Suggestion text | 25 characters |
postbackData | 2,000 characters |
| Open URL | 2,048 characters |
Suggested reply
A suggested reply displays a predefined response to the recipient.
| Property | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Text displayed in the suggestion and returned as the suggested reply. Maximum: 25 characters. |
postbackData | String | Yes | Data returned to the client when the recipient selects the suggestion. Maximum: 2,000 characters. |
{
"reply": {
"text": "Confirm",
"postbackData": "confirm-order"
}
}
Open URL action
Opens a URL when selected by the recipient.
| Property | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Text displayed in the suggestion. Maximum: 25 characters. |
url | String | Yes | URL to open. Maximum: 2,048 characters. |
postbackData | String | Yes | Data associated with the action. Maximum: 2,000 characters. |
{
"openUrlAction": {
"text": "View details",
"url": "https://www.example.com/orders/123",
"postbackData": "view-order-123"
}
}
Dial action
Starts a telephone call to the specified number.
| Property | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Text displayed in the suggestion. Maximum: 25 characters. |
phoneNumber | String | Yes | Telephone number in E.164 format, for example +351211234567. |
postbackData | String | Yes | Data associated with the action. Maximum: 2,000 characters. |
{
"dialAction": {
"text": "Call us",
"phoneNumber": "+351211234567",
"postbackData": "call-customer-service"
}
}
View location action
Displays a specified geographical location.
| Property | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Text displayed in the suggestion. Maximum: 25 characters. |
latitude | Decimal | Yes | Latitude in the range -90 to 90. |
longitude | Decimal | Yes | Longitude in the range -180 to 180. |
label | String | No | Description or label associated with the location. Maximum: 100 characters. |
postbackData | String | Yes | Data associated with the action. Maximum: 2,000 characters. |
{
"viewLocationAction": {
"text": "View location",
"latitude": 38.7223,
"longitude": -9.1393,
"label": "Lisbon office",
"postbackData": "view-lisbon-office"
}
}
Location content is supported as a suggestion action. Location content is not currently supported as the main content of a rich card. A static map image can instead be referenced through the rich card's media URL.
Share location action
Prompts the recipient to share their current location.
| Property | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Text displayed in the suggestion. Maximum: 25 characters. |
postbackData | String | Yes | Data associated with the action. Maximum: 2,000 characters. |
{
"shareLocationAction": {
"text": "Share location",
"postbackData": "share-current-location"
}
}
Create calendar event action
Allows the recipient to create a calendar event.
| Property | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Text displayed in the suggestion. Maximum: 25 characters. |
title | String | Yes | Calendar event title. Maximum: 100 characters. |
description | String | No | Calendar event description. Maximum: 500 characters. |
startTime | DateTime | Yes | Event start date and time in ISO 8601 format. |
endTime | DateTime | Yes | Event end date and time in ISO 8601 format. It must be later than startTime. |
postbackData | String | Yes | Data associated with the action. Maximum: 2,000 characters. |
{
"createCalendarEventAction": {
"text": "Add to calendar",
"title": "Product demonstration",
"description": "Online demonstration of the new product.",
"startTime": "2026-09-10T09:00:00Z",
"endTime": "2026-09-10T09:30:00Z",
"postbackData": "calendar-product-demo"
}
}
Batch request example
The following example sends three independent RCS messages through a single HTTP request.
curl --location 'https://api.arpoone.com/v1.2/rcs/send' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--data '{
"organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
"messages": [
{
"to": "351912345671",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {"text": "Your order has been shipped."}
},
{
"to": "351912345672",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {
"text": "Your appointment is confirmed.",
"suggestions": [{"reply": {"text": "Confirm", "postbackData": "appointment-confirm"}}]
}
},
{
"to": "351912345673",
"expirationDateTime": "2026-09-02T16:00:00Z",
"contentMessage": {
"contentInfo": {
"fileUrl": "https://cdn.example.com/documents/invoice.pdf",
"mimeType": "application/pdf"
}
}
}
]
}'
Processing behaviour
Submitting the request does not necessarily mean that the messages have already been delivered to their recipients.
When a request is accepted:
- the request is authenticated;
- the organization and its access to the RCS channel are validated;
- each message and its content are validated;
- the available RCS balance is validated;
- the accepted messages are submitted for asynchronous processing.
Final delivery can depend on factors outside the Arpoone API, including:
- whether the recipient is reachable through RCS;
- whether the recipient's network supports the RCS agent;
- the RCS capabilities supported by the recipient's device;
- the validity and availability of referenced media;
- downstream provider and operator processing.
HTTP responses
The operation follows the standard Arpoone transactional API response format.
| HTTP status | Result |
|---|---|
| 200 OK | The request was accepted for processing. |
| 400 Bad Request | The request contains invalid data or content. |
| 401 Unauthorized | Authentication is missing or invalid. |
| 403 Forbidden | The authenticated user or organization is not authorized to use the operation. |
| 404 Not Found | A referenced organization or another required resource was not found. |
| 402 Payment Required or existing balance status | The organization does not have sufficient RCS balance. |
| 429 Too Many Requests | The applicable request rate limit was exceeded. |
| 500 Internal Server Error | An unexpected error occurred while processing the request. |
| 503 Service Unavailable | The service is temporarily unavailable. |
Errors
In case of errors, the error property within in the response will be populated with an object containing information about the error that occurred:
{
"error": {
"code": "MESSAGES_EMPTY",
"param": "",
"description": "MESSAGES_EMPTY"
},
"messages": null
}
The code property specifies the type of error that occurred, while the param property specifies which parameter in the RCS send payload caused the error.
The complete list of error codes can be found here.