← rcscheck.dev

RCS Spec Reference

All 47 validation rules applied by rcscheck.dev. Based on GSMA RCS Business Messaging spec r4.0 with per-aggregator overlays for Google RBM, Twilio, Sinch, and Infobip.

STRStructuralCARDRich CardSUGGSuggestions & ButtonsMEDIAMediaCARCarouselFBSMS Fallback
GSMA Base Limits (r4.0)
Message typeFieldLimit
TextbodyMax 3072 chars
TextsuggestionsMax 11
Rich cardtitleMax 200 chars
Rich carddescriptionMax 2000 chars
Rich cardsuggestions (Google RBM)Max 4
Rich cardsuggestions (Sinch)Max 2
Rich cardsuggestions (Infobip)Max 3
Rich cardimage heightSHORT, MEDIUM, or TALL
CarouselcardsMin 2, max 10
CarouselcardWidthSMALL or MEDIUM (uniform)
SuggestiontextMax 25 chars
SuggestionpostbackDataMax 2048 chars
SMS fallbacktextMax 1600 chars (10 segments)

STRStructural5 rules

STR-001errorall aggregators
Payload must be valid JSON
path$
fixEnsure the payload is valid JSON. Use a linter or formatter to check for syntax errors.
STR-002errorall aggregators
Payload root must contain a 'contentMessage' object
pathcontentMessage
fixWrap your message content in a 'contentMessage' object: { "contentMessage": { ... } }
STR-003errorall aggregators
contentMessage must contain exactly one message type: text, richCard, or carousel (via richCard.carouselRichCard)
pathcontentMessage
fixInclude exactly one of: contentMessage.text (string), contentMessage.richCard.standaloneCard, or contentMessage.richCard.carouselRichCard
STR-004errorall aggregators
contentMessage contains an unrecognised message type field
pathcontentMessage
fixRemove unrecognised fields. Valid message types are: text, richCard (with standaloneCard or carouselRichCard).
STR-005warningall aggregators
Payload exceeds recommended 5KB size
path$
fixReduce payload size by shortening text fields or using shorter image URLs. Most RCS payloads are under 2KB.

CARDRich Card7 rules

CARD-001errorall aggregators
cardOrientation must be VERTICAL or HORIZONTAL
pathcontentMessage.richCard.standaloneCard.cardOrientation
fixSet cardOrientation to either "VERTICAL" or "HORIZONTAL".
CARD-002errorall aggregators
HORIZONTAL cards must not include media
pathcontentMessage.richCard.standaloneCard.cardContent.media
fixRemove the media field from a HORIZONTAL card, or change cardOrientation to VERTICAL.
CARD-003errorall aggregators
title is required for standalone rich card
pathcontentMessage.richCard.standaloneCard.cardContent.title
fixAdd a title string to cardContent.
CARD-004errorall aggregators
title exceeds 200 character limit
pathcontentMessage.richCard.standaloneCard.cardContent.title
fixShorten the title to 200 characters or fewer.
CARD-005errorall aggregators
description exceeds 2000 character limit
pathcontentMessage.richCard.standaloneCard.cardContent.description
fixShorten the description to 2000 characters or fewer.
CARD-006warningall aggregators
title contains emoji — some carriers may strip or corrupt emoji characters
pathcontentMessage.richCard.standaloneCard.cardContent.title
fixConsider removing emoji from the title or test thoroughly across target carriers.
CARD-007errorall aggregators
thumbnailImageAlignment is only valid on HORIZONTAL cards
pathcontentMessage.richCard.standaloneCard.thumbnailImageAlignment
fixRemove thumbnailImageAlignment from VERTICAL cards, or change cardOrientation to HORIZONTAL.

SUGGSuggestions & Buttons10 rules

SUGG-001errorall aggregators
Maximum 11 suggestions per message (GSMA spec)
pathcontentMessage.suggestions
fixReduce suggestions to 11 or fewer.
SUGG-002errorgoogle
Standalone rich card maximum 4 suggestions (Google RBM)
pathcontentMessage.richCard.standaloneCard.cardContent.suggestions
fixReduce suggestions on this card to 4 or fewer for Google RBM.
SUGG-003errorsinch
Standalone rich card maximum 2 suggestions (Sinch)
pathcontentMessage.richCard.standaloneCard.cardContent.suggestions
fixReduce suggestions on this card to 2 or fewer for Sinch.
SUGG-004errorall aggregators
Suggestion text exceeds 25 character limit
pathcontentMessage.suggestions[*].text
fixShorten each suggestion label to 25 characters or fewer.
SUGG-005errorall aggregators
postbackData exceeds 2048 character limit
pathcontentMessage.suggestions[*].postbackData
fixShorten postbackData to 2048 characters or fewer. Consider using a shorter identifier and resolving the full data server-side.
SUGG-006errorall aggregators
openUrlAction.url must be a valid HTTPS URL
pathcontentMessage.suggestions[*].action.openUrlAction.url
fixEnsure the URL starts with https:// and is a valid, well-formed URL.
SUGG-007warningall aggregators
dialAction is not supported on iOS 18 — it will be silently dropped
pathcontentMessage.suggestions[*].action.dialAction
fixRemove dialAction suggestions or add a fallback for iOS users. Consider using a tel: URL in openUrlAction as an alternative.
SUGG-008warningall aggregators
shareLocationAction is not supported on all carriers
pathcontentMessage.suggestions[*].action.shareLocationAction
fixTest shareLocationAction with your target aggregator. It is unsupported by Twilio and may fail silently on others.
SUGG-009errorall aggregators
Duplicate suggestion text within the same message
pathcontentMessage.suggestions
fixEnsure each suggestion has a unique label. Duplicate labels confuse users and may be rejected by some aggregators.
SUGG-010infoall aggregators
More than 3 suggestions may be truncated on small screens
pathcontentMessage.suggestions
fixConsider limiting suggestions to 3 for the best UX on small screens. Additional suggestions may require scrolling.

