Guide

E.164 phone number format explained

E.164 is the one phone number format every telephony system understands. What it looks like, how to convert numbers to it, how to validate it and why SMS APIs insist on it.

Updated October 29, 2026 · 6 min read

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

RuleExample
Starts with ++44…, never 0044… or 011 44…
Country code of 1 to 3 digits, never starting with 01 (US, Canada), 44 (UK), 234 (Nigeria)
National number without trunk prefixUK 020… becomes +4420…
Digits only after the +No spaces, dashes, dots or brackets
At most 15 digits+123456789012345 is the longest possible
No extensionAn extension such as ext. 12 is stored separately

E.164 examples by country

CountryWritten locallyE.164
United States(206) 922-0880+12069220880
United Kingdom020 7946 0958+442079460958
Germany030 901820+4930901820
France01 23 45 67 89+33123456789
Italy06 4568 1234+390645681234
India098765 43210+919876543210
Nigeria0803 123 4567+2348031234567
Australia(02) 9876 5432+61298765432
Brazil(11) 91234-5678+5511912345678
Mexico55 1234 5678+525512345678
Japan03-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:

FormatExampleUse it for
E.164+442079460958Storage, APIs, SMS and voice providers
International+44 20 7946 0958Display to an international audience
National020 7946 0958Display inside the country
RFC 3966tel:+44-20-7946-0958tel: links in HTML and apps

How to convert a number to E.164

  1. Remove everything that is not a digit, except a leading +.
  2. Replace the international call prefix with +. That prefix is 00 in most of Europe and in India, 011 in the US and Canada, 010 in Japan, 0011 in Australia and 009 in Nigeria.
  3. If there is no +, the number is national: remove the trunk prefix and add + and the country code. The trunk prefix is 0 in the UK, Germany, France, India, Japan and Australia, 1 in the US and Canada, 8 in Russia, and none in Italy, Spain or Mexico.
  4. 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}$
InputRegex resultWhy
+442079460958MatchE.164
+15555555555MatchRight shape, but area code 555 is not in service
+44 20 7946 0958No matchSpaces
442079460958No matchNo +
+0442079460958No matchCountry codes never start with 0
+1234567890123456No match16 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

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.

Frequently asked questions

What does an E.164 number look like?

A plus sign, the country code and the national number without trunk prefix, spaces or punctuation: +14155552671 for a US number, +442079460958 for a London number. At most 15 digits after the plus.

Is E.164 the same as international format?

Almost. The international format adds spaces for readability (+44 20 7946 0958); E.164 removes them (+442079460958). Both start with + and the country code.

What is the regex for E.164?

^\+[1-9]\d{1,14}$ checks the shape: a plus, a non-zero first digit, up to 15 digits. In Python use re.fullmatch and in PHP the D modifier, because $ there also matches before a trailing line break. A regex does not check whether the number exists; for that you need numbering-plan validation.

Should I store phone numbers in E.164?

Yes. E.164 is unambiguous, one string per number and accepted by every SMS and voice API, so it is the best format for databases. Keep an extension in a separate field, and format numbers nationally only for display.

How long can an E.164 number be?

At most 15 digits, country code included, so an E.164 string has at most 16 characters with the plus. Country codes have 1 to 3 digits; many national numbers are much shorter than the maximum.

Phone number API

Validate numbers like this in your app

numlookupapi checks any phone number worldwide in one request and returns validity, line type, carrier, location and every standard format as JSON.

Read the documentation

250 free requests every month. No credit card required.

GET https://api.numlookupapi.com/v1/validate/+12069220880

{
  "valid": true,
  "number": "12069220880",
  "local_format": "2069220880",
  "international_format": "+12069220880",
  "country_prefix": "+1",
  "country_code": "US",
  "country_name": "United States of America",
  "location": "Seattle",
  "line_type": "landline",
  "e164_format": "+12069220880",
  "national_format": "(206) 922-0880"
}

Keep reading

Start using our phone number API for free today!

Get 250 requests / month for free