Skip to navigation
RCS

Send RCS messages

View as MarkdownOpen in Claude

RCS messages are sent through the same endpoint as SMS, MMS, and WhatsApp, POST /api/messaging/messages. Setting from to the ID of your RCS agent routes the message over RCS. The Agent ID is shown on the agent’s page in the Dashboard.

For the full request schema and authentication, see the Send a message API reference. To send SMS and MMS from the same endpoint, see Send and receive messages.

The Relay SDK sends RCS the same way: pass your agent’s ID as the sender, and the rules and errors on this page apply. To answer an inbound RCS message from a SWML script, see Reply with SWML.

Messaging rules

  • to must be a US phone number. Numbers in any other country, including Canada and US territories such as Puerto Rico, are rejected with rcs_recipient_country_not_supported. The examples below use +1555 placeholders, so replace them with a real US number.
  • The agent must be in_review, launching, or launched.
  • Send either body for plain text or content for rich content, never both.
  • media and message_type are not supported. Send media with a content of type media instead.
  • status_callback and custom_variables work the same way as for SMS, as described in Track delivery via REST.

Until the agent is launched, it can reach only the test device numbers registered on it. This isn’t checked when you send: a message to any other number is accepted with status: queued and isn’t delivered, so watch its delivery status rather than expecting a 422.

Content types

Set content.type to one of the following. Each value determines the other fields of content.

mediaobjectRequired
Sends a media file.
OR
locationobjectRequired
Sends a location pin.
OR
suggestionsobjectRequired
Sends text with suggestions the recipient can tap.
OR
cardobjectRequired
Sends a single rich card.
OR
carouselobjectRequired
Sends a horizontally scrolling set of rich cards.

Suggestions in actions take one of these types:

replyobjectRequired
A suggested reply. Tapping it sends a reply to your agent as an inbound message.
OR
urlobjectRequired
Opens a URL on the recipient's device.
OR
callobjectRequired
Starts a phone call from the recipient's device.
OR
locationobjectRequired
Shows a location on a map on the recipient's device.
OR
calendarobjectRequired
Adds an event to the recipient's calendar.
OR
request_locationobjectRequired
Asks the recipient to share their location. The location the recipient shares isn't delivered to your application.

Examples

Plain text

{
"to": "+15551234567",
"from": "<YOUR_AGENT_ID>",
"body": "Your appointment is confirmed for tomorrow at 2pm."
}

Text with suggested replies

{
"to": "+15551234567",
"from": "<YOUR_AGENT_ID>",
"content": {
"type": "suggestions",
"text": "Can you make your appointment tomorrow at 2pm?",
"actions": [
{ "type": "reply", "title": "Yes, confirm" },
{ "type": "reply", "title": "Reschedule" },
{ "type": "call", "title": "Call us", "phone": "+15557654321" }
]
}
}

Rich card

A card has a title and, optionally, a subtitle, a media URL, and suggestions.

{
"to": "+15551234567",
"from": "<YOUR_AGENT_ID>",
"content": {
"type": "card",
"title": "Your order has shipped",
"subtitle": "Order #12345 arrives Thursday.",
"media": "https://example.com/images/package.png",
"actions": [
{ "type": "url", "title": "Track your order", "url": "https://example.com/orders/12345" }
]
}
}

A carousel holds up to 10 cards and up to 3 suggestions under them.

{
"to": "+15551234567",
"from": "<YOUR_AGENT_ID>",
"content": {
"type": "carousel",
"cards": [
{
"title": "Classic sneaker",
"subtitle": "$89",
"media": "https://example.com/images/classic.png",
"actions": [{ "type": "url", "title": "Buy", "url": "https://example.com/products/classic" }]
},
{
"title": "Trail runner",
"subtitle": "$119",
"media": "https://example.com/images/trail.png",
"actions": [{ "type": "url", "title": "Buy", "url": "https://example.com/products/trail" }]
}
],
"actions": [
{ "type": "reply", "title": "Show me more" }
]
}
}

Verify the send

A successful request returns the message with kind: rcs and status: queued. For a rich message, body in the response holds your content serialized as a JSON string. Set status_callback to follow the message as its status changes, as described in Receive RCS messages.

When the request is rejected with a 422, the code says why. The RCS-specific codes, and the general messaging codes an RCS send most often hits, are:

CodeCause
invalid_from_numberfrom isn’t the ID of an RCS agent in this Project. Check for a typo, or an agent ID from another Project.
rcs_agent_not_sendableThe agent isn’t in_review, launching, or launched.
rcs_agent_not_configuredThe agent hasn’t been set up for sending messages yet.
rcs_messaging_not_enabledRCS isn’t enabled for this Space.
rcs_recipient_country_not_supportedto isn’t a US phone number.
body_not_allowed_with_rcs_contentThe request has both body and content.
rcs_media_not_supportedThe request has media. Use a content of type media instead.
rcs_message_type_not_supportedThe request has message_type. Use content instead.
rcs_content_missing_fieldA required field in content is missing. The error names its path.
rcs_content_invalid_valueA type or webview value isn’t allowed. The error lists the allowed values.
rcs_content_invalid_urlA URL in content isn’t a valid HTTP or HTTPS URL.
rcs_content_invalid_coordinateA latitude or longitude is out of range or not a number.
rcs_content_too_longA text field is longer than its maximum.
rcs_content_too_many_itemsA carousel has more than 10 cards or more than 3 suggestions.
rcs_content_not_an_object / rcs_content_not_an_arrayA field in content has the wrong JSON type.
rcs_content_not_supportedcontent was sent from a phone number instead of an RCS agent.
body_or_media_requiredThe request has neither body nor content.
character_limit_exceededbody is longer than the character limit. The error states the limit.
sending_restricted_to_verifiedYour account can send only to verified numbers, and to isn’t one of them.
not_routeableSignalWire can’t route a message to to.
insufficient_balanceYour account balance doesn’t cover the message.

For every other code, see Error codes.

Next steps