35
Module 35

Phone numbers: formats, plans and validation

E.164, formats and trunk prefixes, country table, shared codes, number types, TON/NPI, six validation levels, storage rules.

On this page · 10 sections

Every SMS, call, OTP and roaming record starts with a phone number. Numbers look simple, but formats differ by country, change over time, and are easy to store or validate wrongly. This module explains the standard (E.164), the differences between countries, how numbers appear in telecom protocols (SMPP, MAP), and how to validate them correctly.

How the examples were checked. Country rules and examples below were read from the open-source libphonenumber metadata (Google, Apache licence; 246 regions, 207 distinct country codes in the version consulted in November 2026) and from the SMPP value tables in Wireshark. All sample numbers are the example numbers in that metadata, not real subscribers. Numbering plans change; regulators publish the official current plans.

1. What E.164 is

ITU-T E.164 defines the international public telecommunication numbering plan. A number in E.164 form is:

 +  CC  NSN
 │   │   └─ National Significant Number (area/network code + subscriber number)
 │   └───── Country Code: 1 to 3 digits (e.g. 1, 44, 385)
 └───────── "+" means "replace your local international dialling prefix"
 Total digits (CC + NSN): at most 15
Rule Detail
Maximum length 15 digits after the "+" (country code included)
Country code 1–3 digits, prefix-free (no code is the start of another)
Only digits No spaces, hyphens or brackets in the stored form
"+" A display sign for the international prefix; it is not dialled
Trunk prefix The national "0" (or "1" in the US) is not part of E.164
International call prefix What you dial to leave your country (00, 011, 010, 0011…), not part of the number

(The 15-digit limit and 1–3-digit country codes are widely documented in secondary sources; the recommendation text itself was not read in full.)

Why "+385" is better than "00385"

The "+" is location-independent: a mobile phone converts it into whatever international prefix the local network needs (00 in most of Europe, 011 in the US/Canada, 010 in Japan). A stored "00385…" only works for people who dial 00.

2. Four ways to write the same number (Croatia, example number)

Form Written as Use
E.164 (machine form) +385921234567 Databases, APIs, SMS, billing, signalling
International display +385 92 123 4567 Printed and shown to users (ITU E.123 style)
National display 092 123 4567 Dialling inside the country (trunk prefix 0 appears)
tel URI tel:+385-92-123-4567 (RFC 3966) Links, SIP, web

Rule of thumb: store E.164, show national or international, never mix them in the database.

3. Anatomy of a number (Croatia, from libphonenumber metadata)

Type Pattern in plain words Length Example (E.164)
Mobile starts with 9 and then specific ranges (e.g. 91, 92, 95, 97, 98, 99) 8–9 digits after +385 +385921234567
Fixed line starts with 1 (Zagreb) or one of the regional codes 20–23, 31–35, 40, 42–49, 51–53 8–9 digits +38512345678
Toll-free starts with 80 7–9 digits +385800123456
Premium rate starts with 60, 61, 64, 65, 69 7–8 digits +3856001234

(That the code 1 belongs to Zagreb is general knowledge; the metadata only lists the allowed ranges.)

Important: a mobile prefix no longer tells you the operator — number portability lets a customer keep the number when changing operator (Modules 14 and 29). To know the current network you must ask a database or do an HLR lookup.

4. A country table (from the metadata)

Region Country code Intl. dialling prefix Trunk prefix Example mobile (E.164) Mobile length Fixed length
Croatia +385 00 0 +385921234567 8–9 8–9
Slovenia +386 00 (several) 0 +38631234567 8 8
Bosnia and Herzegovina +387 00 0 +38761123456 8–9 8
Serbia +381 00 0 +381601234567 8–10 7–12
Montenegro +382 00 0 +38260123456 8 8
Hungary +36 00 06 +36201234567 9 8
Austria +43 00 0 +43664123456 7–13 4–13
Italy +39 00 none (the 0 is kept) +393123456789 9–10 6–12
Germany +49 00 0 +4915123456789 10–11 5–15
Switzerland +41 00 0 +41781234567 9 9
United Kingdom +44 00 0 +447400123456 10 9–10
France +33 00 0 +33612345678 9 9
Spain +34 00 none +34612345678 9 9
Poland +48 00 none +48512345678 9 7, 9
United States +1 011 1 +12015550123 10 10
China +86 00 (several) 0 +8613123456789 11 7–11
India +91 00 0 +918123456789 10 10
Brazil +55 00 + carrier code 0 +5511961234567 10–11 10
Japan +81 010 0 +819012345678 10 9
Australia +61 several 0 +61412345678 9 9
Turkey +90 00 0 +905012345678 10 10
Nigeria +234 009 0 +2348021234567 10 10
South Africa +27 00 0 +27711234567 5–9 9

