Documentation
Sign inGet started

SMS character limits and segment counting

Every SMS is carried in fixed-size units called segments. Each segment is one billing unit, so message length directly affects cost. How many characters fit in a segment depends on the encoding Bird picks for your body, and a single character outside the default alphabet can cut the capacity in half.

How encoding is chosen

Bird inspects every character in your message body before sending:
  • If every character belongs to the GSM-7 alphabet (the standard 7-bit character set defined by GSM 03.38), the message uses GSM-7 encoding.
  • If any single character falls outside GSM-7, the entire message switches to UCS-2 (16-bit Unicode encoding).
There is no per-character mixing. One emoji, one CJK character, or one curly quote converts the whole body to UCS-2.

Segment limits

EncodingSingle segmentPer segment (multipart)
GSM-7160 characters153 characters
UCS-270 characters67 characters
When a message is longer than one segment, it is split into multiple segments. Each segment in a multipart message reserves a few bytes for a reassembly header (the User Data Header), which is why the per-segment capacity drops from 160 to 153 for GSM-7, and from 70 to 67 for UCS-2.
A 161-character GSM-7 message takes 2 segments (ceil(161 / 153) = 2), not one full segment plus a tiny second one. The split divides the encoded body evenly across segments.

Maximum message length

Bird accepts up to 12 segments per message. That translates to:
  • GSM-7: 1,836 characters (12 x 153)
  • UCS-2: 804 characters (12 x 67)
A body that exceeds 12 segments is rejected with a 422 error. Bird never truncates a message silently.

The GSM-7 character set

GSM-7 covers the characters most Latin-script messages need:
  • Letters A-Z, a-z
  • Digits 0-9
  • Common punctuation: @, £, $, !, ", #, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, space, newline
  • Some accented characters from Western European languages (the accent in "cafe" is GSM-7, for instance)

Extension-table characters

A handful of characters are part of GSM-7 but live on an extension table. Each one costs 2 septets instead of 1, so they count double against the segment limit:
, [, ], {, }, \, ~, ^, |
This matters at the boundary. If you write 159 regular characters followed by one euro sign, the encoded size is 161 septets (159 + 2), which pushes the message into 2 segments, even though it looks like 160 characters.

Characters that trigger UCS-2

Any character outside GSM 03.38 forces the entire message to UCS-2. The most common triggers:
  • Emoji: each emoji is encoded as a surrogate pair (4 bytes). A single segment fits 35 emoji; the 36th pushes the message to 2 segments.
  • CJK characters (Chinese, Japanese, Korean)
  • Arabic, Thai, Hindi, and other scripts outside the GSM-7 alphabet
  • Curly ("smart") quotes: (the straight versions " and ' are GSM-7). Smart encoding can replace these before sending.
Common accented Latin characters (like e with an accent in "cafe", or u with an umlaut) are part of the GSM-7 set and do not trigger UCS-2.

Smart encoding

Some UCS-2 triggers are not characters you chose: a word processor turns ' into , an em dash arrives with a paste, a form field carries a non-breaking space. Set options.smart_encoding to true on a send and Bird replaces those with their GSM-7 equivalents before the message goes out, which keeps the body in GSM-7 and can halve its segment count.
It is off unless you ask for it, and it is all or nothing: a body that still holds a character outside GSM-7 afterwards, such as an emoji or an accented letter the alphabet lacks, is sent exactly as you supplied it. Smart encoding covers the full replacement table, the accented-letter case, and how to read back what applied.

Reading segment counts from the API

Every SMS response includes a segments object that reports what Bird calculated:
Codevoorbeeld
{
  "segments": {
    "count": 1,
    "encoding": "GSM_7BIT",
    "characters": 64
  }
}
  • count: the number of billable segments
  • encoding: GSM_7BIT or UCS2
  • characters: the number of characters (Unicode code points) in the body
The count is the number you are billed for. Check it in the response or in the SMS log to verify your messages land where you expect.

Keeping messages to one segment

A few habits that prevent accidental multi-segment sends:
  • Replace curly quotes with straight quotes. Word processors and some phones auto-replace " with , which forces UCS-2 and halves your capacity. Smart encoding does this for you on the sends you enable it for.
  • Skip emoji in transactional or authentication messages where segment count matters.
  • Watch extension-table characters (, {, }, [, ], \, ~, ^, |). Each one eats two character slots.
  • If you write in a non-Latin script (CJK, Arabic, Thai), plan for the UCS-2 limits from the start: 70 characters single-segment, 67 per segment when split.
  • Use URL shorteners for links. A URL can consume 50+ characters of a 160-character budget.