RCS Business Messaging
Preview
REST

Rich Cards & Media

Design guidelines and payload schemas for standalone rich cards, carousels, media heights (SHORT | MEDIUM | TALL), and suggestion types (reply, openUrl, dial). Optimised for mobile messaging clients used across Ghana and Africa.

Standalone cards

One media + title + description + up to 4 suggestions for focused CTAs

Carousels

2–10 scrollable cards for catalogues, plans, and multi-option journeys

Media heights

SHORT, MEDIUM, or TALL image/video frames matched to content importance

Suggestions

reply, openUrl, and dial chips that drive measurable engagement

Cards / carousel

2–10

min 2, max 10

Suggestions / card

≤ 4

chip actions

Title length

200

characters max

Description

2,000

characters max

Media height

Set media.height to control how tall the image or video appears on the card. Choose based on creative importance and scroll budget.

SHORT

Aspect: ~3:1 landscape band

Best for: Banners, logos, thin promo strips, status icons

Assets: Recommended ≥ 1440×480

MEDIUM

Aspect: ~2:1 / product hero

Best for: Default for products, receipts, maps, most campaigns

Assets: Recommended ≥ 1440×720

TALL

Aspect: ~4:5 / portrait emphasis

Best for: Fashion, food, lifestyle creatives that need visual impact

Assets: Recommended ≥ 1080×1350

FieldTypeRequiredDescription
media.heightSHORT | MEDIUM | TALL
required
Vertical size of the media frame on the card.
media.urlstring (HTTPS)
required
Public or signed HTTPS URL to JPEG/PNG/GIF/MP4. Max ~2 MB image, ~10 MB video (provider limits apply).
media.thumbnailUrlstring (HTTPS)optionalOptional preview while the main media loads (especially for video).
media.forceRefreshbooleanoptionalIf true, clients should bypass cached media for this URL. Default false.
JSON
"media": {
"height": "MEDIUM",
"url": "https://cdn.example.com/campaigns/accra-weekend.jpg",
"thumbnailUrl": "https://cdn.example.com/campaigns/accra-weekend-thumb.jpg",
"forceRefresh": false
}

Standalone rich card

Use type: "richCard" for a single focused message — delivery updates, payment receipts, one offer, or a support CTA. Pair with suggestions so users can act in one tap.

JSON
{
"to": "0244123456",
"agentId": "AGT-SENDXA-GH",
"type": "richCard",
"richCard": {
"title": "Delivery today — Osu, Accra",
"description": "Rider Kwame is 12 minutes away. Please keep your phone nearby for handover.",
"media": {
"height": "MEDIUM",
"url": "https://cdn.example.com/maps/osu-eta.png"
},
"suggestions": [
{
"type": "openUrl",
"text": "Live map",
"url": "https://track.example.com/GH-44102"
},
{
"type": "dial",
"text": "Call rider",
"phoneNumber": "+233244111222"
},
{
"type": "reply",
"text": "Leave at gate",
"postbackData": "instruction:leave_gate"
},
{
"type": "reply",
"text": "Reschedule",
"postbackData": "instruction:reschedule"
}
]
},
"fallback": {
"enabled": true,
"channel": "sms",
"from": "ShopGH",
"message": "Rider 12 min away (Osu). Track https://track.example.com/GH-44102 or call 0244111222"
}
}

Carousels present 2–10 cards in a horizontal scroller. Ideal for product catalogues, loan tiers, event tickets, or multi-branch locations. Keep card widths consistent; use the same media.height across cards for a polished look.

