sms compliance

Sent logo
Sent TeamMay 3, 2025 / sms compliance / E.164

E.164 Phone Number Format: Complete Validation & Conversion Guide (2025)

Master E.164 phone number validation, formatting, and conversion with regex patterns, JavaScript examples, and libphonenumber-js. Includes E.164 format examples, validator tools, security best practices, and Twilio integration for SMS and international calling.

E.164 Phone Number Format: Complete Guide to Validation & Implementation (2025)

Learn how to validate, format, and convert phone numbers to E.164 format—the international standard for telecommunications. This guide covers E.164 format examples, regex validation patterns, JavaScript implementation with libphonenumber-js, conversion tools, and integration with Twilio and SMS systems for global phone number handling.

What is E.164 Phone Number Format?

E.164 is the international telecommunication standard that defines the format for phone numbers worldwide. The ITU-T (International Telecommunication Union) establishes specifications for structuring phone numbers to enable global dialing across all networks and countries. The official ITU-T Recommendation E.164, titled "The international public telecommunication numbering plan," provides these specifications (ITU-T E.164, 2010).

An E.164 phone number has a maximum of 15 digits and follows this structure:

  • Country Code (1–3 digits): Identifies the country (e.g., +1 for USA/Canada)
  • National Destination Code (variable length): Identifies the area or carrier
  • Subscriber Number: The remaining digits (maximum 12 digits combined with NDC) that identify the specific phone line

E.164 Format Example: +14155550123 (where +1 is USA, 415 is San Francisco area code, 5550123 is the subscriber number)

E.164 forms the foundation of global telecommunications, ensuring consistent call routing and interoperability between countries and network operators. It's the universal language for phone numbers, allowing systems to correctly identify and connect calls across all countries and carriers. This standardized format is essential for SMS delivery, international calling, VoIP services, and two-factor authentication systems.

Historical Context and Evolution: From ISDN to the Modern Era

First published in 1988 as the "Numbering Plan for the ISDN Era," E.164 has continuously evolved to keep pace with advancements in telecommunications. The standard expanded to accommodate growing global demand for phone numbers. The most substantial revision is E.164 (11/2010), approved November 18, 2010, with periodic amendments continuing through ITU Operational Bulletins (latest amendments published July 2020, Bulletin No. 1199) to address the complexities of modern communication, including:

  • Mobile number portability: Allows users to retain their numbers when switching carriers across different networks.
  • IP telephony integration: Supports VoIP and cloud-based communication systems.
  • Emergency service requirements: Ensures reliable routing to emergency services (E911, E112).
  • International roaming capabilities: Enables seamless communication while traveling abroad.
  • Virtual and eSIM support: Accommodates digital-first phone numbers and embedded SIM technology.

E.164 is not a static standard but a dynamic framework adapting to the ever-changing landscape of global communication, including emerging technologies like virtual phone numbers and cloud telephony platforms.

E.164 Format Specifications: Understanding Phone Number Structure

The E.164 phone number structure consists of precisely defined components that enable global interoperability. Understanding this structure is essential for accurate validation and implementation across international telecommunications systems.

E.164 Number Structure: The Three Essential Components

An E.164 number consists of three key components, each playing a crucial role in accurate routing:

  1. Country Code (CC): This 1–3 digit prefix identifies the country. For example, +1 is for North America, +44 for the UK, and +86 for China. The ITU-T assigns these codes (ITU-T E.164, 2010).

  2. National Destination Code (NDC): This variable-length code identifies a specific geographic area, mobile network, or service within a country. National authorities manage these codes. NDC lengths vary both between and within countries depending on the numbering plan design.

  3. Subscriber Number (SN): This is the remaining portion of the number, uniquely identifying the subscriber within the NDC zone. The combined length of NDC and SN cannot exceed 12 digits. Together, the NDC and SN form the National Significant Number.

text
Example Breakdown:
+1 (415) 555-0123
│  │    └────────── Subscriber Number (SN)
│  └─────────────── National Destination Code (NDC)
└──────────────────── Country Code (CC)

Understanding these components is crucial when parsing and validating E.164 numbers.

E.164 Format Requirements and Validation Rules

E.164 numbers must adhere to strict formatting rules to ensure global compatibility:

1. Character Set

Only digits 0–9 are allowed per ITU-T E.164. A plus (+) prefix indicates international format for display but should be omitted from stored data. No spaces, hyphens, or other separators are allowed in the canonical format. This ensures consistency and simplifies processing.

2. Length Constraints

The minimum length is the CC length plus one digit. The maximum total length is 15 digits (comprising 1–3 digit country code plus up to 12 digits for the national number). Country-specific minimum lengths also apply, adding another layer of complexity to validation.

