Skip to content

RCS

This guide walks you through sending your first RCS message using the InstaMessage Messaging API.

RCS (Rich Communication Services) is the next generation of SMS. It shows your verified brand name and logo, and supports images, video, files, rich cards and suggested reply buttons, all in the recipient's native messaging app.

You'll learn how to authenticate, send RCS text, media and rich messages, personalise content using injected_fields, and understand the API response.


Before you begin

To send RCS messages through InstaMessage, you'll need the following:


1. An InstaMessage account

If you're new to InstaMessage, contact our sales team to set up your account:

[email protected]


2. A verified RCS agent

RCS messages are sent from an RCS agent (your verified brand sender), not a phone number.

Each agent must be registered and approved by Google and the mobile carriers before it can send messages. This includes your brand name, logo, colour, description and use case.

To get your RCS agent set up, contact our team:

[email protected]

Once approved, the agent is connected to your InstaMessage account and becomes the sender for all RCS messages sent via the API. You don't pass a sender in your requests.

Carrier approval and country availability apply. RCS can only be delivered to recipients whose device and carrier support RCS.


3. Your API key

You can find your API key in the InstaMessage dashboard:

  1. Go to Admin → API
  2. Select Show Key under API Live Key
  3. Copy your API Key
Where to find your API key in the InstaMessage dashboard

Your API key is tied to your InstaMessage account and authorises access to all InstaMessage APIs.

Important: Treat your API key like a password. Never share it publicly or commit it to source control.

Each account has a single active API key. Subaccounts and environments will be supported in future.


Authentication method

InstaMessage uses API key authentication.

Each API request must include a valid API key issued to your account.

Authorization: Bearer YOUR_API_KEY

RCS Endpoint

All RCS messages are sent using the unified messaging endpoint:

POST https://api.instamessage.co.uk/v1/messages

4. Required fields for sending RCS

Required fields

FieldDescription
channelMust be "rcs"
toE.164 formatted number (Example: +447123456789)
message_type"text", "image", "video", "file" or "custom"

Conditional fields

FieldRequired whenDescription
textmessage_type = textBody of the message. Up to 3,000 characters; longer text is rejected with error 4043.
imagemessage_type = imageObject containing url. JPEG, PNG or GIF.
videomessage_type = videoObject containing url. MP4, M4V, MPEG, WEBM or H.263.
filemessage_type = fileObject containing url. PDF only.
custommessage_type = customRich content object (rich cards, carousels, suggestions). See Rich messages.

Media URLs must be publicly accessible over HTTPS and up to 2,000 characters; longer URLs are rejected with error 4045. Media files can be up to 100 MB. Captions are not supported on RCS media messages; send a separate text message if you need one.

Templates (message_type: "template") and audio messages are not supported on RCS.


Example — Image

{
  "channel": "rcs",
  "to": "+447123456789",
  "message_type": "image",
  "image": {
    "url": "https://example.com/images/order-12345.png"
  }
}

Example — Video

{
  "channel": "rcs",
  "to": "+447123456789",
  "message_type": "video",
  "video": {
    "url": "https://example.com/videos/how-to-return.mp4"
  }
}

Example — File

{
  "channel": "rcs",
  "to": "+447123456789",
  "message_type": "file",
  "file": {
    "url": "https://example.com/invoices/INV-12345.pdf"
  }
}

Rich messages (custom)

Use message_type: "custom" to send rich cards, carousels and suggested replies or actions.

The custom object must contain a contentMessage, following the Google RCS Business Messaging (RBM) AgentContentMessage format. InstaMessage checks it against the rich content limits, then passes it through to the recipient unchanged.

Text with suggested replies

A message can carry up to 11 suggestions. When the recipient taps a suggested reply, it arrives as an inbound message.

