The Sailup team · · 12 min read
SMS Character Limits in Ghana: Why One Curly Quote Turns 160 Characters into 70
A plain SMS holds 160 GSM-7 characters. One cedi sign, curly quote or emoji switches the whole message to Unicode and the limit drops to 70, so a 149-character promo costs three credits instead of one.
A single SMS carries 160 characters, but only if every character in it belongs to the GSM-7 alphabet. One character from outside that alphabet (a cedi sign, a curly quote pasted from Word or an emoji all qualify) switches the whole message to Unicode, where the limit is 70. Past the limit the message is split into segments of 153 (GSM-7) or 67 (Unicode) characters, and every segment costs one credit per recipient at ₵0.02. So a 149-character promo with a single ₵ in it costs three credits per person, and the same promo with "GHS" costs one.
That is the whole post in a paragraph. The rest is the detail: where the numbers come from, which characters trip up Ghanaian senders most often, and how to see the count before you pay for it.
The quick reference
| Encoding | How characters are counted | Single message | Per segment when split |
|---|---|---|---|
| GSM-7 | One per character; the nine extension characters ^ { } \ [ ] ~ | € count as two each | 160 | 153 |
| UCS-2 (Unicode) | One per UTF-16 code unit, so most emoji count as two | 70 | 67 |
Two rules sit under that table. Encoding is decided for the whole message, not per character: one Unicode character anywhere in the body and every character is counted at the Unicode rate. And segments are what you pay for: one credit per segment per recipient, so a two-segment message to 5,000 people is 10,000 credits.
Where 160 and 70 come from
An SMS body is 140 octets. That is fixed by the standard, 3GPP TS 23.038, which also defines the GSM 7-bit alphabet. Pack seven-bit characters into 140 octets and you get 140 × 8 ÷ 7 = 160 of them. That is the only reason the number is 160, and no provider can raise it.
UCS-2 spends two octets on every character, so the same 140 octets hold 70.
The GSM-7 basic set is small: plain Latin letters, digits, common punctuation, a handful of accented letters (é è ù ì ò à ü ö ä ñ, and the capitals Ç É Ä Ö Ñ Ü Å Æ Ø), plus £ $ ¥ and a few Greek capitals. It does not have á í ó ú or ç, and it does not have the cedi sign in either form.
What flips a message to Unicode in Ghana
Almost nobody sets out to write a 70-character message. The flip is nearly always an accident: copy pasted from Word, a phone keyboard that curls quotes on its own, a currency sign added because it looks right. These are the usual triggers in Ghana.
| Trigger | Where it usually comes from | Safe substitute |
|---|---|---|
| ₵ and ¢ | Typing a price as GH₵50 | GHS 50 or GHc50 |
| ɛ ɔ ŋ | Twi, Ga and other Ghanaian languages | Plain e, o and n, as most people already type them on a phone, or keep them and accept the 70 limit |
| ‘ ’ “ ” | Word, Google Docs and most phone keyboards convert straight quotes automatically | Straight quotes, ' and " |
| – and — | Word turns a hyphen between two spaces into a dash | A plain hyphen, or a full stop |
| … | Typing three dots in Word or on iOS | Three full stops |
| Emoji | Phone keyboards | Leave it out. One emoji costs two Unicode characters and drags the other 68 with it |
| á í ó ú ç | Names and borrowed words | Unaccented letters, unless the name matters more than the segment |
The cedi sign deserves its own line. ₵ is the official sign, ¢ is what many keyboards offer instead, and neither is in GSM-7. Put GH₵50 anywhere in a promo and the whole promo is Unicode. Write GHS 50, or GHc50 if you prefer the look; every reader in Ghana knows what it means.
Twi is a harder call, because sometimes the letters are the point. Yɛda wo ase, Efua. Your GHS 50 top-up is done. is 46 characters and fits in one Unicode segment with room to spare, so short messages in Twi cost nothing extra. It is the 150-character Twi promo that costs three credits. For that, either spell it the way most people do on a phone keyboard (Yeda wo ase) or keep the letters and budget for the extra segments on purpose.
Quote marks are the sneaky one because the change is invisible in most editors. With straight quotes, Kwame, use code "SEPT10" at our Accra Mall shop till 6pm today for GHS 10 off. Reply STOP to 020 XXX XXXX to opt out. is 117 characters and one segment. Paste the same line out of a Word document, where the quotes have quietly become “ and ”, and it is 117 Unicode characters, which is two segments. Same words, double the cost.
The nine GSM-7 characters that cost two
GSM-7 has a small extension table reached through an escape character. Anything on it takes two septets, the escape and then the character itself. These are the nine you will meet:
| Character | Name | Cost |
|---|---|---|
^ | caret | 2 |
{ and } | curly braces | 2 each |
[ and ] | square brackets | 2 each |
\ | backslash | 2 |
~ | tilde | 2 |
| | vertical bar | 2 |
€ | euro sign | 2 |
These do not flip the message to Unicode. They just count double, which matters near the edge. [Adwoa Pharmacy] Your prescription is ready for pickup at our Kumasi branch. is 76 characters but 78 septets, and a 158-character message with that prefix is 160 septets, right on the line. Square brackets around a brand name are the most common way to lose two characters without noticing. Your sender ID already says who you are, so the prefix can go.
Merge fields in dashboard campaigns are written with braces, {{first_name}} and {{attributes.branch}}, but the braces never reach the handset; the contact's name does. What you cannot know in advance is how long that name is, so leave room for the longest one on your list.
How a long message is split
When a message runs past 160 GSM-7 characters (or 70 in Unicode), it goes out as several SMS. Each part carries a small user data header saying which message it belongs to and which part it is, and the handset stitches them back together, which is why the recipient sees one long message rather than three short ones.
That header takes 6 octets out of the 140. What is left is 134 octets, which holds 153 seven-bit characters or 67 UCS-2 characters. That is where 153 and 67 come from, and it is why a two-segment message holds 306 characters rather than 320.
Sailup does the splitting, before the message reaches the carrier. You send one body to POST /v1/sms/ or type one in the campaign editor; Sailup encodes it, cuts it into parts and hands the carrier each part with its header attached. Each part is billed as one credit. If you have seen 152 and 66 quoted elsewhere, that is the same header with a 16-bit reference number, which takes 7 octets. Sailup's counter uses 153 and 67.
A worked example: one cedi sign, three credits
Here is a promo a salon in Osu might send, exactly as first typed:
Ama, this Saturday only: 20% off braids at Osu Beauty Bar. Knotless braids now GH₵80. Book on 024 XXX XXXX. Reply STOP to the same number to opt out.
That is 149 characters. Everything in it is GSM-7 except the ₵, and the ₵ is enough. The message is counted as Unicode: 149 characters at 67 per segment is 67 + 67 + 15, so three segments and three credits per recipient.
Swap the sign for letters:
Ama, this Saturday only: 20% off braids at Osu Beauty Bar. Knotless braids now GHS 80. Book on 024 XXX XXXX. Reply STOP to the same number to opt out.
Now it is 150 characters, one longer than before, and one segment. Same offer, same deadline, same opt-out line pointing at the salon's own number (Sailup cannot receive replies, so a STOP line has to name a line you monitor; the call-to-action post covers this). The recipient sees no difference except that the price is spelt in letters. The sender pays a third as much.
This is the usual pattern. The message was already close to 160, and one character pushed it onto the 67-per-segment rate, where 149 characters is not two segments but three.
What it does to the bill
At ₵0.02 a credit, the segment count is a straight multiplier on your campaign.
| Recipients | Segments per message | Credits | Cost |
|---|---|---|---|
| 5,000 | 1 | 5,000 | ₵100 |
| 5,000 | 2 | 10,000 | ₵200 |
| 5,000 | 3 | 15,000 | ₵300 |
The ₵200 between the first row and the last is one character. It also throws off anything you planned on the one-segment number, such as the auto top-up threshold you sized to your largest single send.
Transactional traffic is where the extra segment compounds quietly. Your login code is 482913. It expires in 5 minutes. Don't share it with anyone. is 79 characters and one segment with a straight apostrophe. Let a phone keyboard curl that apostrophe and it is 79 Unicode characters, which is two segments, on every OTP you send until somebody notices.
How Sailup shows the segment count
You do not have to count by hand. In the dashboard, the send form under Messages counts segments as you type, shows the credits per recipient, and raises two warnings when they apply: "This message contains characters that require Unicode encoding (70-character parts)" the moment a non-GSM character lands in the body, and "This message exceeds 160 characters" when the message will be split. The first is the one to act on, because it almost always means one character you did not intend. Find it, replace it, and watch the count drop. The campaign editor does not do this; it only counts characters against its 4,096 limit, so paste a campaign body into the send form first.
On the API, every send returns quantity, the number of segments per recipient:
curl -X POST https://api.sailup.io/v1/sms/ \
-H "Authorization: Bearer sailup_a1b2c3..." \
-H "Content-Type: application/json" \
-d '{"from": "YourBrand", "to": ["0201234567"], "body": "Ama, this Saturday only: 20% off braids at Osu Beauty Bar. Knotless braids now GHS 80. Book on 024 XXX XXXX. Reply STOP to the same number to opt out."}'The 202 Accepted response carries, for each recipient, a message id and a quantity, which here is 1. Send the GH₵ version of the same body and quantity comes back as 3. Multiply it by the number of recipients in to and you have the credit cost of that call. Log it and you can catch drift in production: a template that has always returned 1 and starts returning 2 has picked up a stray character, usually from a merged-in name. The send SMS docs cover the full response.
The 4,096-character cap in campaigns
The campaign editor accepts a body of up to 4,096 characters, and the API rejects anything over 960, which is six 160-character pages. Both are ceilings, not suggestions. A body that long in GSM-7 is 27 segments (4,096 ÷ 153, rounded up), so 27 credits per recipient; in Unicode it is 62. Sent to 5,000 contacts, the GSM-7 version is 135,000 credits, or ₵2,700, for one campaign. If you find yourself anywhere near the cap, you are probably writing an email.
The useful working limits are much lower: one segment for anything promotional, two at most for a transactional message that genuinely needs the detail, such as a receipt with a reference number and a MoMo line. The bulk SMS workflow post treats writing the message as one step of the campaign, and the advice there is the same: if it does not fit in 160, it usually says too much.
Pre-send checklist
- Draft in a plain text field, not Word or a phone note, so quotes stay straight and dashes stay hyphens.
- Search the body for ₵, ¢, curly quotes, en and em dashes and the single-character ellipsis. Replace them with GHS, straight quotes, a hyphen and three full stops.
- Decide on Twi and Ga spellings before you write, not after the counter turns red.
- Drop the square brackets around a brand name. Your sender ID already carries it.
- Budget for merge fields at the length of the longest value on your list, not the average.
- Check the count, in the send form as you type or as
quantityin the API response, and multiply by recipients. - If the count is 2, ask whether the message would say the same thing at 160. It usually would.
The cheapest edit you will make this week is replacing one character. Paste your draft into the send form and read the segment count before it goes anywhere near a list, or log quantity on every API response and alert on any change. Opening an account costs nothing.
Frequently asked questions
How many characters can one SMS hold?
160 if every character is in the GSM-7 alphabet, which covers plain Latin letters, digits, common punctuation and a few accented letters. 70 if the message contains even one character outside it, such as a cedi sign, a curly quote or an emoji. Longer messages are split into segments of 153 or 67 characters, and each segment is billed as one credit per recipient.
Why does my SMS say it needs Unicode encoding?
Something in the body is outside the GSM-7 alphabet. The usual suspects in Ghana are the cedi sign, curly quotes pasted from Word or a phone keyboard, an em dash, an ellipsis typed as a single character, an emoji, or Twi and Ga letters such as ɛ and ɔ. Find and replace that one character and the message goes back to the 160-character limit.
Is the cedi sign a special character in SMS?
Yes. Neither ₵ nor ¢ is in the GSM-7 alphabet, so writing GH₵50 anywhere in a message switches the whole thing to Unicode and cuts the limit from 160 characters to 70. Write GHS 50 or GHc50 instead. Every recipient in Ghana understands it, and the message stays at the 160-character rate.
How many credits does a long SMS cost on Sailup?
One credit per segment per recipient, at ₵0.02 a credit. A GSM-7 message of up to 160 characters is one segment; 161 to 306 characters is two; 307 to 459 is three. In Unicode the bands are 70, then 134, then 201. The API returns the segment count as quantity on every send, and the dashboard send form shows it as you type.
Can I send SMS in Twi without going over 70 characters?
You can, but the Twi letters ɛ, ɔ and ŋ are outside GSM-7, so any message using them is a Unicode message with a 70-character limit for a single SMS and 67 per segment after that. Short greetings and confirmations fit easily. For a long promotional message, either spell the words with plain e, o and n the way most people type on a phone, or accept the extra segments and budget for them.
Who splits a long SMS into parts?
Sailup does, before the message reaches the carrier. You send one body through the API or the campaign editor; Sailup encodes it, cuts it into segments of 153 GSM-7 or 67 Unicode characters, and attaches a small header to each part so the recipient's phone can reassemble them into one message. Each part is billed as one credit.
Send your first SMS in five minutes.
No setup fees, no contracts — pay only for what you send, and volume discounts when you scale.