3. Structural Rules

Use a regular expression to enforce the basic E.164 format:

Validation TypeRegex PatternDescription
Basic E.164 Structure^\+[1-9]\d{1,14}$Validates structure only – does not verify country-specific rules
Storage Format^[1-9]\d{1,14}$For numbers stored without + prefix
javascript
// Basic E.164 format regex - validates structure only
const e164Regex = /^\+[1-9]\d{1,14}$/;

// Examples:
// +14155550123 ✓ Valid
// +442071234567 ✓ Valid
// +861234567890 ✓ Valid
// 14155550123 ✗ Missing + prefix
// +01234567890 ✗ Starts with 0
// +1415555012345678 ✗ Exceeds 15 digits

Important Note: This regex validates basic structure but does not verify country-specific rules or whether the number actually exists. For production validation, use specialized libraries like libphonenumber-js that maintain comprehensive country-specific rulesets.

How to Validate E.164 Phone Numbers: Implementation Guide

Implementing robust E.164 phone number validation requires a multi-layered approach that combines format checking, country-specific validation, and length verification. This section provides step-by-step implementation guidance for building reliable phone number validation into your applications.

Phone Number Validation Strategy: Multi-Layered Approach

A robust validation strategy incorporates multiple layers to ensure accuracy:

Validation LayerPurposeImplementation
Basic Format ValidationVerify structure, catch invalid characters, confirm lengthUse regex: /^\+[1-9]\d{1,14}$/
Country-Specific ValidationCheck country patterns and length restrictionsMaintain country-specific rule database or use validation library
Length ValidationVerify total number length including country codeCritical for countries with variable NDC lengths

Implementation Example:

