Support · Legal
Verified RCS · SMS · MMS

RCS API overview

Technical RCS & Developers

Reviewed by , VP of Global Operations, Signalmash · Last reviewed · Editorial standards

Quick answer

The RCS API is a REST interface for sending RCS messages from a verified agent and receiving user interactions via webhooks. You authenticate, check a number’s RCS capability, then POST a message (text, rich card, or carousel with suggestions) to a send endpoint addressed by your agent ID; inbound replies, taps, read receipts, and delivery events arrive at your configured webhook. With SimplyRCS, the same capabilities are available via API and the app at the same price, with SMS/MMS fallback handled automatically.

See this on your own phone in about 30 seconds: get a free sender ID test →

A typical send is an HTTPS POST with a JSON body describing the message. Following Google RBM conventions, a minimal text send looks like this (endpoint and IDs simplified):

POST https://{region}-rcsbusinessmessaging.googleapis.com/v1/phones/{E164_PHONE}/agentMessages?agentId={AGENT_ID}
Content-Type: application/json

{
  "contentMessage": {
    "text": "Your order #1043 has shipped 📦",
    "suggestions": [
      { "action": { "text": "Track", "postbackData": "track_1043",
        "openUrlAction": { "url": "https://shop.example/track/1043" } } }
    ]
  }
}

Before sending, call the capability check for the destination; if it isn’t RCS-capable, send via SMS/MMS instead (a good provider does this fallback for you).

The three things every RCS API does

Strip away naming differences between providers and an RCS API does three jobs.

It answers "can this number receive RCS?" RCS reach depends on the handset, the carrier, and the user's own settings, and it changes over time, so capability is a question you ask per number at send time rather than a property you store. Everything else follows from the answer.

It sends a message from a verified agent. The message is addressed from your approved sender rather than from a number, which is what produces the brand name, logo, and checkmark on the recipient's phone. The payload describes what the message contains: text, a rich card, a carousel, and the suggested replies or actions attached to it.

It delivers what happened back to you. RCS is two-way and event-rich in a way SMS is not. Beyond delivery, you receive read receipts, free-form replies, and taps on individual suggestions, each identifiable, so you can tell which button a customer pressed rather than only that they responded.

Authentication and environments

Access is credentialed per environment, so the keys that drive a staging integration are not the keys that can message real customers. This matters more in messaging than in most APIs, because a mistake is not a bad database write you can roll back, it is a message that has already arrived on someone's phone. Treat a production messaging credential with the same care as a payment credential, and rotate it on the same schedule.

Sending through the SimplyRCS API

The SimplyRCS API is documented as an OpenAPI 3.1 spec you can read without an account: the machine-readable spec is public. Everything below comes from it. Authenticate with either an Authorization: Bearer token or an X-API-Key header; both are accepted and both take the same key.

A send is one POST. The only required field is the contact:

curl -X POST https://simplyrcs.signalmash.com/v1/messages/send \\
  -H "Authorization: Bearer $SIMPLYRCS_API_KEY" \\
  -H "Content-Type: application/json" \\
  -H "Idempotency-Key: order-1043-shipped" \\
  -d '{
    "contactId": "ct_8f21",
    "channelType": "RCS",
    "messageType": "TRANSACTIONAL",
    "fallbackToSms": true,
    "content": {
      "type": "text",
      "text": "Your order #1043 has shipped.",
      "actions": [{ "text": "Track", "url": "https://shop.example/track/1043" }]
    }
  }'

The same call in Node, with the idempotency key derived from the thing you are notifying about rather than randomly generated, which is what makes a retry safe:

const res = await fetch("https://simplyrcs.signalmash.com/v1/messages/send", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.SIMPLYRCS_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": `order-${order.id}-shipped`,
  },
  body: JSON.stringify({
    contactId: order.contactId,
    channelType: "RCS",
    messageType: "TRANSACTIONAL",
    fallbackToSms: true,
    content: {
      type: "text",
      text: `Your order #${order.id} has shipped.`,
      actions: [{ text: "Track", url: order.trackingUrl }],
    },
  }),
});

if (!res.ok) throw new Error(`send failed: ${res.status} ${await res.text()}`);
const { messageId, fallbackUsed } = await res.json();

The response tells you what actually happened to it, which matters because RCS is not guaranteed to be the channel that delivered:

{
  "messageId": "...",
  "conversationId": "...",
  "status": "...",
  "billingType": "...",
  "providerMessageId": "...",
  "fallbackUsed": false,
  "fallbackChannelId": null
}