{
  "channel": "rcs",
  "to": "+447123456789",
  "message_type": "custom",
  "custom": {
    "contentMessage": {
      "text": "Your delivery is booked for tomorrow. Does that work?",
      "suggestions": [
        { "reply": { "text": "Yes, thanks", "postbackData": "CONFIRM" } },
        { "reply": { "text": "Reschedule", "postbackData": "RESCHEDULE" } },
        {
          "action": {
            "text": "Track order",
            "postbackData": "TRACK",
            "openUrlAction": { "url": "https://example.com/track/12345" }
          }
        }
      ]
    }
  }
}

Rich card

{
  "channel": "rcs",
  "to": "+447123456789",
  "message_type": "custom",
  "custom": {
    "contentMessage": {
      "richCard": {
        "standaloneCard": {
          "cardOrientation": "VERTICAL",
          "cardContent": {
            "title": "Your order is on its way",
            "description": "Order 12345 will arrive today between 10:00 and 12:00.",
            "media": {
              "height": "MEDIUM",
              "contentInfo": {
                "fileUrl": "https://example.com/images/van.png",
                "forceRefresh": false
              }
            },
            "suggestions": [
              {
                "action": {
                  "text": "Track order",
                  "postbackData": "TRACK",
                  "openUrlAction": { "url": "https://example.com/track/12345" }
                }
              }
            ]
          }
        }
      }
    }
  }
}
{
  "channel": "rcs",
  "to": "+447123456789",
  "message_type": "custom",
  "custom": {
    "contentMessage": {
      "richCard": {
        "carouselCard": {
          "cardWidth": "MEDIUM",
          "cardContents": [
            {
              "title": "Classic Hoodie",
              "description": "£45.00",
              "media": {
                "height": "MEDIUM",
                "contentInfo": { "fileUrl": "https://example.com/images/hoodie.png" }
              },
              "suggestions": [
                { "reply": { "text": "Buy hoodie", "postbackData": "BUY_HOODIE" } }
              ]
            },
            {
              "title": "Everyday Tee",
              "description": "£20.00",
              "media": {
                "height": "MEDIUM",
                "contentInfo": { "fileUrl": "https://example.com/images/tee.png" }
              },
              "suggestions": [
                { "reply": { "text": "Buy tee", "postbackData": "BUY_TEE" } }
              ]
            }
          ]
        }
      }
    }
  }
}

Rich content limits

InstaMessage checks custom against the Google RBM and Vonage limits before accepting the message. A payload that breaks a limit is rejected with a 400 and error 4044, and the message names the rule, so nothing is sent or charged.

WhereLimit
customMust contain a contentMessage object. At most 250 KB (250,000 bytes) as JSON.
contentMessageExactly one of text, richCard, contentInfo, uploadedRbmFile or fileName. text up to 3,000 characters. Up to 11 suggestions.
richCardExactly one of standaloneCard or carouselCard.
standaloneCardcardOrientation is required: HORIZONTAL or VERTICAL. thumbnailImageAlignment, if set: LEFT or RIGHT. cardContent is required. A HORIZONTAL card with media also needs a title, description or suggestions.
carouselCard2 to 10 cards in cardContents. cardWidth, if set: SMALL or MEDIUM.
Card contentAt least one of media, title or description. title up to 200 characters, description up to 2,000. Up to 4 suggestions.
mediaheight, if set: SHORT, MEDIUM or TALL. Exactly one of contentInfo, uploadedRbmFile or fileName. contentInfo.fileUrl must be an http(s) URL of up to 2,000 characters.
SuggestionExactly one of reply or action. text is required, up to 25 characters. For an action, postbackData and fallbackUrl up to 2,048 characters.

Other fields are passed through as sent. A field set to null counts as not set.

Example — Rich content error

{
  "code": 4044,
  "message": "Invalid RCS rich content: carouselCard.cardContents must have 2-10 cards"
}

Rich card media must be an image or video. PDFs can't be used in cards.

These checks cover the payload's structure only. Media file types and sizes are checked when the message is sent, so an unsupported file still fails at delivery.


5. Optional fields

