1001Ferramentas
📱Validators

Country-aware Cellphone Validator

Validate mobile phone number for chosen country (BR, US, PT, ES, AR, MX). Country-specific rules.

Validating mobile numbers by country: E.164, libphonenumber and the local rules

A mobile number on the internet is not just any string of digits — it is a structured identifier defined by ITU-T Recommendation E.164. The standard says: a country code (1 to 3 digits) followed by a national number, totaling at most 15 digits, written with a leading +. So +5511999998888 is a Brazilian mobile in canonical E.164 form. Every WhatsApp, Telegram, Twilio or AWS SNS request expects E.164 input. This validator picks a country, strips formatting, applies the country-specific rules and reports whether the number is well-formed and likely mobile (vs fixed line, VoIP or toll-free).

E.164 in one paragraph

Format: +CC NNNNNNNNNN where CC is 1-3 digits (the ITU-assigned country code) and the national part is up to 12 digits. No spaces, no parentheses, no dashes — those are display formatting only. Maximum total length: 15 digits after the +. The + itself is a placeholder for the international access prefix that varies by country (00 in Europe, 011 in the US, 00 in Brazil).

Country-by-country mobile rules

  • Brazil (+55) — 2-digit DDD (area code) + 9-digit mobile starting with literal 9. The leading 9 became mandatory in 2014 for all states. Total: 13 digits after +. Example: +5511999998888.
  • USA / Canada (+1) — North American Numbering Plan (NANP): 3-digit area code (NPA) + 3-digit exchange (NXX) + 4 digits. No distinction between mobile and fixed at the format level. Example: +14155551234.
  • UK (+44) — mobile numbers always start with 7, followed by 9 digits. Example: +447911123456.
  • Germany (+49) — mobile prefixes 15x, 16x, 17x + 7-8 digits.
  • Japan (+81) — mobile prefixes 70, 80, 90 + 8 digits.
  • China (+86) — mobile prefixes 13x, 14x, 15x, 17x, 18x, 19x + 8 digits.
  • India (+91) — 10 digits, first digit always 6-9 for mobile.
  • Mexico (+52) — 10 digits. The historical 1 prefix before mobile numbers was dropped in 2019.
  • Argentina (+54)9 prefix + area code + number for mobile (used in international calls and WhatsApp): +5491112345678.

libphonenumber: the only library you should use

libphonenumber was open-sourced by Google in 2010 to power Android's contacts app. It contains a metadata table of every country's numbering plan, refreshed regularly, with regex patterns for valid mobile, fixed, toll-free and premium ranges. Ports exist for every major language: libphonenumber-js (browser-friendly JavaScript, ~140 KB), libphonenumber-java, phonenumbers (Python), libphonenumber-android.

import { parsePhoneNumber } from 'libphonenumber-js'
const n = parsePhoneNumber('+5511999998888')
n.isValid()           // true
n.getType()           // 'MOBILE'
n.country             // 'BR'
n.format('E.164')     // '+5511999998888'
n.format('INTERNATIONAL') // '+55 11 99999 8888'

The anti-pattern: writing your own per-country regex. Country numbering plans change (Mexico dropped the 1 in 2019, Brazil added the 9 in 2014, El Salvador added a digit in 2017), and you will not catch those updates manually. Use libphonenumber and let Google's data team do the work.

Mobile vs fixed line vs toll-free vs VoIP

  • Mobile — the original use case for SMS, WhatsApp, OTP delivery. In Brazil, the leading 9 makes detection trivial.
  • Fixed line — typically shorter or with a non-mobile prefix; cannot receive SMS reliably.
  • Toll-free — Brazil 0800, US 1-800/888/877/866. Reachable inbound only; no SMS.
  • Premium rate — Brazil 0900, US 1-900. Caller is charged; rarely valid for user accounts.
  • VoIP (DID) — assigned by providers like Twilio, Vonage, Plivo. Often reachable for SMS but flagged as risky by fraud systems.

For sign-up forms that gate accounts behind SMS verification, libphonenumber.getType() values MOBILE and FIXED_LINE_OR_MOBILE are typically accepted; VOIP, TOLL_FREE and PREMIUM_RATE are rejected.

The Brazilian context: WhatsApp as identity

In Brazil, the mobile number is effectively a national identity — WhatsApp penetration is above 95% of internet users, and e-commerce, fintechs and government services authenticate via WhatsApp or SMS to that number. The WhatsApp Business API requires a real, owned, E.164-valid number. Failing to validate the mobile correctly means dead OTP messages, abandoned signups and angry support tickets. Always send a test OTP after the format check before trusting the number.

Validation algorithm in five steps

  1. Strip non-digits — keep only 0-9 and an optional leading +.
  2. Detect or assume country code — either from the leading + or a default locale.
  3. Apply E.164 length cap — max 15 digits after +.
  4. Match the country's mobile pattern — leading-9 for BR, leading-7 for UK, leading 6-9 for IN, etc.
  5. Reject toll-free, premium, VoIP if your use case requires real mobile.

FAQ

Which library should I use? libphonenumber-js for JavaScript, libphonenumber-java for the JVM, phonenumbers for Python. They share the same metadata, so results are consistent across stacks.

What is the maximum length of an E.164 number? 15 digits after the +. The country code is 1-3 digits, leaving 12 for the national number.

Are toll-free numbers valid? Yes, syntactically — but they are inbound-only and cannot receive SMS or WhatsApp. Reject them in any sign-up flow that needs mobile verification.

Why does my Brazilian number look invalid? Likely missing the mandatory 9 in front of the 8-digit landline-era mobile. +551199998888 is obsolete; the correct form is +5511999998888 with 9 digits after the DDD.

Should I store numbers in E.164 or local format? Always store in E.164 (+5511999998888) and format for display with libphonenumber.format(). Local format is locale-specific and breaks the moment a user travels or changes country.

Related Tools