FieldTypeRequiredDescription
carousel.cardWidthSMALL | MEDIUMoptionalWidth of each card. MEDIUM (default) for richer media; SMALL for denser lists.
carousel.cardsRichCard[]
required
Array of 2–10 rich card objects.
JSON
{
"to": "233244123456",
"agentId": "AGT-SENDXA-GH",
"type": "carousel",
"carousel": {
"cardWidth": "MEDIUM",
"cards": [
{
"title": "Personal loan — GHS 5,000",
"description": "12 months · from 2.5% monthly · Instant decision",
"media": {
"height": "MEDIUM",
"url": "https://cdn.example.com/loans/tier-5k.jpg"
},
"suggestions": [
{
"type": "openUrl",
"text": "Apply",
"url": "https://bank.example.com/loans/5k"
},
{
"type": "reply",
"text": "More info",
"postbackData": "loan:5k:info"
}
]
},
{
"title": "Personal loan — GHS 15,000",
"description": "18 months · from 2.2% monthly · Salary account preferred",
"media": {
"height": "MEDIUM",
"url": "https://cdn.example.com/loans/tier-15k.jpg"
},
"suggestions": [
{
"type": "openUrl",
"text": "Apply",
"url": "https://bank.example.com/loans/15k"
},
{
"type": "reply",
"text": "More info",
"postbackData": "loan:15k:info"
}
]
},
{
"title": "Talk to an advisor",
"description": "Not sure which option fits? Our team in Accra & Kumasi can help.",
"media": {
"height": "MEDIUM",
"url": "https://cdn.example.com/loans/advisor.jpg"
},
"suggestions": [
{
"type": "dial",
"text": "Call now",
"phoneNumber": "+233302123456"
},
{
"type": "openUrl",
"text": "Book branch",
"url": "https://bank.example.com/branches"
}
]
}
]
},
"fallback": {
"enabled": true,
"channel": "sms",
"from": "MyBank",
"message": "Personal loans from GHS 5,000. Apply: https://bank.example.com/loans"
}
}

Suggestion types

Suggestions are tappable chips. They can sit on a text message, a standalone card, or individual carousel cards. Keep labels short (≤ 25 characters) so they fit on small screens.

reply

Sends a canned reply into the thread and emits rcs.suggestion_click / rcs.user_reply with your postbackData.

JSON
{
"type": "reply",
"text": "Confirm",
"postbackData": "order:confirm"
}
openUrl

Opens an HTTPS URL in the browser / in-app webview. Use for checkout, tracking, and deep links.

JSON
{
"type": "openUrl",
"text": "Track order",
"url": "https://track.example.com/x"
}
dial

Starts a phone call to an E.164 number. Ideal for support lines and rider contact in logistics.

JSON
{
"type": "dial",
"text": "Call support",
"phoneNumber": "+233302555010"
}
FieldTypeRequiredDescription
typereply | openUrl | dial
required
Suggestion behaviour.
textstring
required
Chip label. Max 25 characters recommended.
postbackDatastringoptionalRequired for reply. Opaque string returned on click/reply webhooks (max 2048).
urlstringoptionalRequired for openUrl. Must be https://.
phoneNumberstringoptionalRequired for dial. E.164 format (+233… for Ghana).

Design & content rules

HTTPS media only

Serve images/videos from a CDN with valid TLS. Avoid expired signed URLs.

Compress assets

Prefer JPEG/WebP under 500 KB for images; keep videos short and under provider caps.

Localise CTAs

Use clear Ghana English (or local language) and GHS pricing on commercial cards.

Accessible contrast

If text is baked into images, ensure readable contrast on small screens.

No localhost / private IPs

Media URLs must be reachable from the public internet.

Don’t overload chips

More than 4 card suggestions or long labels will truncate or reject.

Validation errors

CodeWhenFix
INVALID_RICH_CARDMissing title or invalid media heightProvide title; use SHORT|MEDIUM|TALL
INVALID_CAROUSELcards length not in 2–10Add or remove cards to fit range
INVALID_SUGGESTIONUnknown type or missing url/phoneNumberMatch fields to suggestion type
MEDIA_FETCH_FAILEDCDN URL unreachable at send timeVerify public HTTPS availability
SUGGESTION_LIMITMore than 4 suggestions on a cardTrim to 4 highest-value actions