FieldDescription
opt_out_url"true" (if a marketing message). When set to true, appends the account's configured opt-out URL to the end of the message. Applies to text messages only.
injected_fieldsPersonalisation values for placeholders such as {{first_name}}. Applies to text messages only.
  • injected_fields are applied at send time and do not modify stored contact data.
  • If a contact exists, InstaMessage can also use stored contact fields and custom attributes.
  • If a field exists in both places, injected_fields takes precedence.

Example precedence

  • Contact first_name = "Adam"
  • You send injected_fields.first_name = "Eve"
  • {{first_name}} renders as "Eve"

RCS billing

How an RCS message is charged depends on your agent's billing category and the content you send.

Per-message pricing (default)

  • Basic message: a text message of up to 160 characters
  • Rich message: a text message over 160 characters, or any image, video, file or custom message

Conversational agents

If your agent is registered as conversational, a reply from the recipient opens a 24-hour conversation window:

  • The first message you send inside the window is charged a single conversation fee
  • Every further message you send in that window is free
  • Messages sent outside a window use per-message pricing

Contact your account manager for RCS pricing in your region.


RCS Messaging Rules

  • RCS messages are sent immediately
  • Messages are sent from your approved RCS agent. You can't choose a different sender per message
  • The recipient's device and carrier must support RCS
  • Media URLs must be publicly reachable when the message is sent

Delivery status webhooks

InstaMessage reports delivery outcomes and inbound replies using account-level webhooks.

Webhooks are configured once per account and apply to all messages sent via the API.

Delivery status webhooks

When a message status updates (such as delivered, read or failed), InstaMessage sends a delivery status webhook to your configured webhook URL.

Replies and suggestion taps from the recipient are delivered as inbound message webhooks.

Example delivery status webhook payload

{
  "event_type": "message.status",
  "message_id": "abc123XYZ789def",
  "conversation_id": "conv456ABC123",
  "channel": "rcs",
  "to": "+447123456789",
  "status": "delivered",
  "timestamp": "2026-01-14T12:03:11Z"
}

Delivery status lookup (fallback)

If you miss a webhook delivery, you can retrieve the latest delivery status using the message ID returned when the message was created.

See: Delivery tracking → Delivery Receipts & Message Status

This endpoint acts as a recovery mechanism if a webhook delivery is missed.

Example message status response:

{
  "message_id": "abc123XYZ789def",
  "conversation_id": "conv456ABC123",
  "channel": "rcs",
  "to": "+447123456789",
  "status": "delivered",
  "created_at": "2026-01-14T12:02:10Z",
  "delivered_at": "2026-01-14T12:03:11Z"
}

6. Send your first RCS message

Below is a basic example in multiple languages.

curl -X POST "https://api.instamessage.co.uk/v1/messages" \
  -H "Authorization: Bearer $IM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "rcs",
    "to": "+447123456789",
    "message_type": "text",
    "text": "Your delivery is on its way."
  }'

7. Personalise your RCS message

Use placeholders inside your text and supply values via injected_fields.

Example — Personalised RCS message

{
  "channel": "rcs",
  "to": "+447123456789",
  "message_type": "text",
  "text": "Hi {{first_name}}, your order {{order}} is out for delivery today.",
  "injected_fields": {
    "first_name": "Alex",
    "order": "12345"
  }
}

Rendered output:

Hi Alex, your order 12345 is out for delivery today.


8. Example API response

{
  "message_id": "abc123XYZ789def",
  "conversation_id": "conv456ABC123"
}

Delivery status and timestamps are provided asynchronously via webhooks or can be retrieved using the message ID.


9. Validation errors

Requests that fail validation return HTTP 400 with a code and message. No message is created and nothing is charged.

CodeMessageWhen
4005Message recipient not specifiedto is missing
4006Invalid phone numberto isn't a valid phone number
4008Message type not supportedmessage_type isn't text, image, video, file or custom (for example audio or template)
4009Message content not specifiedThe field for the message_type is missing (for example message_type: "image" without image)
4043Message text too longtext is over 3,000 characters
4044Invalid RCS rich content: rulecustom breaks one of the rich content limits
4045Media URL too longimage.url, video.url or file.url is over 2,000 characters

Next steps

Now that you can send RCS, you may want to: