Back to blog
FeaturesEngineering

Validate Before You Send: Pinnacle's Message Validation for SMS, MMS, and RCS

Pinnacle's validate endpoints give you a real-time dry run of any SMS, MMS, or RCS message before you commit to sending it — segment count, encoding detection, cost preview, media format checking, and RCS field limit enforcement. The most thorough pre-send validation in business messaging.

Ivan

·11 min read
Validate Before You Send: Pinnacle's Message Validation for SMS, MMS, and RCS

The Cost of Sending Blind

Most messaging APIs work the same way: you construct a message, call the send endpoint, and find out what happened afterward. Maybe it delivered. Maybe it failed because your media format wasn't supported. Maybe it split into four segments instead of one and you paid four times what you expected. Maybe your RCS card's button label was 27 characters instead of the allowed 25, and the entire request rejected.

The common thread: you only find out when it's too late — after you've paid, after the message failed, after the customer didn't get what they needed.

Pinnacle's validation endpoints change this model. Call validate before send and get the full picture: segment count, encoding, cost estimate, unsupported files, and field limit enforcement — all before a single message leaves the platform.


Three Validation Endpoints, One Pattern

Pinnacle exposes a validate endpoint for each message type. The pattern is identical to sending — same fields, same structure — but no message is dispatched and no credits are charged. It's a complete dry run.

POST /messages/validate/sms
POST /messages/validate/mms
POST /messages/validate/rcs

Or via the SDK:

TypeScript
import { PinnacleClient } from "rcs-js";
const client = new PinnacleClient({ apiKey: process.env.PINNACLE_API_KEY });
 
// Validate before committing to send
const result = await client.messages.sms.validate({ text: myMessage });

Run validation in your build pipeline, staging environment, or directly in your application before sending production traffic — the choice is yours.


SMS Validation: Segments, Encoding, and Cost

Of the three message types, SMS looks the simplest — it's just text. But SMS has a hidden complexity that catches engineers off guard: character encoding.

GSM-7 vs. Unicode

Standard SMS operates on the GSM-7 character set — the basic Latin alphabet, digits, and a handful of punctuation marks. A GSM-7 message fits 160 characters in a single segment.

The moment you include a character outside GSM-7 — an emoji, a curly quote, an em dash, an accented character — the entire message switches to Unicode encoding. A Unicode SMS fits only 70 characters per segment, not 160. That single emoji you added to make the message feel friendlier just more than doubled your segment count (and your cost).

Pinnacle's SMS validator catches this before it happens:

TypeScript
const result = await client.messages.sms.validate({
  text: "Your order has shipped! Track it here: https://pncl.to/abc123 🚚",
});
 
// Returns:
// {
//   segments: { gsm7: {...}, utf16: {...} },
//   total: { gsm7: 0.008, utf16: 0.012 },
//   isOverSegmentLimit: false
// }

That truck emoji triggered Unicode encoding. Without validation, this is invisible until you check your billing. With validation, you know before you send — and you can decide whether to remove the emoji and save a segment, or keep it and accept the cost.

What SMS Validation Checks

  • Segment count: How many 160-character (GSM-7) or 70-character (Unicode) segments your message will consume
  • Encoding type: gsm7 or unicode — tells you exactly which encoding will be applied
  • Estimated cost: The credit cost for sending this message, based on your current plan

MMS Validation: Media Formats and Unsupported Files

MMS is more complex than SMS: you're sending media files, and carrier support for file formats is not universal. A .webp image that renders beautifully in a browser might be completely unsupported by certain carriers. A video file that's too large will be rejected at the carrier level, never reaching the recipient.

Pinnacle's MMS validator checks your media URLs before you send:

TypeScript
const result = await client.messages.mms.validate({
  mediaUrls: [
    "https://cdn.yourapp.com/promo.jpg",
    "https://cdn.yourapp.com/product-demo.mp4",
  ],
  text: "Check out our new spring collection 👇",
});
 
// Returns:
// {
//   segments: 1,
//   unsupportedFiles: [],
//   estimatedCost: 0.02
// }

