What is E.164? The phone number format, explained
The international standard that makes a phone number mean the same thing everywhere. What it is, why to store it, and how to get a number into it correctly.
Contents
E.164 is the international standard format for phone numbers. If you store or send phone numbers in software — for SMS, for voice, for a CRM, for signup screening — this is the format you want them in, and getting it right removes a whole category of bugs before they start.
The definition
E.164 is an ITU recommendation (ITU-T Recommendation E.164) that defines a single, unambiguous way to write any phone number in the world. An E.164 number is:
- a leading
+, - the country code (1–3 digits),
- the national number,
- with no spaces, dashes, brackets or leading zeros, and
- at most 15 digits in total (not counting the
+).
So the US number written locally as (650) 447-2983 is, in E.164:
+16504472983
And the UK number written locally as 07911 123456 — note the leading zero — is:
+447911123456
The leading 0 is a national dialing convention; in E.164 it's dropped and replaced by the country code. That single rule trips up more integrations than any other.
Anatomy
+1 6504472983
│ │
│ └─ national number (the actual subscriber number)
└──── country code (1 for US/Canada, 44 for UK, 61 for Australia)
The + matters: it's the part that says "what follows is a country code," which is how the same string dials correctly from any country without hardcoding an international access prefix (like 011 in the US or 00 in much of Europe).
Why you want to store it
The reason to normalize to E.164 on the way in, rather than storing whatever the user typed, comes down to three properties:
- It's unambiguous.
0400 123 456could be several countries' formats.+61400123456is exactly one number, full stop. No guessing a country later. - It deduplicates cleanly.
(650) 447-2983,650.447.2983, and+1 650 447 2983are the same number written three ways. Store them as typed and your database thinks they're three customers. Store them as E.164 and they collapse to one row. - Every downstream API expects it. Twilio, most SMS gateways, voice providers and validation APIs take E.164. Store it that way and you never transform on the way out.
The pattern is simple: validate and normalize once, at the point of entry, and store the E.164 form as your canonical value.
How to convert a number to E.164
Here's the catch: you can't reliably convert a national number to E.164 without knowing which country it belongs to, because the same digits mean different numbers in different countries. If the user typed the + and country code, you're set. If they didn't, you need a default country from somewhere — their locale, a form field, their IP's country.
Don't try to do this with string manipulation. The rules (which leading zeros to strip, valid lengths, which prefixes exist) are per-country and encoded in Google's libphonenumber. In JavaScript:
import { parsePhoneNumber } from "libphonenumber-js";
parsePhoneNumber("07911 123456", "GB").number; // "+447911123456"
parsePhoneNumber("+1 650 447 2983").number; // "+16504472983"
That .number property is the E.164 form. (There's a fuller walk-through in phone number validation in JavaScript.)
Common mistakes
- Keeping the national leading zero.
+4407911123456is wrong; the0goes when the country code comes in. - Assuming +1. Prepending a country code because "most of our users are American" silently corrupts every foreign number.
- Storing the formatted version.
+1 650-447-2983is nice for display but isn't E.164 — the spaces and dashes aren't part of the format. Store+16504472983; format for display separately. - Treating E.164 as a reachability guarantee. E.164 is about format. A number can be perfectly valid E.164 and long disconnected — see the note below.
E.164 tells you the shape, not the status
It's worth being precise about what this format does and doesn't promise. A correctly formatted, valid E.164 number is one that could exist under its country's numbering plan. It says nothing about whether the number is currently assigned, which carrier holds it, or whether a handset would answer. Those are separate, live questions — and any tool that conflates "valid E.164" with "reachable" is overselling. If you want to validate and normalize numbers to E.164, the free phone validator returns the E.164 form for any valid number, and is explicit about the live checks it doesn't perform.
The short version
E.164 is +, country code, national number, no punctuation, max 15 digits. Normalize to it once at entry (using libphonenumber, not string surgery), store that as canonical, and format for display separately. It's the single cheapest habit for keeping phone data sane across countries — and it's about how a number is written, not whether anyone's home.