Three details in that call are easy to get wrong and expensive to get wrong.

messageType defaults to MARKETING. Omit it and the strictest consent gates apply, so a transactional receipt can be blocked for a contact who never opted into marketing. Set it explicitly on every send rather than relying on the default.

Idempotency-Key is how you survive a retry. Pass a printable-ASCII key up to 255 characters and a repeat of the same request replays the original response for 24 hours instead of sending a second message. A timeout on a messaging API is not like a timeout on a database write: without an idempotency key, the safe-looking retry is a duplicate message on a real phone.

Fallback is a field, not a fallback plan you build. Set fallbackToSms and read fallbackUsed on the response to know which channel carried it, since the two bill differently.

Errors come back shaped consistently. These are the live responses, not illustrations:

{ "error": "FST_ERR_VALIDATION", "message": "body must have required property 'contactId'" }
{ "error": "UNAUTHORIZED", "message": "Authorization header or X-API-Key header required" }

Two adjacent endpoints are worth knowing before you design the flow. GET /v1/contacts/{id}/rcs-check reports whether a contact can actually receive RCS, which is how you decide what to compose rather than discovering it at send time. POST /v1/messages/preview renders a message without sending it. There is also POST /v1/messages/{id}/revoke for pulling back a message that has not yet been delivered.

On rate limits, and what the spec does not say. Worth stating plainly, because the honest answer is more useful than a made-up number: the published spec documents no general rate limit for the messaging endpoints, and not one of its 143 paths declares a 429 response. The single documented limit sits on a public campaign-enrolment endpoint, at 10 requests per minute per IP, and does not describe the API as a whole.

Design as though a limit exists anyway. An undocumented ceiling is not the same as no ceiling, it is a ceiling you will discover in production. Handle non-2xx responses with backoff rather than an immediate retry loop, keep the idempotency key stable across those retries so a throttled call that actually succeeded cannot send twice, and confirm your expected throughput with support before a launch that depends on it.

Webhooks are registered through the API rather than a dashboard-only setting: POST /v1/webhook-endpoints takes a url and an events array, POST /v1/webhook-endpoints/{id}/test fires a test delivery, and GET /v1/webhook-endpoints/{id}/deliveries shows what was attempted and what happened. API keys are managed the same way, including POST /v1/api-keys/{id}/rotate, which mints a new secret while keeping the key id, name, scope, and expiry, and stops the old secret authenticating immediately.

Webhooks are where the real design work is

Most of the engineering effort in an RCS integration is inbound rather than outbound. Sending is a request; receiving is a system.

Three properties decide whether that system is sound. Signing lets you verify an event genuinely came from your provider rather than from anyone who found your endpoint, so the signature should be checked before the payload is trusted. Idempotency matters because delivery is at-least-once: the same event can legitimately arrive twice, and an integration that books two appointments from one reply is a bug in your handler rather than in the network. Keep the event identifier and discard repeats. Ordering and replay cover the rest, since your endpoint will eventually be down when something important happens, and the question is whether those events queue and redeliver or vanish.

Our own platform provides signed webhooks, idempotency keys, at-least-once delivery with deduplication, ordered conversation streams, event replay, and a dead-letter queue for events that never succeed. See the RCS webhook guide and RCS event types for what arrives and when.

Fallback is an API behaviour, not a feature you build

The single largest difference between RCS APIs is what happens when the recipient cannot receive RCS. If fallback is your responsibility, you are maintaining two integrations, two message formats, and your own logic for deciding between them, and you will get the edge cases wrong before your provider does.

Where fallback is handled for you, one send reaches the whole list: rich where possible, SMS or MMS everywhere else, with delivery reported per channel so you can see which messages landed as which. That per-channel reporting is worth asking about specifically, because a provider that only reports "delivered" cannot tell you what the rich format is actually earning you. See RCS fallback to SMS.

Throughput and what governs it

Sending limits in the US are not set by your provider's infrastructure but by your registration. Your brand and campaign records produce a trust score, and that score governs how much you may send per day. An integration that works in testing and throttles in production is usually hitting that ceiling rather than an API limit. See how 10DLC registration works, since the same registration also governs the SMS fallback leg.

MCP for AI agents

Alongside the REST interface, SimplyRCS exposes an MCP server, which lets an AI agent use messaging as a tool through standard tool calls rather than through bespoke integration code. That is a meaningfully different integration path from a conventional API: the agent discovers what it can do rather than being programmed against a fixed contract. Few providers offer it.

