
E.164 Phone Number Format: Why It Matters & How to Convert Numbers Correctly
When building global calling systems, VoIP platforms, or contact center applications, one technical detail can make or break your phone number routing: E.164 phone number format. This ITU-T standard defines how phone numbers should be structured internationally in result ensuring every number is unique, unambiguous, and routable across carriers worldwide. Whether you're importing contact lists, building IVR flows, or integrating with telephony APIs, E.164 formatting is the foundation for reliable global communications.
E.164 is the international standard that ensures phone numbers are uniquely formatted for global routing and eliminating ambiguity in cross-border calling and VoIP systems.
What This Guide Covers
This technical guide explains the E.164 phone number format, why it's critical for VoIP and AI calling platforms, and how to convert and validate numbers programmatically. You'll learn:
- What E.164 format is and why telephony systems require it
- The structure of E.164 numbers (country code, NDC, subscriber number)
- Country-specific examples and common formatting mistakes
- How to convert numbers to E.164 using JavaScript/TypeScript
- Best practices for validation, storage, and analytics
- How phone number validators enforce E.164 before import
What Is E.164 Phone Number Format?
E.164 is the ITU-T recommendation that defines the international public telecommunication numbering plan. It specifies that every phone number should:
- Start with a
+symbol (indicating international format) - Include a country code (1–3 digits)
- Include a national destination code (NDC) or area code (if applicable)
- Include a subscriber number
- Contain no spaces, dashes, parentheses, or other separators
- Be limited to a maximum of 15 digits (excluding the
+sign)
Why E.164 Matters for VoIP and Contact Centers
When you're running AI-powered calling campaigns, IVR systems, or global contact centers, E.164 format ensures:
- Unambiguous routing: Carriers and VoIP providers route calls based on E.164 numbers and eliminate confusion between domestic and international formats.
- Global compatibility: E.164 works across all countries and telephony providers, so you can dial from anywhere to anywhere.
- Data consistency: Storing numbers in E.164 format simplifies deduplication, analytics, and CRM integrations.
- API compliance: Most telephony APIs (including the underlying carriers used by platforms like FoneSwift) require E.164 format for outbound calls, SMS, and number provisioning.
Without E.164, you risk failed calls, duplicate contacts, and broken integrations—especially when scaling globally.
Structure of an E.164 Phone Number
An E.164 number has three parts:
| Component | Description | Example (US) | Example (UK) |
|---|---|---|---|
| Country Code | 1–3 digits identifying the country | 1 | 44 |
| National Destination Code (NDC) | Area code or network prefix (optional in some countries) | 415 | 20 |
| Subscriber Number | Unique number assigned to the line | 5551234 | 71234567 |
Full E.164 format: +[Country Code][NDC][Subscriber Number]
Examples by Country
| Country | Local Format | E.164 Format | Notes |
|---|---|---|---|
| United States | (415) 555-1234 | +14155551234 | Country code 1, NDC 415, subscriber 5551234 |
| United Kingdom | 020 7123 4567 | +442071234567 | Country code 44, NDC 20, subscriber 71234567 |
| Germany | 030 12345678 | +493012345678 | Country code 49, NDC 30, subscriber 12345678 |
| India | 022 1234 5678 | +912212345678 | Country code 91, NDC 22, subscriber 12345678 |
| Brazil | (11) 91234-5678 | +5511912345678 | Country code 55, NDC 11, subscriber 912345678 |
| Australia | 02 1234 5678 | +61212345678 | Country code 61, NDC 2, subscriber 12345678 |
Notice that all separators (spaces, dashes, parentheses) are removed, and the + prefix is always present.
Common Formatting Mistakes & How to Avoid Them
1. Including Separators
❌ Incorrect: +1 (415) 555-1234
✅ Correct: +14155551234
E.164 format strips all non-numeric characters except the leading +.
2. Missing the + Sign
❌ Incorrect: 14155551234
✅ Correct: +14155551234
The + is required to indicate international format. Without it, carriers may interpret the number as domestic, causing routing failures.
3. Using Leading Zeros (for Some Countries)
In many countries (e.g., UK, Germany), domestic numbers start with 0, but E.164 replaces this with the country code.
❌ Incorrect: +44020 7123 4567
✅ Correct: +442071234567
When converting from local to E.164, drop the leading 0 and prepend the country code.
4. Exceeding 15 Digits
E.164 allows a maximum of 15 digits (excluding +). If a number exceeds this, it's invalid.
❌ Incorrect: +123456789012345678
✅ Correct: Check the country's numbering plan—most valid numbers are 10–13 digits.
How to Convert Phone Numbers to E.164 Programmatically
JavaScript/TypeScript Example
Here's a simple function to normalize a phone number to E.164 format:
/**
* Normalize a phone number to E.164 format
* @param {string} phoneNumber - Raw phone number (may include spaces, dashes, etc.)
* @param {string} defaultCountryCode - Default country code (e.g., '1' for US)
* @returns {string} E.164 formatted phone number
*/
function toE164(phoneNumber, defaultCountryCode = '1') {
// Remove all non-numeric characters except leading +
let cleaned = phoneNumber.replace(/[^\d+]/g, '');
// If it starts with +, assume it's already international
if (cleaned.startsWith('+')) {
return cleaned;
}
// Remove leading 0 (common in many countries)
if (cleaned.startsWith('0')) {
cleaned = cleaned.substring(1);
}
// If it doesn't start with country code, prepend default
if (!cleaned.startsWith(defaultCountryCode)) {
cleaned = defaultCountryCode + cleaned;
}
// Add + prefix
return '+' + cleaned;
}
// Examples
console.log(toE164('(415) 555-1234', '1')); // +14155551234
console.log(toE164('020 7123 4567', '44')); // +442071234567
console.log(toE164('+49 30 12345678')); // +493012345678
console.log(toE164('0212345678', '91')); // +912212345678
Using a Library: libphonenumber-js
For production systems, use a battle-tested library like libphonenumber-js (a JavaScript port of Google's libphonenumber):
import { parsePhoneNumber } from 'libphonenumber-js';
function toE164WithValidation(phoneNumber, defaultCountry = 'US') {
try {
const parsed = parsePhoneNumber(phoneNumber, defaultCountry);
if (parsed && parsed.isValid()) {
return parsed.format('E.164');
}
throw new Error('Invalid phone number');
} catch (error) {
console.error('Parsing error:', error.message);
return null;
}
}
// Examples
console.log(toE164WithValidation('(415) 555-1234', 'US')); // +14155551234
console.log(toE164WithValidation('020 7123 4567', 'GB')); // +442071234567
console.log(toE164WithValidation('invalid')); // null
Why use a library?
- Handles edge cases (mobile vs. landline, short codes, premium numbers)
- Validates against official numbering plans
- Supports 200+ countries
- Detects invalid formats before they break your system
Regex Pitfalls: Why You Shouldn't Rely on Regex Alone
Many developers attempt to validate E.164 with regex:
const e164Regex = /^\+[1-9]\d{1,14}$/;
This regex checks:
- Starts with
+ - Followed by 1–15 digits (no leading zeros in country code)
But it doesn't validate:
- Whether the country code exists
- Whether the NDC is valid for that country
- Whether the subscriber number length is correct
Best practice: Use regex for format validation, but use libphonenumber-js for semantic validation.
Best Practices for E.164 in VoIP Systems
1. Always Store Numbers in E.164 Format
Store phone numbers in your database as E.164 strings. This ensures:
- No ambiguity when querying or joining tables
- Easy deduplication (compare exact strings)
- Consistent display formatting (parse E.164 back to local format for UI)
2. Validate Before Import
When importing contact lists (CSV, Excel, CRM sync), validate and normalize to E.164 before storing. This prevents:
- Failed calls due to malformed numbers
- Duplicate contacts with different formats of the same number
- Analytics skew (same number counted twice)
Many platforms (including FoneSwift's phone validator) enforce E.164 validation on upload, flagging invalid rows before import.
3. Use E.164 for Call Routing and Analytics
When logging calls, events, or SMS, always store the E.164 number. This allows you to:
- Group analytics by country (extract country code)
- Filter by region (extract NDC)
- Join call logs with CRM records (consistent format)
4. Display Numbers in Local Format (But Store E.164)
For user-facing displays (call logs, contact cards), parse E.164 back to local format:
import { parsePhoneNumber } from 'libphonenumber-js';
function displayFormat(e164Number) {
const parsed = parsePhoneNumber(e164Number);
return parsed ? parsed.formatNational() : e164Number;
}
console.log(displayFormat('+14155551234')); // (415) 555-1234
console.log(displayFormat('+442071234567')); // 020 7123 4567
5. Test with International Numbers
If you're building a global system, test with numbers from multiple countries:
- US/Canada (
+1) - UK (
+44) - Germany (
+49) - India (
+91) - Brazil (
+55) - Australia (
+61)
Ensure your normalization logic handles leading zeros, variable NDC lengths, and country-specific quirks.
Using E.164 for Global Number Provisioning
When you buy international phone numbers for your contact center or AI calling system, providers return them in E.164 format. This ensures:
- Consistent number format across countries
- Easy integration with call routing logic
- No ambiguity when assigning numbers to campaigns or agents
For example, provisioning a UK number via API might return:
{
"phoneNumber": "+442071234567",
"country": "GB",
"type": "local",
"capabilities": ["voice", "sms"]
}
Store this E.164 number in your system, and use it for outbound caller ID, inbound routing rules, and analytics.
How Phone Number Validators Enforce E.164
Modern contact center platforms include phone number validators that:
- Parse uploaded numbers (from CSV, Excel, or API)
- Normalize to E.164 using libphonenumber or similar
- Flag invalid numbers (wrong length, invalid country code, non-existent NDC)
- Deduplicate (same E.164 number with different formatting)
- Enrich metadata (country, region, line type, carrier)
Example validation workflow:
| Input | Normalized (E.164) | Status | Notes |
|---|---|---|---|
| (415) 555-1234 | +14155551234 | ✅ Valid | US number |
| 020 7123 4567 | +442071234567 | ✅ Valid | UK number (leading 0 dropped) |
| +1 415 555 | N/A | ❌ Invalid | Too short |
| 123-456-7890 | +11234567890 | ⚠️ Warning | Missing country code (defaulted to US) |
FoneSwift's validator enforces E.164 before import, ensuring every number in your campaign is dialable.
E.164 Conversion Table (Quick Reference)
| Country | Country Code | Example Local | Example E.164 | Notes |
|---|---|---|---|---|
| United States | +1 | (555) 123-4567 | +15551234567 | 10 digits after country code |
| Canada | +1 | (416) 555-1234 | +14165551234 | Same as US (NANP) |
| United Kingdom | +44 | 020 7123 4567 | +442071234567 | Drop leading 0 |
| Germany | +49 | 030 12345678 | +493012345678 | Drop leading 0 |
| France | +33 | 01 23 45 67 89 | +33123456789 | Drop leading 0 |
| India | +91 | 022 1234 5678 | +912212345678 | 10 digits after country code |
| China | +86 | 010 1234 5678 | +861012345678 | 11–12 digits after country code |
| Japan | +81 | 03 1234 5678 | +81312345678 | Drop leading 0 |
| Brazil | +55 | (11) 91234-5678 | +5511912345678 | Mobile numbers have 9 digits |
| Australia | +61 | 02 1234 5678 | +61212345678 | Drop leading 0 |
Risks of Not Using E.164 & How to Mitigate
Risk 1: Call Failures
Problem: VoIP APIs reject non-E.164 numbers, causing failed calls.
Mitigation: Validate and normalize all numbers to E.164 before passing to telephony APIs.
Risk 2: Duplicate Contacts
Problem: Same number stored in multiple formats (e.g., (415) 555-1234 and +14155551234).
Mitigation: Always store E.164 in database; use it as unique key for deduplication.
Risk 3: Broken Analytics
Problem: Call logs show inconsistent formats, making it impossible to group by country or region.
Mitigation: Log E.164 numbers; extract country code and NDC for reporting.
Risk 4: Incorrect Routing
Problem: Numbers without country codes are routed domestically, causing international calls to fail.
Mitigation: Default to user's country code if missing, but flag for manual review.
How to Start Using E.164 in Your Contact Center (Step-by-Step)
Step 1: Audit Existing Phone Numbers
Export all phone numbers from your CRM, database, or call logs. Analyze formats:
- How many are already in E.164?
- How many include separators (spaces, dashes, parentheses)?
- How many are missing country codes?
Step 2: Normalize to E.164
Use a script (with libphonenumber-js) to convert all numbers to E.164:
import { parsePhoneNumber } from 'libphonenumber-js';
import fs from 'fs';
import csv from 'csv-parser';
const results = [];
fs.createReadStream('contacts.csv')
.pipe(csv())
.on('data', (row) => {
try {
const parsed = parsePhoneNumber(row.phone, 'US'); // default country
row.e164 = parsed.isValid() ? parsed.format('E.164') : 'INVALID';
} catch {
row.e164 = 'INVALID';
}
results.push(row);
})
.on('end', () => {
console.log('Normalized', results.length, 'numbers');
// Write to new CSV or database
});
Step 3: Update Database Schema
Add an e164 column (or rename existing phone column) to store E.164 strings:
ALTER TABLE contacts ADD COLUMN phone_e164 VARCHAR(16);
UPDATE contacts SET phone_e164 = normalized_value;
Step 4: Validate on Upload
Add validation middleware to your upload flow (CSV import, API POST):
app.post('/api/contacts/upload', (req, res) => {
const { phone } = req.body;
try {
const parsed = parsePhoneNumber(phone, req.body.defaultCountry || 'US');
if (!parsed.isValid()) {
return res.status(400).json({ error: 'Invalid phone number' });
}
req.body.phoneE164 = parsed.format('E.164');
// Continue processing...
} catch (error) {
return res.status(400).json({ error: 'Invalid phone number format' });
}
});
Step 5: Test International Calls
Provision test numbers in multiple countries (US, UK, Germany, India) and verify:
- Outbound calls use E.164 caller ID
- Inbound calls log E.164 numbers
- SMS sends to E.164 numbers
- Analytics group by country code
Use FoneSwift's demo environment to test E.164 routing across global numbers.
Step 6: Monitor & Iterate
Track validation failures:
- Which countries have the most formatting errors?
- Which import sources (CRM, CSV, API) need better defaults?
- Are there edge cases (short codes, toll-free numbers) your validator misses?
Iterate on your normalization logic and update documentation for your team.
E.164 Format Checklist
Use this checklist before deploying E.164 validation in production:
- All phone numbers stored in database are in E.164 format (
+prefix, no separators) - Upload/import flows validate and normalize to E.164 using libphonenumber-js
- Call logs store E.164 numbers for consistent analytics
- UI displays numbers in local format (parse E.164 → national format)
- Default country code is set for ambiguous numbers (e.g., US
+1) - Validation flags invalid numbers (wrong length, non-existent country code)
- Deduplication logic compares E.164 strings (not formatted strings)
- International test numbers validated in at least 3 countries
- API documentation specifies E.164 requirement for phone fields
- Analytics dashboards extract country code and NDC from E.164 numbers
Try the Phone Validator with FoneSwift
Ready to enforce E.164 validation in your contact center? FoneSwift's phone number validator automatically normalizes, validates, and enriches phone numbers during CSV import—flagging invalid numbers before they break your campaigns. Plus, with global virtual numbers, AI-powered calling, and usage-based pricing, you can scale confidently across 100+ countries.
Start your 14-day free trial and eliminate phone number formatting errors today—no credit card required.
Enjoyed This Article?
Subscribe to get more insights on AI calling, VOIP, and contact center automation delivered weekly.