- 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.
The UK phone numbering plan — a developer field guide
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 |
Critical rule (MOST IMPORTANT)
070 is NOT a mobile prefix.
It looks like 07 but:
- cannot reliably receive SMS
- often used in fraud
👉 Always validate sub-ranges, not just “starts with 07”.
UK phone number format rules — the things regex gets wrong
E.164 international format vs national format
| Format | Example |
|---|---|
| National | 07700 900123 |
| E.164 | +447700900123 |
Always store in E.164
Python: Convert to 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 NoneLength rules by number type
| 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
Format validation — regex patterns by number type
Python Implementation
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}⚠️ Important
Regex validates format only — NOT real-world validity.
➡️ For live status, use API (next section)
CTA (Mid Article)
👉 Start validating UK numbers in production:
- https://www.apitier.com/api-catalogue/validate-phone-api
- https://docs.apitier.com/docs/validate-phone-api/getting-started
Free tier: 500 requests/month (no card required)
Live validation via API — beyond format checking
Regex cannot tell:
- if number exists
- if SIM is active
- if it can receive SMS
Python API Example
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()Node.js Example
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 Example
curl "https://phone.apitier.com/v1/phone/validate?phoneNumber=%2B447700900123&countryCode=GB&x-api-key=your_key"API response fields explained
| 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 |
Four real-world use cases
1. Signup form
- Accept: mobile, landline
- Reject: premium, voip, 070
2. OTP verification
- Only mobile
- Must be active
3. CRM cleaning
- Normalize to E.164
- Remove inactive
4. Fraud detection
Red flags:
- VoIP
- 070 numbers
- inactive SIM
Five gotchas that break UK validation
- 070 ≠ mobile
- 056 = VoIP
- London = 3-digit code (020)
- Always store E.164
- Carrier ≠ original network
Frequently Asked Questions
How many digits does a UK mobile number have?
11 digits (national) or +44 + 10 digits (E.164)
What is difference between 07 and 070?
07 = mobile
070 = personal forwarding (NOT mobile)
Can I validate without API?
Yes (regex), but no live status
What format should I store?
E.164 (+447700900123)
Are 0800 numbers valid?
Yes, but NOT for OTP
JSON-LD FAQ Schema
{
"@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."
}
}
]
}Final Thoughts
Ready to validate UK phone numbers properly?
👉 Get started now:
500 free API calls/month
No credit card
Supports mobile, landline, VoIP detection