It lives at /v1/mcp on the same host as the REST API, with a Server-Sent Events transport at /v1/mcp/sse, and it authenticates with the same API key and the same two header forms as everything else. That last point matters more than it sounds: there is no separate credential system for the agent path, so an API key you have already scoped and can already rotate is the same key the agent uses.

The practical difference is what you write. Against the REST API you write the integration: which endpoint, which fields, what to do with the response. Against MCP you grant a capability and the agent works out the call. For a bot that needs to check whether a contact can receive RCS, send accordingly, and read the delivery result back, that is the difference between an integration you maintain and a tool you expose once. See RCS and AI agents.

The Google RBM API, and how providers wrap it

Underneath every RCS API on the market is one API: Google's RCS Business Messaging (RBM) API, which is how an approved agent sends messages, receives replies and events, and checks whether a number can take RCS. Google does not sell it to businesses directly; access runs through approved partners, and that is where the differences between providers begin. A provider's RCS API is the RBM API plus everything Google leaves to the partner:

  • Agent management and verification. Creating the agent, submitting it to Google and the carriers, and keeping its use case in good standing. On SimplyRCS this is filed for you; on a self-serve API it is your project.
  • The fallback leg. RBM only sends RCS. Delivering the same message as SMS or MMS to a phone that cannot take RCS, from a registered number, is the provider's job, and so is reporting which channel each recipient actually got.
  • Consent gating and compliance. Opt-in state, STOP and HELP handling, quiet hours and use-case matching sit above the RBM call.
  • One event stream. RBM events, SMS delivery receipts and inbound replies arrive from different places; the provider normalises them into one set of webhooks.
  • Billing. RBM has no rate card of its own that a business pays; the per-message price, the carrier fees and any platform fee are set by the provider.

The practical consequence for a developer is that "Google RCS API" is not something you can integrate with on your own, and comparing providers means comparing the wrapper: what it files for you, what it falls back to, what it reports, and what it charges.

The Twilio RCS API, and what to check against it

Twilio is the API most teams have already used for SMS, so "can we just send RCS through Twilio?" is usually the first question rather than the last. It reached general availability for RCS on US carriers in 2025, and the API surface is mature, well documented, and global. If your team is already building on Twilio and wants RCS as one more channel in code, that is a legitimate answer.

Three differences are worth checking before you assume the SMS integration extends cleanly.

There is no application layer. Twilio is API-first by design: no built-in campaign builder, no shared inbox, no message preview. Whatever a non-engineer needs to see or send, you build. That is a feature if you are embedding messaging in your own product, and a hidden project cost if a marketing team is the actual user.

RCS is priced by message class. Twilio's published US rates put RCS basic text at roughly $0.0083 per message and rich media at roughly $0.0220 to send and $0.0165 to receive, plus carrier fees, number rentals, and a per-failed-message charge. A rich card therefore costs multiples of the plain text it replaces, which quietly argues against using the format the channel exists for. Full rate card and a worked 100,000-message example are on Twilio RCS pricing.

Carrier registration is yours to file. Brand, campaign, and RCS agent submissions are self-serve, with no approval SLA. That is fine when you have someone who has done it before, and it is the usual cause of a launch date slipping when you do not.

For comparison, the SimplyRCS API charges the same rate for a rich card as for a plain text, handles the RCS-to-SMS fallback decision per recipient inside a single send, files the carrier registrations for you, and prices the API identically to the application, so the same $250 per month per RCS Agent covers both. It is US-only, which is the trade: if you need to send to more than one country, Twilio's footprint is wider and that matters more than any of the above.

RCS API pricing compared

Most RCS API evaluations stall on the same problem: four of the seven providers a US team will shortlist do not publish a per-message rate at all, so half the comparison arrives as a quote weeks later. Here is what is actually on the public rate cards, for the two message classes that carry almost all business traffic.

API RCS text or interactive card RCS carrying media
SimplyRCS $0.0039 per message $0.0150 per message
Twilio ~$0.0083 per message ~$0.0220 sent, ~$0.0165 received
Telnyx RCS $0.0065 per segment $0.016 per message
Plivo RCS $0.0077 per segment $0.0180 per message
Bandwidth Not published, negotiated Not published, negotiated
Infobip RCS Not published, quote only Not published, quote only
Sinch Not published, quote only Not published, quote only
Vonage Not published for the US Not published for the US