What this table teaches

  • Trunk prefix differs: 0 in most countries, 06 in Hungary, 1 in the US/Canada, none in Italy, Spain and Poland — in Italy the leading 0 of a fixed number stays even in international form (+39 02 1234 5678).
  • Lengths vary: Austria's mobile numbers can be 7–13 digits, Germany's fixed numbers 5–15 — you cannot validate with "10 digits".
  • International prefix differs: 00, 011 (US), 010 (Japan), 009 (Nigeria) and country-specific carrier codes (Brazil) — hence "+" in storage.
  • US: fixed and mobile numbers cannot be told apart from the number alone (same pattern).

5. Country codes that are shared

In the metadata, 12 country codes are shared by several regions. Examples:

Code Regions
+1 (NANP, North American Numbering Plan) US, Canada and 23 other regions (Caribbean and Pacific territories) — told apart by the area code (first 3 digits)
+7 Russia, Kazakhstan
+39 Italy, Vatican City
+44 UK, Guernsey, Isle of Man, Jersey
+61 Australia, Christmas Island, Cocos (Keeling) Islands
+358 Finland, Åland
+590 Guadeloupe, Saint-Barthélemy, Saint-Martin
+599 Bonaire/Sint Eustatius/Saba, Curaçao
+47, +212, +262, +290 Norway/Svalbard, Morocco/Western Sahara, Réunion/Mayotte, Saint Helena/Tristan da Cunha

Consequence: a country code is not enough to identify the country; software needs the region and the leading digits, and billing/regulation (e.g. +1 premium numbers, SMS pricing) depends on it.

6. Number types and special numbers

Type Meaning Remarks
Fixed line Geographic number tied to an area code In several countries cannot be told from mobile
Mobile Mobile number Prefix does not equal operator (portability)
Toll-free Caller does not pay (Croatia 80…, US 800/833/844…) Usually domestic only
Premium rate Caller pays extra (Croatia 6x) Fraud risk (IRSF, Wangiri, Modules 26–27)
Shared cost Caller and callee share cost (Germany 180) Country-specific
VoIP / personal numbers Non-geographic IP numbers (UK 56…) Often used by businesses and fraudsters
Short codes 4–6 digits for services (SMS A2P) Not E.164; operator-specific
Emergency (112) Not E.164; works without roaming agreement Module 21
Harmonised EU numbers (116…) Social services (Module 22) Same across EU
Alphanumeric sender ID Brand name instead of a number in SMS Up to 11 characters in SMS (3GPP TS 23.040); not a real number
IMSI, ICCID, IMEI Different identity types, not phone numbers Module 14

7. Numbers inside telecom protocols

7.1 MSISDN versus the other numbers

  • MSISDN = the E.164 phone number of a subscriber.
  • IMSI (E.212) identifies the SIM; Global Titles in SS7 are E.164-based (and E.214 for mobile GTs derived from IMSI); Point Codes are separate (Modules 4 and 14).

7.2 TON and NPI — how a number is labelled

Many protocols carry a number together with two labels: Type of Number (TON) and Numbering Plan Indicator (NPI). Values below were checked in the SMPP tables used by Wireshark:

TON Meaning NPI Meaning
0 Unknown 0 Unknown
1 International (E.164 with country code) 1 ISDN / E.163/E.164 telephony
2 National 3 Data (X.121)
3 Network specific 4 Telex (F.69)
4 Subscriber number 6 Land mobile (E.212)
5 Alphanumeric (sender names) 8 National
6 Abbreviated (short code) 9 Private
10 / 14 / 18 ERMES / Internet (IP) / WAP client ID

