Phone Numbers & SMS Parts
Accepted Tanzanian number formats, E.164 normalization, GSM-7 vs UCS-2 encoding, and how parts map to credits.
#Accepted formats
Only Tanzania mobile numbers are accepted for domestic sends. The API accepts several formats and normalizes to E.164 before dispatch — every SDK does the same locally before any network call:
| Format | Example | Accepted |
|---|---|---|
| Tanzania local (07xx / 06xx) | 0712345678 | Yes — converted to +255712345678 |
| International with + | +255712345678 | Yes |
| International without + | 255712345678 | Yes |
| Other countries | +254712345678 | No (Tanzania-only MVP) |
Valid Tanzania mobile prefixes: 071 072 073 074 075 076 077 078. All of these are equivalent:
{ "to": "0712345678" }
{ "to": "+255712345678" }
{ "to": "255712345678" }Invalid numbers fail fast with 400 invalid_phone — nothing is charged. For international destinations see SMS Rates; international sends are charged per part using the destination country's rate card.
#Encoding detection
The API auto-detects encoding from the characters in your message. Any character outside the GSM-7 set — emoji, Arabic, Chinese, curly quotes — flips the whole message to UCS-2:
| Encoding | Single SMS | Per part (multipart) |
|---|---|---|
| GSM-7 (standard Latin) | 160 chars | 153 chars |
| UCS-2 (Arabic, Emoji, Chinese) | 70 chars | 67 chars |
Multipart messages use 153/67 chars per part (not 160/70) because 7 bytes are reserved for concatenation headers.
#Parts → credits
You are charged 1 credit per SMS part by default (CREDIT_PRICE_PER_SMS_PART). Examples:
| Message | Encoding | Chars | Parts | Credits |
|---|---|---|---|---|
Hello, your order is ready. | GSM-7 | 28 | 1 | 1 |
| OTP template (59 chars) | GSM-7 | 59 | 1 | 1 |
| 200-char promotional message | GSM-7 | 200 | 2 | 2 |
Habari 😊 Bei yako ni 5000 TZS | UCS-2 | 31 | 1 | 1 |
مرحبا | UCS-2 | 5 | 1 | 1 |
#Count parts before sending
import { getSmsPartInfo, detectEncoding } from "sendafrica";
const info = getSmsPartInfo("Hello, your order is ready.");
// { encoding: "GSM-7", length: 28, parts: 1, creditsRequired: 1 }
const emoji = getSmsPartInfo("Habari 😊 Bei yako ni 5000 TZS");
// { encoding: "UCS-2", length: 31, parts: 1, creditsRequired: 1 }
detectEncoding("Hello"); // "GSM-7"
detectEncoding("Hello 😊"); // "UCS-2"Watch hidden unicode
Smart quotes (“…”), em-dashes (—), and zero-width characters silently switch a message to UCS-2 and cut your per-part budget from 160 to 70 chars. Sanitize user-composed text when possible.