Phone Number Portability: Tracking Numbers Across Carriers

Navigate the complexities of phone number portability and its impact on validation, carrier detection, and user experience.

Phone Number Portability: Tracking Numbers Across Carriers
8 septembre 2025
Mis à jour le 6 juin 2026
11 min read
Phone Validation

Mobile Number Portability (MNP) allows users to change carriers without changing their MSISDN. For validation and carrier tracking, this means: HLR/NP databases are mandatory, and operator prefixes are often misleading.

Phone Number Portability Overview
Phone Number Portability Overview

Cleariflow Phone Validation API scope: Our Phone Validation API performs structural validation via Google libphonenumber, E.164 normalization, line type, and optional carrier/location metadata (mainly US/CA). It does not resolve MNP or perform HLR lookups. This article covers portability concepts for teams building a larger telco data stack.

MNP Basics

  • Ported: number has been transferred — the original MCC/MNC prefix does not reflect the current operator.
  • Non-ported: number remains with the original operator.
  • Partial MNP: countries without centralized database — requires HLR query to the home network.

Prioritize: fast cache → local NP database → HLR/NP provider with status confirmation.

Data Sources and Standards

  • NP Registry: centralized databases (e.g., EU/some APAC countries). Response provides current operator and porting date.
  • HLR Lookup: actual subscriber status (active/inactive), current operator's MCC/MNC, possibly roaming status.
  • CRDB/ENUM (in some countries): MSISDN→routing mapping.

Best practice: update local NP cache every 24h, HLR results every 1–4h; include data version in API response.

Validation Flow and Fallbacks

type MNPInfo = { isPorted: boolean; current: { mcc: string; mnc: string; carrier: string }; portedAt?: number }

async function resolveCarrier(msisdn: string): Promise<MNPInfo> {
  const cached = await cache.get(msisdn)
  if (cached) return cached

  // 1) Fast NP database
  const np = await npRegistry.lookup(msisdn).catch(() => null)
  if (np) return save(msisdn, normalize(np))

  // 2) HLR fallback
  const hlr = await hlrProvider.lookup(msisdn, { timeoutMs: 3000 }).catch(() => null)
  if (hlr) return save(msisdn, normalize(hlr))

  // 3) Prefix as last resort (low confidence)
  const inferred = inferByPrefix(msisdn)
  return { ...inferred, isPorted: true } // mark as uncertain
}

Key point: explicitly mark confidence level and source (np|hlr|prefix) so business logic can respond appropriately.

Fraud Signals Around Porting

Porting is often used in fraud/ATO schemes:

  • Fresh Port (< 7 days): elevated risk for SMS OTP/2FA — request additional verification.
  • Frequent Ports (n transfers within 90 days): risk flag.
  • Carrier Mismatch: discrepancy between geo/payment instrument and current operator.

Recommendation: mark such cases as risk=high, request alternative verification channel (push/email/WebAuthn).

Implementation Notes

  • Number normalization: E.164, cleanup, auto-add country code on backend.
  • TTL: MNP 24h, HLR 1–4h, prefix 1h. Update on events (SMS delivery errors, user complaints).
  • Rate limits: HLR is expensive — set budget and degrade to NP/prefix.
  • API response: { isPorted, current: { mcc,mnc,carrier }, portedAt, confidence, source }.

Monitoring and SLAs

  • Metrics: % correct operators (by SMS delivery/DR), average latency, provider error rate, fresh port percentage.
  • Alerts: spike in fresh ports, OTP delivery failure, increase in HLR timeouts.
  • SLA: p95 < 400ms via cache; operator accuracy > 98% on validation deliveries.

Start with Cleariflow Phone Validation API for format and region detection. Add MNP/HLR providers separately when you need current operator or line-status data.

Tags:number-portabilitycarrier-switchingmnpvalidation-challenges