If a file format isn't supported, it surfaces in unsupportedFiles — before you've dispatched anything. Fix the format, re-validate, and send with confidence.

What MMS Validation Checks

  • Media format support: Identifies files that carriers won't accept, returned as unsupportedFiles
  • Segment count: MMS messages are counted differently from SMS — validation surfaces the actual count
  • Estimated cost: Per-message credit cost for the MMS

RCS Validation: Field Limits, Card Structure, and More

RCS messages are the richest and most structurally complex. A single RCS send can include up to 10 cards, each with a title, subtitle, media, and up to 4 action buttons — plus up to 10 quick replies at the bottom. Every one of these fields has strict limits enforced by the RCS specification:

FieldLimit
Text message3,000 characters max
Card title200 characters max
Card subtitle2,000 characters max
Button label25 characters max
Buttons per card4 max
Cards per message10 max
Quick replies10 max

A button label that's 26 characters instead of 25 will cause the entire RCS send to fail. A carousel with 11 cards will be rejected outright. These aren't soft warnings — they're hard limits enforced at the protocol level.

Pinnacle's RCS validator enforces every one of these constraints before you send:

TypeScript
const result = await client.messages.rcs.validate({
  cards: [
    {
      title: "Spring Sale — 30% Off Everything",
      subtitle: "Limited time. Shop now before it's gone.",
      media: "https://cdn.yourapp.com/spring-hero.jpg",
      buttons: [
        {
          type: "openUrl",
          title: "Shop Now",
          payload: "https://yourapp.com/sale",
        },
        { type: "trigger", title: "Get My Code", payload: "SPRING26" },
      ],
    },
  ],
  quickReplies: [{ type: "trigger", title: "Unsubscribe", payload: "STOP" }],
});
 
// Returns:
// {
//   segments: 1,
//   unsupportedFiles: [],
//   estimatedCost: 0.035
// }

If any field exceeds its limit — or if a media file isn't supported — validation returns an error before your message is dispatched. No failed send, no wasted credits, no confused recipient.

What RCS Validation Checks

  • Text length: Flags messages exceeding the 3,000-character limit
  • Card title length: Each card title checked against the 200-character max
  • Card subtitle length: Each subtitle checked against the 2,000-character max
  • Button label length: Every button and quick reply label checked against the 25-character max
  • Button count: Flags cards with more than 4 buttons
  • Card count: Flags carousels with more than 10 cards
  • Quick reply count: Flags messages with more than 10 quick replies
  • Media format support: Identifies unsupported file types before they cause delivery failure
  • Estimated cost: Per-message credit cost for the RCS message

The Validate-Then-Send Pattern

The intended usage is simple: call validate first, check the result, then send. In practice, this might look like:

TypeScript
async function sendSafeMessage(text: string, to: string, from: string) {
  // Step 1: Validate
  const validation = await client.messages.sms.validate({ text });
 
  // Step 2: Check segment count before committing
  if (validation.isOverSegmentLimit) {
    throw new Error(`Message exceeds the 10-segment limit. Trim the content.`);
  }
 
  // Step 3: Send
  return await client.messages.sms.send({ to, from, text });
}

This pattern is especially powerful for:

  • Dynamic messages: Templates where variable content could push a message over a segment boundary
  • AI-generated content: When an LLM writes your message text, validate before sending to catch encoding surprises and length overruns
  • Bulk pre-flight checks: Validate representative samples from your audience before a full blast
  • CI/CD pipelines: Catch message structure regressions before they reach production

Validation in AI Workflows via MCP

The Pinnacle MCP server exposes validate_sms, validate_mms, and validate_rcs as first-class tools — which means AI agents building messaging workflows can validate their own output before dispatching:

"Draft a promotional SMS about our spring sale, validate it to make sure it stays within one GSM-7 segment, and then send it to +14155551234."

The agent validates, sees the segment count, trims if needed, validates again, then sends — all without human intervention and without any wasted credits from trial-and-error sending.


