- Home
- API
- Verification API
- How to validate a UK phone num ...

UK phone number validation looks simple until you try to do it properly. A naive regex catches obvious garbage but passes 070 personal numbers as mobile, accepts 056 VoIP ranges your OTP provider cannot reach, and silently accepts numbers that are structurally valid but unallocated. This guide explains the UK numbering plan, provides production-ready regex patterns, and shows how to use an API to validate real-world usability.
This is the most important section.
| Prefix | Type | Digits | Description | Developer Notes |
|---|---|---|---|---|
| 01, 02 | Geographic landline | 10–11 | Area-based numbers | Varying area codes |
| 03 | Non-geographic | 11 | Same cost as landline | Safe for OTP |
| 055 | Corporate VoIP | 11 | Enterprise blocks | Rare |
| 056 | VoIP | 11 | Internet-based | No SMS |
| 070 | Personal numbers | 11 | Call forwarding | ⚠️ Scam risk |
| 071–075, 077–079 | Mobile | 11 | Standard mobile | SMS supported |
| 076 | Pager | 11 | Legacy paging | Ignore |
| 0800, 0808 | Freephone | 11 | Free to call | No OTP |
| 084, 087 | Special rate | 11 | Paid service | Reject |
| 09 | Premium | 11 | High cost | Reject |
070 is NOT a mobile prefix.
It looks like 07 but:
👉 Always validate sub-ranges, not just “starts with 07”.
| Format | Example |
|---|---|
| National | 07700 900123 |
| E.164 | +447700900123 |
Always store in E.164
import re
def to_e164_uk(number: str) -> str | None:
digits = re.sub(r"\D", "", number)
if digits.startswith("44") and len(digits) == 12:
return "+" + digits
if digits.startswith("0") and len(digits) == 11:
return "+44" + digits[1:]
return None| Type | Total Digits | Example |
|---|---|---|
| London | 11 | 020 7946 0958 |
| Mobile | 11 | 07700 900123 |
| Landline | 11 | 01632 960123 |
| Non-geographic | 11 | 0300 123 4567 |
👉 Rule: 99% of UK numbers = 11 digits
import re
def clean(n: str) -> str:
return re.sub(r"[\s\-\(\)\.]", "", n)
PATTERNS = {
"mobile": re.compile(r"^(\+44|0)7([1-9]\d{2}|624)\d{6}$"),
"personal_070": re.compile(r"^(\+44|0)70\d{8}$"),
"landline": re.compile(r"^(\+44|0)[12]\d{9}$"),
"national_03": re.compile(r"^(\+44|0)3\d{9}$"),
"voip": re.compile(r"^(\+44|0)56\d{8}$"),
"freephone": re.compile(r"^(\+44|0)80[08]\d{7}$"),
"special": re.compile(r"^(\+44|0)8[47]\d{8}$"),
"premium": re.compile(r"^(\+44|0)9\d{9}$"),
}
def classify(number):
n = clean(number)
for t, p in PATTERNS.items():
if p.match(n):
return {"valid": True, "type": t}
return {"valid": False}Regex validates format only — NOT real-world validity.
➡️ For live status, use API (next section)
👉 Start validating UK numbers in production:
Free tier: 500 requests/month (no card required)
Regex cannot tell:
import requests
API_KEY = "your_api_key"
def validate_phone(number):
resp = requests.get(
"https://phone.apitier.com/v1/phone/validate",
params={
"phoneNumber": number,
"countryCode": "GB",
"x-api-key": API_KEY
}
)
return resp.json()const axios = require("axios");
async function validate(number) {
const res = await axios.get(
"https://phone.apitier.com/v1/phone/validate",
{
params: {
phoneNumber: number,
countryCode: "GB",
"x-api-key": "your_key"
}
}
);
return res.data;
}
curl "https://phone.apitier.com/v1/phone/validate?phoneNumber=%2B447700900123&countryCode=GB&x-api-key=your_key"| Field | Meaning | Action |
|---|---|---|
| valid | Format + allocation | Reject if false |
| lineType | mobile, voip, etc | Filter |
| carrier | Network | Routing |
| liveStatus | active/inactive | OTP decision |
| internationalFormat | +44 format | Store |
| localFormat | 07 format | Display |
Red flags:
11 digits (national) or +44 + 10 digits (E.164)
07 = mobile
070 = personal forwarding (NOT mobile)
Yes (regex), but no live status
E.164 (+447700900123)
Yes, but NOT for OTP
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How many digits does a UK mobile number have?",
"acceptedAnswer": {
"@type": "Answer",
"text": "UK mobile numbers have 11 digits in national format and 12 characters in E.164 format."
}
},
{
"@type": "Question",
"name": "What is the difference between 07 and 070 numbers?",
"acceptedAnswer": {
"@type": "Answer",
"text": "07 is mobile, 070 is personal forwarding and not suitable for SMS."
}
}
]
}Ready to validate UK phone numbers properly?
👉 Get started now:
500 free API calls/month
No credit card
Supports mobile, landline, VoIP detection