Practical rules for SMPP senders: a normal international number uses TON 1, NPI 1; an alphanumeric sender uses TON 5; short codes use TON 3/6 depending on the operator; wrong TON/NPI is a classic cause of rejected messages or messages delivered with the wrong sender (Module 23: SMPP trace).

7.3 Where formatting errors hurt in the network

Symptom Cause
SMS rejected "invalid destination" (SMPP 0x0B) Missing country code, wrong TON/NPI, trunk prefix included (+385 (0)92…)
OTP never arrives Number stored without country code or with a leading 0; wrong region
HLR lookup says "unknown" Malformed number or non-existent range
Wrong routing in number portability Lookup done on the wrong form (national vs international)
Billing errors / duplicates Same subscriber stored as 0921234567 and +385921234567
Spoofing and display issues Sender shown in non-E.164 form; alphanumeric sender hijacking

8. Validation — the six levels

Level Question How
1. Syntax Only digits (and a leading +)? Strip spaces/hyphens/brackets safely
2. Possible Right length for the region? isPossibleNumber (length only; fast, loose)
3. Valid Does the number fit an allocated pattern for that region? isValidNumber (length + prefix patterns from metadata)
4. Type Mobile, fixed, toll-free, premium… getNumberType — critical for SMS (only mobiles can receive SMS)
5. Reachable Does the number exist now on a network? HLR lookup (SRI-SM, Module 14), carrier lookup APIs, number-verification APIs
6. Owned Is it controlled by this user? OTP/verification (and SIM-swap checks, Module 29)

Common mistake: treating level 3 ("valid format") as proof the number is real, active or the user's. It only says the digits fit a pattern.

Why a regex is not enough

  • Patterns are long and change (new ranges are allocated; e.g. the US pattern lists dozens of area-code ranges; the German pattern is hundreds of characters).
  • Variable lengths (Austria 7–13 mobile digits; Germany fixed 5–15).
  • Shared codes and territories (+1, +44).
  • Region-dependent parsing: 0921234567 is valid in Croatia but means something else elsewhere — parsing needs a default region.
  • Use a maintained library (libphonenumber and its ports for Java, JavaScript, Python, PHP and others), updated regularly, and still keep levels 5–6 for real verification.

9. How to store and handle numbers (checklist)

  1. Store E.164 as text ("+385921234567"), never as an integer (you lose leading zeros and the "+").
  2. Keep the original input and the region you assumed when parsing.
  3. Normalise on entry, display in national/international format on output.
  4. Do not drop or add the trunk "0" by hand; let the library do it per country.
  5. Handle extensions (ext./x) separately — they are not part of E.164.
  6. Treat numbers as personal data (GDPR, Module 22); limit logging and retention.
  7. Plan for recycling: an old number can be reassigned to someone else — check "last verified" dates.
  8. Re-check periodically: numbering plans change.
  9. Test with real range examples for the countries you serve, including shared codes and short codes.
  10. Use alphanumeric senders carefully: they are not numbers, may need registration, and cannot receive replies.

10. Further reading (and one source to treat with care)

  • ITU-T E.164 (numbering plan), E.123 (written notation), E.212 (IMSI), E.214 (mobile GTs); RFC 3966 (tel URI).
  • libphonenumber (metadata and README): the practical reference for patterns and examples.
  • National regulators' numbering plans (e.g. HAKOM's Plan adresiranja, Modules 14 and 22) for the official current ranges.
  • Sent.dm "Phone number standards" — an index of 225 country guides by a commercial messaging platform; useful as a starting list, but it cites no sources and contains inconsistencies (for example Bosnia and Herzegovina appears twice with different patterns), so verify any rule against the regulator or libphonenumber.

Remember this: a phone number is "+" + country code + national significant number, at most 15 digits; store that, show it nicely, and remember that format-valid is not the same as existing or yours. Prefixes tell you the type and region, not the current operator.

Sources for this module

How this module was written: from general knowledge of the field, not copied from these documents. They are the primary sources where each topic can be checked and studied further.

✓ page opened and title confirmed during writing   ◐ found via web search results   ○ official link only (titles from memory; content not read). Always check the latest version and release.