Why This Matters More Than It Sounds

A pre-send validator might seem like a nice-to-have. In practice, the business consequences of not validating are real and quantifiable:

  • Unexpected costs from encoding surprises: A single emoji in a long SMS triggers Unicode encoding, cutting segment capacity from 160 to 70 characters. A 140-character GSM-7 message becomes a 2-segment Unicode message — double the cost, for every recipient. At 100,000 messages, that's 100,000 extra credits you didn't budget for. Validation surfaces this before the send, not on your invoice.
  • Silent delivery failures: An unsupported MMS media format gets dropped silently at the carrier level. The API returns success, but no media ever reaches the recipient. You don't know until customers start complaining — or don't, because they just quietly churned. With MMS validation, you catch unsupported formats before dispatch.
  • Rejected RCS sends: An RCS button label that's 26 characters instead of 25 rejects the entire message at the API level. A card with 5 buttons (max is 4) fails the whole send. For a blast to 50,000 recipients, a single field limit violation means zero messages delivered. Validation runs these checks before anything leaves the platform.
  • Campaign economics at scale: SMS marketing campaigns generate $41 for every $1 spent on average — but only when messages actually reach recipients. A malformed blast that fails, or one that unexpectedly costs 2x because of encoding, directly erodes that ROI. Validation is how you protect it.
  • Compliance risk: For high-stakes messages (two-factor auth, medical alerts, financial notifications), a failed or malformed send isn't just annoying — it's a support ticket, a churn event, or a regulatory incident. These are the messages where validation pays for itself most visibly.

Validation closes all of these gaps. It's the difference between testing in production and testing before production — and at any meaningful send volume, the savings dwarf the cost of one extra API call.


Frequently Asked Questions

Does validation count against my API rate limits?

No. Validate endpoints are read-only operations and are not subject to the same rate limits as send endpoints.

Does validation cost credits?

No. Validation is free — it's a dry run that returns metadata without dispatching any messages.

Can I validate a blast before sending to my entire audience?

The validate endpoint validates a single message (the message body), not the full blast operation. To pre-flight a blast, validate a representative message from your template, check the segment count and cost, and then proceed with the blast call.

Does validation guarantee delivery?

No. Validation confirms your message is structurally valid and compatible with carrier requirements. Actual delivery depends on network conditions, recipient device capabilities, and carrier routing.

Can I use validation in the dashboard?

The dashboard includes some built-in validation logic — it checks for common issues like missing fields and provides real-time previews as you compose. However, the full validation endpoints (/messages/validate/sms, /mms, /rcs) are more comprehensive: they return exact segment counts, encoding analysis, cost estimates, and unsupported file detection that the dashboard UI doesn't surface. For programmatic workflows or pre-send checks at scale, use the API or SDK.

What if my RCS media URL is accessible but the format isn't supported?

The MMS and RCS validators fetch and inspect your media URLs to determine format compatibility. If the file is accessible but the format isn't supported by carriers, it surfaces in unsupportedFiles. If the URL is unreachable, that's also reported.


Key Takeaways

  • Three endpoints: validate_sms, validate_mms, validate_rcs — same input schema as send, zero messages dispatched, zero credits charged
  • SMS encoding detection: Know whether your message is GSM-7 (160 chars/segment) or Unicode (70 chars/segment) before you send — and see the exact segment count
  • MMS media checking: Unsupported file formats are surfaced before delivery failure, not after
  • RCS field enforcement: Every character limit, card count, and button count checked against RCS spec before send
  • Cost preview: Know your exact credit cost before committing to a send or a blast
  • MCP-ready: AI agents can validate their own message output before dispatching — no human review required

Start Validating

Integrate validate before every send call in your production code. For the full API reference, see the validate SMS, validate MMS, and validate RCS endpoints.

If you're not yet on Pinnacle, sign up and subscribe to a plan to start sending. Questions about message validation, AI workflows, or enterprise integration? Get in touch or reach out to founders@pinnacle.sh.

logo

© 2025 Pinnacle Software Development, Inc.