javascript
import { parsePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';

function validateE164(phoneNumber) {
  // Layer 1: Basic format validation
  const e164Regex = /^\+[1-9]\d{1,14}$/;
  if (!e164Regex.test(phoneNumber)) {
    return { valid: false, error: 'Invalid E.164 format' };
  }

  // Layer 2 & 3: Country-specific and length validation
  try {
    const parsed = parsePhoneNumber(phoneNumber);
    return {
      valid: parsed.isValid(),
      country: parsed.country,
      type: parsed.getType()
    };
  } catch (error) {
    return { valid: false, error: error.message };
  }
}

How to Convert Phone Numbers to E.164 Format

Converting local or national phone numbers to E.164 format is a common requirement when processing user input. Follow these steps for accurate conversion:

Conversion Process:

  1. Remove all formatting characters: Strip spaces, hyphens, parentheses, and punctuation
  2. Remove leading zeros: If the number begins with 0 (common in national formats), remove it
  3. Prepend the country code: Add the appropriate country code with + prefix
  4. Validate the result: Verify the final number is 15 digits or fewer

E.164 Conversion Examples by Country:

CountryNational FormatE.164 FormatNotes
USA(415) 555-0123+14155550123Remove parentheses and hyphens
UK020 7123 4567+442071234567Remove leading 0 and spaces
Germany030 12345678+493012345678Remove leading 0 and spaces
India98765 43210+919876543210Remove spaces, add country code

Code Example:

javascript
import { parsePhoneNumber } from 'libphonenumber-js';

function convertToE164(phoneNumber, defaultCountry = 'US') {
  try {
    const parsed = parsePhoneNumber(phoneNumber, defaultCountry);
    return parsed.format('E.164'); // Returns: +14155550123
  } catch (error) {
    throw new Error(`Conversion failed: ${error.message}`);
  }
}

// Usage:
convertToE164('(415) 555-0123', 'US'); // +14155550123
convertToE164('020 7123 4567', 'GB');  // +442071234567
convertToE164('030 12345678', 'DE');   // +493012345678

Common Edge Cases in Phone Number Validation

Real-world phone number validation requires handling several edge cases:

1. International Display Format

For user-friendliness, format numbers with appropriate separators for display (e.g., +1-415-555-0123). Store numbers in canonical E.164 format internally.

2. Multiple Input Formats

Users enter phone numbers inconsistently – with dashes, parentheses, spaces, or no formatting at all. Normalize all inputs before validation to ensure consistent processing.

3. Extension Numbers

Phone extensions (e.g., +1-415-555-0123 ext. 456) are not part of the E.164 standard. Store extensions separately:

javascript
// Store these separately in your database
{
  phoneNumber: '+14155550123',  // E.164 format
  extension: '456'              // Separate field
}

4. Special Service Numbers

Handle these number types separately as they may not follow standard validation rules:

Service TypeExampleNotes
Emergency911 (US), 112 (EU)Not E.164 compliant; handle separately
Toll-free+1-800-555-0123Valid E.164 but may have special routing
Premium rate+1-900-555-0123Valid E.164 but require special handling
Short codes12345 (5–6 digits)Not E.164; used for SMS services

5. Vanity Numbers

Convert alpha-numeric vanity numbers (e.g., 1-800-FLOWERS) to numeric format:

javascript
function convertVanityNumber(vanityNumber) {
  const keypadMap = {
    'A': '2', 'B': '2', 'C': '2',
    'D': '3', 'E': '3', 'F': '3',
    'G': '4', 'H': '4', 'I': '4',
    'J': '5', 'K': '5', 'L': '5',
    'M': '6', 'N': '6', 'O': '6',
    'P': '7', 'Q': '7', 'R': '7', 'S': '7',
    'T': '8', 'U': '8', 'V': '8',
    'W': '9', 'X': '9', 'Y': '9', 'Z': '9'
  };

  return vanityNumber
    .toUpperCase()
    .replace(/[A-Z]/g, char => keypadMap[char]);
}

// Usage:
convertVanityNumber('1-800-FLOWERS'); // 1-800-3569377

Best Practices: Ensuring Data Integrity and User Experience

Implement E.164 effectively by following these best practices:

1. Storage

Always store phone numbers in the pure E.164 format, removing all formatting characters. This ensures data consistency and simplifies processing. E.164 numbers are limited to 15 digits, making storage requirements predictable. Use appropriate database field types:

  • VARCHAR(15): Recommended for string storage with + prefix
  • VARCHAR(16): If storing + prefix as character
  • BIGINT: For numeric-only storage (without + prefix)
  • Index this field for faster lookups in large contact databases

2. Display

Use local formatting conventions for user interfaces to enhance readability. However, always maintain the E.164 format internally for system operations. Consider cultural formatting preferences to provide the best user experience.

3. Validation

Implement progressive validation, checking the number at both input and processing stages. Use established libraries for complex validation logic. This minimizes errors and improves data quality.

4. Security & Privacy

Treat phone numbers as Personally Identifiable Information (PII). Implement these security measures:

Security MeasureImplementationPurpose
Encryption at restAES-256 encryptionProtect stored phone numbers
Hashing for lookupsSHA-256 with saltEnable searches without exposing numbers
Rate limitingMax 10 validation requests per IP per minutePrevent enumeration attacks
Access loggingAudit trail of all phone number accessCompliance and security monitoring
TLS in transitHTTPS/TLS 1.3Protect numbers during transmission

Implementation Example:

javascript
const crypto = require('crypto');

// Encryption configuration
const algorithm = 'aes-256-gcm';
const keyLength = 32; // 256 bits

function encryptPhoneNumber(phoneNumber, encryptionKey) {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv(algorithm, encryptionKey, iv);

  let encrypted = cipher.update(phoneNumber, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  const authTag = cipher.getAuthTag();

  return {
    encrypted,
    iv: iv.toString('hex'),
    authTag: authTag.toString('hex')
  };
}

// Hash for searchable lookup (one-way)
function hashPhoneNumber(phoneNumber, salt) {
  return crypto
    .createHash('sha256')
    .update(phoneNumber + salt)
    .digest('hex');
}

Key Management:

  • Store encryption keys in a secure key management service (AWS KMS, Azure Key Vault, HashiCorp Vault)
  • Rotate encryption keys quarterly
  • Never store keys in application code or version control

Privacy Compliance:

  • GDPR: Obtain explicit consent before storing phone numbers; provide data export and deletion capabilities
  • CCPA: Allow California residents to opt out of phone number data sales
  • Right to erasure: Implement hard deletion (not just soft delete) for phone numbers on request

5. API Rate Limiting

When using validation services or carrier lookup APIs, implement rate limiting and caching to prevent abuse and reduce costs. Consider implementing exponential backoff for failed validation attempts.

Caching Strategy:

Data TypeTTL (Time To Live)Justification
Valid numbers24 hoursNumbers rarely change; reduce API calls
Invalid numbers1 hourMay be typos users will correct
Carrier lookups7 daysCarrier information changes infrequently
Country metadata30 daysITU updates are periodic
javascript
const cache = new Map();

async function validateWithCache(phoneNumber) {
  const cached = cache.get(phoneNumber);
  if (cached && Date.now() - cached.timestamp < 86400000) { // 24 hours
    return cached.result;
  }

  const result = await expensiveValidationAPI(phoneNumber);
  cache.set(phoneNumber, { result, timestamp: Date.now() });
  return result;
}

Troubleshooting E.164 Phone Number Validation: Common Issues & Solutions

When implementing E.164 validation, developers frequently encounter specific issues that can cause validation failures or incorrect phone number handling. Here are the most common problems and their solutions:

Issue 1: Invalid Country Codes

Problem: Numbers fail validation due to incorrect or outdated country codes.

Solutions:

  • Verify country codes against the official ITU-T E.164 list
  • Check for recent country code changes (countries occasionally modify their codes)
  • Validate the total number length against country-specific specifications
  • Update your country code database quarterly

Monitoring ITU Changes:

Subscribe to ITU Operational Bulletins for official notifications of numbering plan changes. Recent examples include:

  • Kosovo (+383) assigned in 2015
  • South Sudan (+211) assigned in 2011
  • Timor-Leste changed from +670 (temporary) to permanent assignment

Issue 2: Format Inconsistencies in User Input

Problem: Users submit phone numbers in various formats (with spaces, hyphens, parentheses), causing validation failures.

Solutions:

javascript
function normalizePhoneNumber(input) {
  // Remove all formatting characters except + prefix
  let normalized = input.replace(/[^+\d]/g, '');

  // Handle international prefix variations
  // Convert 00 (European) or 011 (North American) to +
  normalized = normalized.replace(/^00/, '+');
  normalized = normalized.replace(/^011/, '+');

  // Ensure single + prefix at start
  normalized = normalized.replace(/^\++/, '+');

  return normalized;
}

// Test cases:
normalizePhoneNumber('(415) 555-0123');    // 4155550123
normalizePhoneNumber('+1-415-555-0123');   // +14155550123
normalizePhoneNumber('001 415 555 0123');  // +14155550123
normalizePhoneNumber('011 44 20 7123 4567'); // +442071234567

Implement progressive validation at both input and processing stages to catch errors early.

Issue 3: Regional Numbering Variations

Problem: Variable NDC lengths and special number formats within countries cause validation errors.

Solutions:

  • Account for variable NDC lengths within the same country
  • Distinguish between mobile and landline formats (they often differ)
  • Handle special service numbers separately (emergency services, toll-free, premium rate)
  • Use established validation libraries that maintain country-specific rulesets

Special Number Ranges by Type:

Number TypeCountryRange/PatternExample
Toll-freeUS/Canada+1-800/888/877/866/855/844/833+18005550123
Toll-freeUK+44-800/808+448005550123
Premium rateUS+1-900+19005550123
Premium rateUK+44-871/872/873+448715550123
MobileUSNo specific prefix+14155550123
MobileUK+44-7+447555550123
MobileIndia+91-6/7/8/9+919876543210

Issue 4: Failed Call Routing or Integration

Problem: Non-E.164 formatted numbers cause failed API calls, unsuccessful contact synchronization, or routing issues.

Solutions:

  • Store numbers in pure E.164 format in your database
  • Convert format at data entry points
  • Validate format before passing to external APIs or telephony systems
  • Log validation failures for debugging and monitoring

Debugging Checklist:

javascript
// Comprehensive validation logging
function validateAndLog(phoneNumber, context) {
  const validationSteps = {
    'has_plus_prefix': phoneNumber.startsWith('+'),
    'correct_length': phoneNumber.length >= 8 && phoneNumber.length <= 16,
    'digits_only_after_plus': /^\+\d+$/.test(phoneNumber),
    'no_leading_zero': !phoneNumber.startsWith('+0'),
    'within_max_length': phoneNumber.length <= 16
  };

  const failed = Object.entries(validationSteps)
    .filter(([_, passed]) => !passed)
    .map(([step, _]) => step);

  if (failed.length > 0) {
    console.error(`Validation failed for ${phoneNumber}`, {
      context,
      failed_checks: failed,
      timestamp: new Date().toISOString()
    });
  }

  return failed.length === 0;
}

Best E.164 Phone Number Validation Libraries (2025)

Implementing E.164 validation from scratch is complex due to country-specific rules and frequent numbering plan updates. These actively maintained JavaScript libraries simplify validation and formatting while ensuring compliance with current international standards.

Library Comparison Overview

Featurelibphonenumber-jsphonegoogle-libphonenumber
Bundle size145 KB85 KB550 KB
Last updatedv1.12.23 (Oct 2025)v3.1.67 (Oct 2025)v3.2.43 (Sep 2025)
TypeScript support✓ Full✓ Full✓ Full
Metadata updatesAutomaticAutomaticAutomatic
Best forWeb applicationsMobile-focused appsServer-side applications
Format validation✓ Comprehensive✓ Mobile only✓ Comprehensive
Number type detection✓ Yes✓ Yes✓ Yes
Carrier lookup✗ No✗ No✓ Yes

When to choose which library:

  • libphonenumber-js: Best for web applications where bundle size matters. Provides comprehensive validation with reasonable size.
  • phone: Best when you only need mobile number validation. Smallest bundle size.
  • google-libphonenumber: Best for server-side applications where bundle size is not a concern and you need the most comprehensive validation.

Using the phone Library

The phone npm package (v3.1.67, October 2025) provides robust E.164 standardization and validation for mobile phone numbers. It handles diverse input formats and ensures compliance with international standards. Note: This library focuses specifically on mobile number formats.

Installation and Setup

bash
npm install phone --save

Usage Example

javascript
const { phone } = require('phone');

// Basic validation
const result = phone('+14155550123');
console.log(result.isValid);      // true
console.log(result.phoneNumber);  // +14155550123
console.log(result.countryCode);  // US

// With country hint
const result2 = phone('4155550123', { country: 'US' });
console.log(result2.phoneNumber); // +14155550123

// Error handling
const invalid = phone('123');
if (!invalid.isValid) {
  console.error('Invalid phone number');
}

Using libphonenumber-js

libphonenumber-js is a lightweight implementation of Google's phone number library, optimized for web applications. It's based on Google's canonical libphonenumber but offers significantly better performance for JavaScript environments.

Installation and Setup

bash
npm install libphonenumber-js --save

Usage Example

javascript
import { parsePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';

// Basic validation
console.log(isValidPhoneNumber('+14155550123')); // true

// Parse and extract details
const phoneNumber = parsePhoneNumber('+14155550123');
console.log(phoneNumber.country);              // 'US'
console.log(phoneNumber.nationalNumber);       // '4155550123'
console.log(phoneNumber.formatInternational()); // '+1 415 555 0123'
console.log(phoneNumber.formatNational());     // '(415) 555-0123'
console.log(phoneNumber.getType());            // 'MOBILE' or 'FIXED_LINE'

// Error handling
try {
  const invalid = parsePhoneNumber('invalid');
} catch (error) {
  console.error('Parse error:', error.message);
  // Handle invalid input gracefully
}

Key Features

  • Lightweight Bundle: ~145 KB total (65 KB code + 80 KB min metadata) compared to Google's original implementation (~550 KB: 350 KB code + 200 KB metadata)
  • Regular Updates: Metadata regularly updated to reflect ITU changes (latest sync: September 19, 2025)
  • Type Safety: Full TypeScript support with type definitions
  • Multiple Build Formats: Supports ES modules, CommonJS, and tree-shaking
  • Flexible Metadata: Choose from min (~80 KB), mobile (~95 KB), or max (~145 KB) metadata sets based on your validation needs

Current Version: libphonenumber-js v1.12.23 (October 2025)

libphonenumber-js is ideal for web applications where bundle size is critical. For server-side applications where bundle size is less critical, Google's original libphonenumber implementation (available as google-libphonenumber v3.2.43 on npm) provides the most comprehensive validation.

Metadata Update Strategy:

Keep your validation library current to handle new numbering plans and country code changes:

json
// package.json
{
  "dependencies": {
    "libphonenumber-js": "^1.12.23"
  },
  "scripts": {
    "update-phone-metadata": "npm update libphonenumber-js"
  }
}

Schedule automated updates quarterly or monitor the libphonenumber-js release notes for critical metadata updates.

Modern Considerations: E.164 in Today's Digital Landscape

As communication technology evolves, several modern considerations have emerged for E.164 implementation:

Virtual Phone Numbers and VoIP

Cloud telephony services and VoIP providers have introduced virtual phone numbers that follow E.164 formatting but may not correspond to traditional geographic locations. RFC 3824 defines procedures for using E.164 numbers with the Session Initiation Protocol (SIP), the foundation of modern VoIP systems. When validating these numbers:

  • Verify that your validation logic accepts VoIP numbers (they're valid E.164 numbers)
  • Consider carrier lookup services to identify number types (mobile, landline, VoIP)
  • Handle porting scenarios where numbers move between carriers or technologies
  • ENUM (E.164 Number Mapping): ENUM translates E.164 phone numbers into URIs, enabling SIP routing. If a SIP address exists for a number, calls route via IP networks; otherwise, they route through the PSTN.

ENUM Lookup Implementation:

javascript
const dns = require('dns').promises;

async function performEnumLookup(e164Number) {
  // Convert +14155550123 to ENUM domain format
  // Result: 3.2.1.0.5.5.5.5.1.4.1.e164.arpa
  const enumDomain = e164Number
    .replace('+', '')
    .split('')
    .reverse()
    .join('.') + '.e164.arpa';

  try {
    const records = await dns.resolveNaptr(enumDomain);

    // Parse NAPTR records for SIP URIs
    const sipUris = records
      .filter(r => r.service.includes('E2U+sip'))
      .map(r => r.replacement);

    return sipUris.length > 0 ? sipUris[0] : null;
  } catch (error) {
    // No ENUM record found - route via PSTN
    return null;
  }
}

Carrier Lookup Services:

Use carrier lookup APIs to identify number types and routing:

  • Twilio Lookup API: Identifies carrier, line type, and porting status
  • Numverify API: Provides carrier and line type information
  • HLR Lookup: Queries Home Location Register for real-time number status

eSIM and Digital-First Numbers

The rise of eSIM technology has created new patterns in phone number provisioning. GSMA specifications govern eSIM remote provisioning: SGP.22 v2.6 (October 2024) for consumer devices and SGP.32 for IoT devices. Key considerations:

  • Numbers may be activated/deactivated more frequently through remote provisioning
  • Multiple numbers may be associated with a single device
  • Digital-first carriers may use non-traditional numbering patterns within E.164 constraints
  • E.164 numbers are part of the operator profile data provisioned to the eSIM

Privacy and Data Protection

Modern privacy regulations require careful handling of phone numbers:

GDPR Compliance (European Union)

  • Legal basis: Obtain explicit consent before storing phone numbers
  • Right to access: Provide data export in machine-readable format
  • Right to erasure: Implement hard deletion (not soft delete) within 30 days of request
  • Data minimization: Only collect phone numbers when necessary for your service
  • Audit logging: Track all access to phone number data

CCPA Compliance (California)

  • Right to know: Disclose what phone number data you collect and how you use it
  • Right to delete: Delete phone number data within 45 days of verified request
  • Right to opt-out: Allow users to opt out of phone number data sales
  • Non-discrimination: Don't penalize users who exercise privacy rights

Implementation Considerations

RequirementTechnical ImplementationCompliance Standard
Data exportJSON/CSV export with all associated phone dataGDPR Art. 20
Hard deletionPurge from databases, backups, and logsGDPR Art. 17
Consent trackingStore timestamp and consent methodGDPR Art. 7
Access loggingAudit trail with user ID, timestamp, actionGDPR Art. 5
PseudonymizationHash or tokenize for analyticsGDPR Art. 32

Pseudonymization Techniques:

javascript
const crypto = require('crypto');

// Option 1: Hashing (one-way, for analytics)
function pseudonymizePhone(phoneNumber, salt) {
  return crypto
    .createHash('sha256')
    .update(phoneNumber + salt)
    .digest('hex')
    .substring(0, 16); // Truncate for storage efficiency
}

// Option 2: Tokenization (reversible, for operational needs)
const tokenStore = new Map();
let tokenCounter = 1000000;

function tokenizePhone(phoneNumber) {
  const token = `PHN_${tokenCounter++}`;
  tokenStore.set(token, phoneNumber);
  return token;
}

function detokenizePhone(token) {
  return tokenStore.get(token);
}

Two-Factor Authentication (2FA) Considerations

When using phone numbers for 2FA:

Best Practices:

  • Support international numbers to avoid excluding global users
  • Implement fallback authentication methods for users without phone access
  • Consider the security implications of SMS-based 2FA versus app-based alternatives
  • Account for number recycling by carriers (old numbers reassigned to new users)

Security Concerns:

Attack TypeDescriptionMitigation
SIM swap attacksAttacker transfers victim's number to their own SIMImplement SIM change detection; require additional verification after SIM changes
SS7 vulnerabilitiesIntercept SMS via telecom protocol exploitsUse app-based TOTP instead of SMS; implement message encryption
Number recyclingCarrier reassigns old number to new userImplement number verification before account recovery; expire inactive accounts
PhishingSocial engineering to obtain 2FA codesEducate users; implement rate limiting on 2FA attempts

SIM Swap Detection:

javascript
// Track device fingerprints and detect SIM changes
async function detectSIMChange(userId, phoneNumber) {
  const lastKnownDevice = await getLastDeviceFingerprint(userId);
  const currentDevice = await getCurrentDeviceFingerprint();

  if (lastKnownDevice !== currentDevice) {
    // Possible SIM swap - require additional verification
    await sendEmailVerification(userId);
    await logSecurityEvent({
      type: 'SIM_CHANGE_DETECTED',
      userId,
      phoneNumber: hashPhone(phoneNumber),
      timestamp: Date.now()
    });

    return { verified: false, reason: 'Device change detected' };
  }

  return { verified: true };
}

Voice vs SMS 2FA Delivery:

Delivery MethodProsConsBest For
SMSWidely supported; familiar to usersSS7 vulnerabilities; can be interceptedStandard 2FA with low-value accounts
Voice callWorks without data connection; harder to interceptLess convenient; risk of voicemail exposureFallback method; users without SMS
App-based TOTPMost secure; no network dependencyRequires smartphone and app installationHigh-value accounts; security-conscious users
Push notificationUser-friendly; secureRequires app installation and internetModern applications with dedicated apps

Frequently Asked Questions About E.164 Format

What is E.164 format for phone numbers?

E.164 format is the ITU-T international standard for structuring phone numbers, consisting of a country code (1–3 digits), national destination code, and subscriber number, with a maximum total length of 15 digits. The format starts with a + symbol followed by digits only, for example: +14155550123. E.164 ensures global interoperability for telecommunications systems.

How do I convert a phone number to E.164 format?

To convert to E.164 format: (1) Remove all formatting characters (spaces, hyphens, parentheses), (2) Remove leading zeros if present, (3) Add the country code prefix with +, (4) Verify the number contains only digits and is 15 digits or fewer. Example: (415) 555-0123 becomes +14155550123. Use validation libraries like libphonenumber-js for automated conversion.

What is the regex for E.164 validation?

The basic E.164 regex pattern is: ^\+[1-9]\d{1,14}$

This matches a + symbol, followed by a non-zero digit, then 1–14 additional digits (total 2–15 digits after the +). Note: This validates structure only and does not verify country-specific rules or number validity.

Why is E.164 format important for international phone numbers?

E.164 format ensures global interoperability for telecommunications, enabling consistent phone number parsing, validation, and call routing across different countries, carriers, and systems. Without E.164 standardization, international calls would fail, SMS messages wouldn't deliver, and VoIP services couldn't properly route communications. The format eliminates ambiguity in phone number interpretation across 195+ country codes.

Can E.164 format include country codes?

Yes, E.164 format always includes the country code as the first 1–3 digits after the + symbol. The country code is mandatory in E.164 format to enable international dialing.

What's the difference between E.164 and national phone number formats?

E.164 is the international format that always includes the country code (e.g., +14155550123), while national formats are country-specific and omit the country code (e.g., (415) 555-0123 in the USA). National formats often include local formatting conventions like parentheses, hyphens, and spaces for readability. E.164 standardization enables global compatibility and unambiguous number identification across borders, making it essential for international telecommunications, SMS gateways, and VoIP systems.

Is the + symbol required in E.164 format?

The + symbol is used for display purposes to indicate the international format, but the stored E.164 format should contain only digits. The + helps distinguish international numbers from local formatting.

How do I validate E.164 phone numbers in JavaScript?

The most reliable method is using specialized validation libraries like libphonenumber-js or phone npm package, which maintain current country-specific rules:

javascript
import { isValidPhoneNumber, parsePhoneNumber } from 'libphonenumber-js';

// Simple validation
console.log(isValidPhoneNumber('+14155550123')); // true

// Detailed validation with error handling
function validatePhone(input) {
  try {
    const phone = parsePhoneNumber(input);
    return {
      valid: phone.isValid(),
      country: phone.country,
      type: phone.getType(),
      formatted: phone.formatInternational()
    };
  } catch (error) {
    return {
      valid: false,
      error: error.message
    };
  }
}

// Usage:
const result = validatePhone('+14155550123');
console.log(result);
// { valid: true, country: 'US', type: 'MOBILE', formatted: '+1 415 555 0123' }

For basic format validation, use regex: /^\+[1-9]\d{1,14}$/, but note this doesn't verify country-specific rules or actual number validity.

How do I use E.164 format with Twilio for SMS?

Twilio requires phone numbers in E.164 format for SMS and voice calls. Convert numbers using libphonenumber-js before sending:

javascript
import { parsePhoneNumber } from 'libphonenumber-js';
import twilio from 'twilio';

const client = twilio(accountSid, authToken);

// Convert to E.164 before sending
const phoneNumber = parsePhoneNumber('(415) 555-0123', 'US').format('E.164');

await client.messages.create({
  body: 'Your verification code is 123456',
  from: '+14155551234',
  to: phoneNumber  // Must be E.164 format: +14155550123
});

Learn more about Twilio E.164 requirements for SMS delivery.

What is the minimum length for E.164 phone numbers?

The E.164 format minimum length varies by country but typically ranges from 8 to 15 digits total (including country code). For example, US numbers are always 11 digits (+1 followed by 10 digits), while some countries like the Solomon Islands may have shorter numbers. Use validation libraries to check country-specific minimum lengths.

Conclusion: Implementing E.164 Phone Number Validation

By understanding and implementing the E.164 international phone number format, you ensure accurate and reliable global communication for your applications. This comprehensive guide has equipped you with:

  • Technical knowledge of E.164 format specifications and structure
  • Validation strategies using regex patterns and validation libraries
  • Implementation examples with libphonenumber-js and the phone library
  • Best practices for security, privacy, and modern telecommunications
  • Troubleshooting solutions for common phone number validation issues

Whether you're building authentication systems, international calling features, or SMS messaging platforms, proper E.164 implementation is critical for global interoperability. Stay updated on ITU-T revisions and maintain your country code databases for optimal performance.

Ready to implement E.164 validation in your application? Start with libphonenumber-js for lightweight web applications or Google's libphonenumber for comprehensive server-side validation. Both libraries handle the complexity of country-specific rules, allowing you to focus on building great user experiences with reliable international phone number support.

Frequently Asked Questions

What is the E.164 phone number format?

E.164 is an international standard defining the format of phone numbers for global communication. It ensures consistent call routing and compatibility between different countries and network operators. This format is essential for accurate identification and connection with phone numbers worldwide, supporting various communication technologies like mobile, IP telephony, and international roaming.

How to validate E164 phone numbers?

E.164 validation involves a multi-layered approach. Start with basic format validation using a regex to check the structure. Then, perform country-specific checks using a database of regional rules and restrictions. Finally, validate the total number length, accounting for variable NDC lengths within certain countries. This comprehensive strategy helps ensure data integrity.

Why is E.164 important for global communication?

E.164 is crucial for seamless international communication by providing a standardized format for phone numbers. This facilitates consistent call routing, network interoperability, and reliable access to emergency services. It supports essential features such as mobile number portability and international roaming capabilities, accommodating advancements in communication technologies.

How to format phone numbers for international calls?

For international calls, use the plus sign (+) followed by the country code, national destination code, and subscriber number. For example, +1-415-555-0123. This format ensures correct routing across global networks. Remember to store phone numbers in the pure E.164 format without any formatting characters for consistency.

What is the maximum length of an E.164 number?

The maximum length of an E.164 number is 15 digits. This includes the country code (1-3 digits), national destination code (typically 2-4 digits), and subscriber number. The minimum length is the country code length plus at least one additional digit. These length constraints are essential for global compatibility.

How to convert local phone numbers to E.164?

To convert local numbers to E.164, first remove any non-digit characters like spaces, hyphens, or parentheses. Then, prepend the appropriate country code. For instance, a US number (415) 555-0123 would become +14155550123. This ensures consistent handling regardless of the original input format.

When should I use libphonenumber-js for E.164?

Consider using libphonenumber-js when building web applications that require E.164 validation and formatting, especially if minimizing bundle size is a priority. It offers a smaller footprint than Google's full phone number library while providing essential features for accurate handling of international phone numbers.

What are the three components of an E.164 number?

An E.164 number comprises three key components: the Country Code (CC), National Destination Code (NDC), and Subscriber Number (SN). The CC identifies the country, the NDC specifies a region within the country, and the SN uniquely identifies the individual subscriber. These components are crucial for correct routing and identification of phone numbers.

How does E.164 handle mobile number portability?

E.164 supports mobile number portability, allowing users to keep their numbers when switching carriers. This ensures continuous connectivity and prevents disruption of communication services. This feature is managed within the NDC framework within each country or region.

Can I use libraries for E.164 validation in JavaScript?

Yes, JavaScript libraries like `phone` and `libphonenumber-js` simplify E.164 validation. These libraries provide efficient and accurate methods to check phone number compliance with international standards, handling diverse input formats and edge cases.

What is the history of E.164?

Initially introduced in 1984 for ISDN, E.164 has evolved to support modern telecommunications, including IP telephony, mobile number portability, and emergency services. Its maximum length was expanded from twelve to fifteen digits in 1997. This continuous evolution maintains its relevance in the changing communication landscape.

How to handle invalid country codes in E.164?

When dealing with invalid country codes, cross-check them against the official ITU-T list. Also, verify the number's length complies with country-specific rules. Regularly updating your country code database is vital, as these codes can change, potentially invalidating existing data.

Why store E.164 numbers without formatting?

Storing E.164 numbers without formatting, such as spaces or hyphens, ensures data consistency and simplifies processing. This 'pure' format facilitates accurate comparisons, validation, and integration with various systems and databases. Always use local formatting only for display purposes.