Phone Number Formatting
How to correctly format international phone numbers for the Click Airtime API, including E.164 format, country codes, and validation.
Correct phone number formatting is critical for successful airtime top-ups. This guide explains the formats accepted by the Click Airtime API and provides validation examples.
E.164 Format
The international standard for phone number formatting is E.164. An E.164 number consists of:
+[country code][subscriber number]
- Maximum 15 digits total (including country code)
- Always starts with
+followed by the country code - No spaces, dashes, or parentheses
Examples
| Country | E.164 Format | Country Code | Subscriber Number |
|---|---|---|---|
| Ghana | +233541112259 | 233 | 541112259 |
| Kenya | +254722123456 | 254 | 722123456 |
| Nigeria | +2348031234567 | 234 | 8031234567 |
| Tanzania | +255712345678 | 255 | 712345678 |
| South Africa | +27821234567 | 27 | 821234567 |
| Mozambique | +258841234567 | 258 | 841234567 |
| United Kingdom | +447911123456 | 44 | 7911123456 |
API Format Requirements
Version 2 API
The V2 API requires E.164 format with the + prefix:
+233541112259
Version 1 API
The V1 API accepts international format without the + prefix:
233541112259
When migrating from V1 to V2, simply prepend + to all existing phone numbers. See the Migration Guide for more details.
Validation
Basic Validation
Before sending a phone number to the API, perform basic client-side validation:
function isValidE164(phoneNumber) {
// E.164: + followed by 1-15 digits
const e164Regex = /^\+[1-9]\d{1,14}$/;
return e164Regex.test(phoneNumber);
}
// Examples
console.log(isValidE164('+233541112259')); // true
console.log(isValidE164('233541112259')); // false (no + prefix)
console.log(isValidE164('+0541112259')); // false (starts with 0)
console.log(isValidE164('+233')); // true (valid but too short for Ghana)import re
def is_valid_e164(phone_number: str) -> bool:
"""Validate E.164 phone number format."""
pattern = r'^\+[1-9]\d{1,14}$'
return bool(re.match(pattern, phone_number))
# Examples
print(is_valid_e164('+233541112259')) # True
print(is_valid_e164('233541112259')) # False
print(is_valid_e164('+0541112259')) # Falsefunction isValidE164(string $phoneNumber): bool {
return preg_match('/^\+[1-9]\d{1,14}$/', $phoneNumber) === 1;
}
// Examples
var_dump(isValidE164('+233541112259')); // true
var_dump(isValidE164('233541112259')); // false
var_dump(isValidE164('+0541112259')); // falseLibrary-Based Validation
For production use, we recommend the google-libphonenumber library which provides comprehensive phone number parsing, formatting, and validation:
const { PhoneNumberUtil, PhoneNumberFormat } = require('google-libphonenumber');
const phoneUtil = PhoneNumberUtil.getInstance();
function validateAndFormat(phoneNumber, defaultCountry = null) {
try {
const parsed = phoneUtil.parse(phoneNumber, defaultCountry);
if (!phoneUtil.isValidNumber(parsed)) {
return { valid: false, error: 'Invalid phone number' };
}
return {
valid: true,
e164: phoneUtil.format(parsed, PhoneNumberFormat.E164),
country: phoneUtil.getRegionCodeForNumber(parsed),
countryCode: parsed.getCountryCode(),
};
} catch (error) {
return { valid: false, error: error.message };
}
}
// Examples
console.log(validateAndFormat('+233541112259'));
// { valid: true, e164: '+233541112259', country: 'GH', countryCode: 233 }
console.log(validateAndFormat('0541112259', 'GH'));
// { valid: true, e164: '+233541112259', country: 'GH', countryCode: 233 }
console.log(validateAndFormat('541112259', 'GH'));
// { valid: true, e164: '+233541112259', country: 'GH', countryCode: 233 }import phonenumbers
def validate_and_format(phone_number, default_country=None):
try:
parsed = phonenumbers.parse(phone_number, default_country)
if not phonenumbers.is_valid_number(parsed):
return {'valid': False, 'error': 'Invalid phone number'}
return {
'valid': True,
'e164': phonenumbers.format_number(parsed, phonenumbers.PhoneNumberFormat.E164),
'country': phonenumbers.region_code_for_number(parsed),
'country_code': parsed.country_code,
}
except phonenumbers.NumberParseException as e:
return {'valid': False, 'error': str(e)}
# Examples
print(validate_and_format('+233541112259'))
# {'valid': True, 'e164': '+233541112259', 'country': 'GH', 'country_code': 233}
print(validate_and_format('0541112259', 'GH'))
# {'valid': True, 'e164': '+233541112259', 'country': 'GH', 'country_code': 233}Common Formatting Issues
Local Numbers
Users often enter local numbers without the country code. You should either:
- Require E.164 input from the start
- Accept local numbers with a country selector and format them server-side
// Convert local Ghanaian number to E.164
function formatGhanaNumber(localNumber) {
// Remove leading zero if present
const cleaned = localNumber.replace(/^0/, '');
return `+233${cleaned}`;
}
formatGhanaNumber('0541112259'); // '+233541112259'
formatGhanaNumber('541112259'); // '+233541112259'
Common Mistakes
| Input | Problem | Correct Format |
|---|---|---|
0541112259 | Local format, missing country code | +233541112259 |
00233541112259 | Uses 00 international prefix instead of + | +233541112259 |
+233 054 111 2259 | Contains spaces | +233541112259 |
+233-054-111-2259 | Contains dashes | +233541112259 |
233541112259 | Missing + prefix (valid for V1, invalid for V2) | +233541112259 |
Supported Countries
Click Airtime supports airtime top-ups to over 150 countries. Use the catalog endpoint to check whether a specific phone number is supported and see available products.
Network Detection: The Click Airtime API automatically detects the mobile network operator (MNO) for each phone number using HLR (Home Location Register) lookup. If a number has been ported to a different network, you can override the detection by specifying the airtimeAccountId in the V2 API.