MEDIAMedia8 rules

MEDIA-001errorall aggregators
fileUrl must be a valid HTTPS URL
pathcontentMessage.richCard.standaloneCard.cardContent.media.contentInfo.fileUrl
fixEnsure fileUrl starts with https:// and is a well-formed URL.
MEDIA-002warningall aggregators
fileUrl should be publicly accessible — private or authenticated URLs will fail at send time
pathcontentMessage.richCard.standaloneCard.cardContent.media.contentInfo.fileUrl
fixEnsure the image URL is publicly accessible without authentication. Use a CDN or public storage bucket.
MEDIA-003errorall aggregators
height must be SHORT, MEDIUM, or TALL
pathcontentMessage.richCard.standaloneCard.cardContent.media.height
fixSet media.height to one of: "SHORT", "MEDIUM", or "TALL".
MEDIA-004errorall aggregators
TALL height is only valid on VERTICAL card orientation
pathcontentMessage.richCard.standaloneCard.cardContent.media.height
fixChange media.height to SHORT or MEDIUM, or change cardOrientation to VERTICAL.
MEDIA-005warningall aggregators
Image file extension suggests an unsupported format. Use jpg, png, or webp.
pathcontentMessage.richCard.standaloneCard.cardContent.media.contentInfo.fileUrl
fixConvert your image to JPEG, PNG, or WebP format and re-upload.
MEDIA-006warningall aggregators
Image URL exceeds 2048 characters — some carriers may reject it
pathcontentMessage.richCard.standaloneCard.cardContent.media.contentInfo.fileUrl
fixUse a URL shortener or CDN with a shorter URL path.
MEDIA-007errorall aggregators
forceRefresh must be a boolean value
pathcontentMessage.richCard.standaloneCard.cardContent.media.contentInfo.forceRefresh
fixSet forceRefresh to true or false (not a string like "true").
MEDIA-008infoall aggregators
thumbnailUrl should match the image aspect ratio to avoid letterboxing
pathcontentMessage.richCard.standaloneCard.cardContent.media.contentInfo.thumbnailUrl
fixEnsure thumbnailUrl points to an image with the same aspect ratio as fileUrl to prevent letterboxing in the preview.

CARCarousel7 rules

CAR-001errorall aggregators
Carousel requires a minimum of 2 cards
pathcontentMessage.richCard.carouselRichCard.cardContents
fixAdd at least 2 cards to the carousel. Use a standalone rich card for single-card messages.
CAR-002errorall aggregators
Carousel maximum is 10 cards
pathcontentMessage.richCard.carouselRichCard.cardContents
fixReduce the carousel to 10 cards or fewer.
CAR-003errorall aggregators
All carousel cards must have the same cardWidth (SMALL or MEDIUM)
pathcontentMessage.richCard.carouselRichCard.cardWidth
fixSet a single cardWidth (either "SMALL" or "MEDIUM") on the carouselRichCard.
CAR-004errorall aggregators
SMALL cardWidth does not support media height TALL
pathcontentMessage.richCard.carouselRichCard.cardContents[*].cardContent.media.height
fixChange cardWidth to MEDIUM, or change media height to SHORT or MEDIUM.
CAR-005warningall aggregators
Carousel with more than 5 cards may result in poor UX on small screens
pathcontentMessage.richCard.carouselRichCard.cardContents
fixConsider limiting the carousel to 5 cards for the best experience on small screens.
CAR-006errorall aggregators
Each carousel card must have a title or description
pathcontentMessage.richCard.carouselRichCard.cardContents[*].cardContent
fixAdd a title or description to every card in the carousel.
CAR-007infoall aggregators
Carousel is not supported on all carriers — SMS fallback is especially important
pathcontentMessage.richCard.carouselRichCard
fixEnsure your contentMessage.fallback.text provides a useful SMS fallback that communicates the carousel's intent.

FBSMS Fallback6 rules

FB-001warningall aggregators
No SMS fallback text provided — messages will fail on non-RCS devices
pathcontentMessage.fallback.text
fixAdd a fallback text: { "contentMessage": { ..., "fallback": { "text": "Your message here" } } }
FB-002errorall aggregators
SMS fallback exceeds 1600 characters (10 segments)
pathcontentMessage.fallback.text
fixShorten the fallback text to 1600 characters or fewer.
FB-003infoall aggregators
SMS fallback exceeds 160 characters — will be sent as multi-part SMS
pathcontentMessage.fallback.text
fixThis is informational. Multi-part SMS works but costs more to send and may arrive out of order on some carriers.
FB-004warningall aggregators
SMS fallback contains a URL — verify it works standalone without buttons or actions
pathcontentMessage.fallback.text
fixEnsure any URLs in the fallback text are direct links that work without context. Avoid deeplinks that require the RCS app.
FB-005warningall aggregators
SMS fallback text appears auto-truncated — review for clarity
pathcontentMessage.fallback.text
fixRewrite the fallback to be a complete sentence rather than a truncated version of the rich card content.
FB-006infoall aggregators
SMS fallback text is identical to the card description — consider differentiating
pathcontentMessage.fallback.text
fixTailor the SMS fallback to work as a standalone message. Include a call-to-action URL if appropriate.
GSMA RCS Business Messaging r4.0GSMA source ↗