Skip to main content
SMS is billed per segment, not per message. Understanding segments saves you money on long or non-Latin sends.

GSM-7 vs UCS-2

SMS has two encodings:
EncodingCharacter setPer-segment cap (single)Per-segment cap (concatenated)
GSM-7Latin letters, digits, basic punctuation160 chars153 chars
UCS-2Unicode (emoji, Arabic, Chinese, …)70 chars67 chars
We detect the encoding automatically: the moment any character in your body falls outside the GSM-7 alphabet, the entire message switches to UCS-2 — you don’t get to send 160 Latin chars plus one emoji as one segment.

Examples

BodyLengthEncodingSegments
"Hello Chidi, your ride arrives in 3 min."42GSM-71
160 chars of Latin text160GSM-71
161 chars of Latin text161GSM-72 (99 + 62)
"Your ride is here! 🚗"20UCS-2 (because of 🚗)1
"Your ride is here! 🚗 " + repeated 60 chars80UCS-22
Preview the segment count before sending using POST /v1/sms-templates/:id/render for templates, or compute it locally:
function segments(body: string): { encoding: 'GSM7' | 'UCS2'; count: number } {
  const hasUnicode = /[^\x00-\x7F]/.test(body);
  const len = [...body].length;
  if (!hasUnicode) {
    return { encoding: 'GSM7', count: len <= 160 ? 1 : Math.ceil(len / 153) };
  }
  return { encoding: 'UCS2', count: len <= 70 ? 1 : Math.ceil(len / 67) };
}

Why the count drops on concatenation

Multi-segment SMS uses a small header on each part to tell the phone how to reassemble the message. That header eats 7 chars in GSM-7 and 3 characters in UCS-2 — so a “160-char” segment really only has 153 of your characters to work with once it’s concatenated.

Cost implications

A friendly emoji can 2x or 3x your cost if you weren’t expecting UCS-2:
"Thanks for signing up!"                  GSM-7 → 1 segment @ ₦4.00 = ₦4.00
"Thanks for signing up! 🎉"               UCS-2 → 1 segment @ ₦4.00 = ₦4.00
"Thanks for signing up! Visit ... 🎉"     UCS-2 → 2 segments @ ₦4.00 = ₦8.00  (same text, no emoji would be GSM-7 → 1 segment)

Best practices

Keep transactional under 160 GSM-7

Tight, no emoji, no fancy quotes. One segment per send.

Ascii-ify URLs

Don’t use URL shorteners with non-Latin chars — those force UCS-2.

Watch smart quotes

Word / Notes replace " with " and ' with ' — both UCS-2.

Preview campaign copy

Use the template render endpoint in CI to assert segment count ≤ 1.

Handy bytes worth avoiding

These tiny Unicode characters force the whole body to UCS-2:
  • " (U+201C) and " (U+201D) — curly quotes
  • ' (U+2019) — typographic apostrophe
  • (U+2026) — ellipsis
  • (U+2013) and (U+2014) — en/em dashes
  • Non-breaking space (U+00A0)
Replace with ", ', ..., -, --, and plain space respectively.