# What is E.164? The phone number format, explained

_2026-07-18 · Boundstone (https://boundstone.io/blog/what-is-e164)_


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](https://www.itu.int/) 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:

1. **It's unambiguous.** `0400 123 456` could be several countries' formats. `+61400123456` is exactly one number, full stop. No guessing a country later.
2. **It deduplicates cleanly.** `(650) 447-2983`, `650.447.2983`, and `+1 650 447 2983` are 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.
3. **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:

```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](/blog/validate-phone-javascript).)

## Common mistakes

- **Keeping the national leading zero.** `+4407911123456` is wrong; the `0` goes 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-2983` is 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](/tools/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.
