The E.164 format is the international phone number format defined by the ITU-T recommendation E.164: a +, the country code (1 to 3 digits) and the national number, with no spaces, dashes, brackets or trunk prefix, and at most 15 digits in total. +442079460958 is a London number in E.164; 020 7946 0958 is the same number written for callers inside the UK. This guide shows E.164 examples for 11 countries, how to convert any number to E.164 in JavaScript, Python and PHP, a regex that checks the format, and how to store phone numbers.
+ 44 2079460958
│ │ └─ national number without the leading 0 (trunk prefix)
│ └─ country code (United Kingdom)
└─ plus sign
The rules of the E.164 format
| Rule | Example |
|---|---|
Starts with + | +44…, never 0044… or 011 44… |
| Country code of 1 to 3 digits, never starting with 0 | 1 (US, Canada), 44 (UK), 234 (Nigeria) |
| National number without trunk prefix | UK 020… becomes +4420… |
Digits only after the + | No spaces, dashes, dots or brackets |
| At most 15 digits | +123456789012345 is the longest possible |
| No extension | An extension such as ext. 12 is stored separately |
E.164 examples by country
| Country | Written locally | E.164 |
|---|---|---|
| United States | (206) 922-0880 | +12069220880 |
| United Kingdom | 020 7946 0958 | +442079460958 |
| Germany | 030 901820 | +4930901820 |
| France | 01 23 45 67 89 | +33123456789 |
| Italy | 06 4568 1234 | +390645681234 |
| India | 098765 43210 | +919876543210 |
| Nigeria | 0803 123 4567 | +2348031234567 |
| Australia | (02) 9876 5432 | +61298765432 |
| Brazil | (11) 91234-5678 | +5511912345678 |
| Mexico | 55 1234 5678 | +525512345678 |
| Japan | 03-1234-5678 | +81312345678 |
We parsed every local number with libphonenumber-js 1.13.15 and its country: each one is valid and converts to the E.164 value shown. Note Italy: Italian numbers keep their leading 0 after the country code. Look up the country code and trunk prefix of any country in the country code list.
E.164 compared with other formats
The same London number in the four standard formats:
| Format | Example | Use it for |
|---|---|---|
| E.164 | +442079460958 | Storage, APIs, SMS and voice providers |
| International | +44 20 7946 0958 | Display to an international audience |
| National | 020 7946 0958 | Display inside the country |
| RFC 3966 | tel:+44-20-7946-0958 | tel: links in HTML and apps |
How to convert a number to E.164
- Remove everything that is not a digit, except a leading
+. - Replace the international call prefix with
+. That prefix is00in most of Europe and in India,011in the US and Canada,010in Japan,0011in Australia and009in Nigeria. - If there is no
+, the number is national: remove the trunk prefix and add+and the country code. The trunk prefix is0in the UK, Germany, France, India, Japan and Australia,1in the US and Canada,8in Russia, and none in Italy, Spain or Mexico. - Check the length: at most 15 digits after the
+, and the right length for that country.
Steps 2 to 4 differ by country and change when numbering plans change, so production code uses Google’s libphonenumber (or one of its ports) instead of string manipulation. The function in each language returns the E.164 string, or null / None when the input is not a valid number.
JavaScript with libphonenumber-js (npm install libphonenumber-js):
import { parsePhoneNumberFromString } from "libphonenumber-js/max";
export function toE164(raw, defaultCountry) {
const number = parsePhoneNumberFromString(raw, defaultCountry);
return number?.isValid() ? number.number : null;
}
toE164("020 7946 0958", "GB"); // "+442079460958"
toE164("011 44 20 7946 0958", "US"); // "+442079460958" (US international prefix)
toE164("8 (495) 123-45-67", "RU"); // "+74951234567" (Russian trunk prefix 8)
toE164("+1 555 555 5555", "US"); // null (not a valid number)
Python with phonenumbers (pip install phonenumbers):
import phonenumbers
def to_e164(raw: str, default_region: str) -> str | None:
try:
number = phonenumbers.parse(raw, default_region)
except phonenumbers.NumberParseException:
return None
if not phonenumbers.is_valid_number(number):
return None
return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
PHP with libphonenumber-for-php (composer require giggsey/libphonenumber-for-php):
use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
function toE164(string $raw, string $defaultRegion): ?string
{
$util = PhoneNumberUtil::getInstance();
try {
$number = $util->parse($raw, $defaultRegion);
} catch (NumberParseException) {
return null;
}
return $util->isValidNumber($number) ? $util->format($number, PhoneNumberFormat::E164) : null;
}
We ran all three with the same inputs (Node.js 26 with libphonenumber-js 1.13.15, Python 3.15 with phonenumbers 9.0.42, PHP 8.5 with libphonenumber-for-php 9.0.42) and got the same results: 0044 20 7946 0958 with default country DE, 020 7946 0958 with GB and 06 4568 1234 with IT converted correctly, +1 555 555 5555 and hello returned null. The default country only applies to numbers without + or an international prefix.
Without code, convert a whole list with the free phone number formatter.
Validating E.164 numbers
A regex checks the shape only:
^\+[1-9]\d{1,14}$
| Input | Regex result | Why |
|---|---|---|
+442079460958 | Match | E.164 |
+15555555555 | Match | Right shape, but area code 555 is not in service |
+44 20 7946 0958 | No match | Spaces |
442079460958 | No match | No + |
+0442079460958 | No match | Country codes never start with 0 |
+1234567890123456 | No match | 16 digits |
In JavaScript $ matches only at the end of the string. In Python and PHP it also matches before a trailing line break, so "+442079460958\n" passes: use re.fullmatch() (or \Z) in Python and the D modifier (/^\+[1-9]\d{1,14}$/D) in PHP. We checked all three.
To know whether a number can exist in its country, validate it against the numbering plan, as the toE164 functions above do, or with the free phone number validator. To also get the carrier and line type, use the numlookupapi API, which returns valid, e164_format, line_type and carrier for any number.
How to store phone numbers
- One E.164 column,
VARCHAR(16): 15 digits plus the+. It is unique per number, so you can index it and find duplicates. - Extensions in their own column. libphonenumber reads
+44 20 7946 0958 ext. 12as the E.164 number plus extension12. - Convert when the number is entered, in the sign-up form or the import, with the user’s country as the default. Fixing numbers later means guessing the country.
- Format for display only: national format for people in the same country, international format for everyone else.
Why SMS and voice APIs require E.164
SMS and voice providers such as Twilio, Vonage and Amazon SNS route by country code and expect E.164 numbers. A national number like 07400 123456 is ambiguous without a country, so a message to it either fails or needs extra parameters. Numbers normalised to E.164 at entry avoid failed messages and duplicate contacts later. To check that a stored E.164 number is still a valid mobile number before you send, validate it with numlookupapi or a whole list with the bulk phone validator.