Published US figures as of September 2026. Verify current pricing with each provider directly; the workings behind each row, including the fees that are not per message, are on that provider's comparison page, starting with Twilio RCS pricing, Telnyx, Plivo and Infobip.

What a per-message RCS API rate does not tell you

Whether the meter runs per segment or per message. Telnyx and Plivo bill rich text by segment, the way SMS is billed, so a long message is several billable units. RCS carries up to 3,072 characters in one message, so a per-message rate and a per-segment rate at similar-looking numbers are not the same price for anything longer than a line or two. The RCS character limit has the segment maths.

Where the line between the two classes falls. Every provider charges more for media than for text, and each one decides differently whether a card with buttons and no attached image counts as the cheap class or the expensive one. Since suggested actions and reply chips are the reason most programmes adopt RCS at all, that single boundary can matter more to a forecast than the headline rate does.

What sits on top of every message. Carrier surcharges are passed through by all of these providers rather than absorbed, and they scale exactly as volume does. Twilio publishes its per-carrier fees beside each rate, $0.0025 to $0.02 per message depending on carrier and message type. They belong in the forecast whatever the rate card says.

What you pay before the first send, and what you build yourself. Brand and campaign registration, RCS agent verification, and number rentals are all pre-send costs, and on a self-serve platform you file them. So is the campaign builder, the shared inbox and the approval queue, which appear on no rate card because the API providers expect you to build them. That build is usually the largest number in the comparison and the only one nobody quotes.

SimplyRCS prices the API identically to the application, so the same $250 per month per verified RCS Agent covers both the endpoints here and the whole RCS business messaging platform, and there is no separate API tier. The full endpoint reference, the webhook payloads and the MCP endpoints are public and readable without an account at SimplyRCS for developers, and every rate is on the pricing page.

What to compare when evaluating an API

Beyond endpoints, the questions worth asking are: is fallback automatic and reported per channel; are webhooks signed, idempotent, and replayable; are credentials environment-scoped; does the provider handle brand and carrier registration or hand you the paperwork; and is the API priced the same as the dashboard. On SimplyRCS the API and the app carry the same capabilities at the same published price.

Frequently asked

Do I need a different integration for SMS fallback?

Not with a provider that handles it. One send reaches the whole list: rich where the recipient can receive RCS, SMS or MMS everywhere else, with delivery reported per channel. Where fallback is your responsibility you are maintaining two integrations and two message formats, and the edge cases are where that goes wrong.

Why do I need to check capability before every send?

Because RCS reach depends on the handset, the carrier, and the user’s own settings, and all three change. Capability is a question you ask per number at send time rather than a value you cache, which is why a contact who received RCS last month may need fallback today.

What stops a duplicate webhook from double-processing?

Nothing, unless you build for it. Event delivery is at-least-once by design, so the same reply can legitimately arrive twice. Store the event identifier and discard repeats. An integration that books two appointments from one customer reply is a bug in the handler rather than in the network.

What actually limits how fast I can send?

Your registration, not the API. Brand and campaign records produce a trust score, and that score governs daily throughput. An integration that works in testing and throttles in production is usually hitting that ceiling, which is why 10DLC registration matters even for an RCS-first programme.

How much does an RCS API cost per message?

Only four of the major providers publish a US rate at all. SimplyRCS is $0.0039 for an RCS text or an interactive card and $0.0150 for a message carrying media. Twilio publishes roughly $0.0083 basic and $0.0220 for rich media sent, Telnyx $0.0065 per rich text segment and $0.016 for rich media, and Plivo $0.0077 per rich text segment and $0.0180 for rich media. Bandwidth, Infobip, Sinch and Vonage quote privately. Carrier surcharges are passed through on top by all of them.

How does the Twilio RCS API compare on price?

Twilio publishes about $0.0083 per basic RCS message and about $0.0220 to send rich media, against $0.0039 and $0.0150 on SimplyRCS, and adds number rentals, a $0.001 failed-message fee and self-filed registration. The larger difference is the application layer: Twilio is API-only, so the campaign builder, shared inbox and approval queue are yours to build, while SimplyRCS prices the API and the app the same and includes both in the $250 per month per RCS Agent.

Is the SimplyRCS API priced differently from the dashboard?

No. The same $250 per month per verified RCS Agent covers the API, the application, the bot builder, the shared inbox and analytics, and messages bill at the same published rate whichever one sends them. There is no separate developer tier and no per-seat licence.

The fastest way to understand RCS is to receive one. Get a free sender ID test →

← All RCS questions