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)
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.

Reading segment counts from the API

Every SMS response includes a segments object that reports what Bird calculated:
Exemplo de código
{
  "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.
  • 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.