Phone

Brazilian phone numbers: mobile, landline and service numbers.

  • Parity matrix

Validate

Validates a Brazilian phone number, mobile or landline by default.

  • The function accepts a country code (+55, 0055 or a bare 55) and removes it first, as in phone.parse. A bare 55 is removed only when 10 or 11 digits are left.
  • The DDD must be a valid Brazilian area code (00 is not).
  • Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid. Until 2.4.0 such characters were dropped, so 11 98765-4321x was valid.
  • The character check applies to the string form of any input, not only to strings: an object whose toString returns "190x" is invalid, as "190x" is, while one that returns "190" is read as the service number 190 with accept: ["service"]. An array of characters is not read as the joined string and is invalid. Only phone.isValid reads the string form; phone.isValidMobile, phone.isValidLandline and phone.isValidService return false for a value that is not a string.
  • options.accept (default ["mobile", "landline"]) lists the kinds of number that count as valid: mobile, landline and service (the numbers phone.isValidService recognizes). An empty list rejects everything.
  • options.version (1 or 2, default 1) is forwarded to phone.isValidMobile: both versions need 7, 8 or 9 as the first subscriber digit, and 2 also rejects the 700 series (satellite service).
  • A mobile number needs 7, 8 or 9 as its first subscriber digit under both numbering rules (Resolução Anatel nº 749/2022, art. 12). 2.4.0 also accepted 6 by default.
ParameterTypeRequired
valuestringyes
optionsIsValidPhoneOptionsno
options.versionPhoneVersionno
options.acceptPhoneType[]no
returnsboolean

Check if a phone number (mobile or landline) is valid. A Brazilian country code (+55, 0055 or a bare 55) is accepted and removed first, as in parsePhone. Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid; up to 2.4.0 such characters were dropped.

  • Options (IsValidPhoneOptions): accept (PhoneType[], default ['mobile', 'landline']) picks which kinds of number count as valid; add 'service' for the numbers isValidServicePhone recognizes. version (PhoneVersion, default 1) is forwarded to isValidMobilePhone.
  • A mobile number must start with 7, 8 or 9 under both versions (Resolução Anatel 749/2022, art. 12, I, "a"), so a leading 6 is rejected; up to 2.4.0 the default version accepted it.
import { isValidPhone } from '@brazilian-utils/brazilian-utils';

isValidPhone('11900000000'); // true
isValidPhone('11712345678', { version: 2 }); // true (7, 8 and 9 are all SMP)
isValidPhone('11700123456', { version: 2 }); // false (the 700 series is satellite)
isValidPhone('11612345678'); // false (6 is not SMP)
isValidPhone('+55 11 98765-4321'); // true (country code accepted)
isValidPhone('08001234567'); // false (service numbers rejected by default)
isValidPhone('08001234567', { accept: ['service'] }); // true
isValidPhone('11900000000', { accept: [] }); // false

Source: Resolução Anatel nº 749/2022.

Code: brazilian-utils/javascript
Try it with JavaScript isValidPhone
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (64) and the result in each library phone.isValid

Format

Formats a phone number according to Brazilian patterns.

  • options.mask (default sn) picks the pattern: sn (subscriber number only, 9 digits: 98765-4321), nanp (DDD plus number, (11) 90000-0000, 11 digits for a mobile and 10 for a landline, any other length keeps the 11-digit grouping), e164 (+5511987654321), international (+55 11 98765-4321), service (0800 123 4567, 4004-1234) and auto. An unknown mask falls back to sn.
  • If the value includes a DDD, pass { mask: "auto" } or "nanp": the default sn mask assumes no DDD and truncates one (11900000000 gives 11900-0000).
  • auto picks service for a service number, international when the value carries a country code, otherwise nanp for more than 9 digits and sn for the rest.
  • e164 and international first drop a country code in the input, as phone.parse does, and fall back to service for a service number. e164 keeps at most the 11 national digits, as international does (119888877660000 gives +5511988887766). Until 2.4.0 e164 kept them all.
  • sn and nanp drop an explicit +55 or 0055 too, so +5511987654321 gives (11) 98765-4321 under nanp. Until 2.4.0 it gave (55) 11987-6543. A bare 55 stays, since it may be the DDD (5511988887777 gives (55) 11988-8877 under nanp).
  • A number still being typed after an explicit country code is formatted as far as it goes (+55 11 9 gives +55 11 9 under international and auto, +55119 under e164). The value +55 alone returns an empty string.
  • options.obfuscate (default false, read for truthiness) hides the subscriber number with * under every mask. It keeps the prefix that names a region or a service (the DDD, +55, the 0800-like code, the 300X/400X root) and the last 2 digits the mask has room for: (11) *****-**21, 0800 *** **67, 4004-**34. This is a convention of the library, not an official rule. It keeps the count of the gov.br account, which shows only the last 2 digits of a mobile. The DDD stays visible, although gov.br hides it.
  • With the default subscriber-number mask, a DDD-prefixed value is truncated before it is obfuscated, so the visible pair is not the last 2 digits of the input (11987654321 gives *****-**43). Pass { mask: "auto" } when the value has a DDD.
  • Under the service mask with obfuscate, a value that is only a service prefix so far keeps it (0800 stays 0800), since the prefix names a service, not a subscriber. A value too short to be recognized (080) is fully hidden (***). A value that is not a service number becomes one * per digit, which hides the digits but not how many there were.
  • With obfuscate, a valid 3-digit public utility code (190) is returned as it is under the service, auto, e164 and international masks. The sn and nanp masks read it as an ordinary short number and hide it.
  • Under e164 with obfuscate, the digits after the 11th national digit are dropped. This affects only invalid input.
  • A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string (2.4.0 read the digits of any number).

Pending decision

The reference (JS) defaults to the subscriber-number mask, which truncates a DDD-prefixed number. The other libraries default to (11)99402-9275. See the open decision in docs/findings.md.

ParameterTypeRequired
valuestring | numberyes
optionsFormatPhoneOptionsno
options.maskPhoneMaskno
options.obfuscatebooleanno
returnsstring

Format a phone number according to Brazilian patterns. If value includes a DDD, pass { mask: 'auto' } or 'nanp': the default "sn" mask assumes no DDD and truncates one.

  • Options (FormatPhoneOptions): mask (PhoneMask, default "sn") picks one of the patterns below. An unknown mask falls back to "sn". obfuscate (default false) hides the subscriber number under every mask.
  • "sn": subscriber number only, 9 digits. "nanp": DDD plus subscriber number, 11 digits for a mobile and 10 for a landline; any other length keeps the 11 digit grouping.
  • "e164" and "international" drop the country code first, as parsePhone does, and fall back to "service" for a service number. "e164" keeps at most the 11 national digits, as "international" does (up to 2.4.0 it kept them all).
  • "sn" and "nanp" drop an explicit +55 or 0055 too, so '+5511987654321' gives (11) 98765-4321 under "nanp" (up to 2.4.0 it gave (55) 11987-6543); a bare 55 stays, since it may be the DDD.
  • A number is read when it is a string or a non-negative safe integer; any other number (negative, fractional, not finite or unsafe) gives an empty string.
  • Under the "service" mask with obfuscate, a value that is only a service prefix so far keeps it (0800 stays 0800), since the prefix names a service, not a subscriber; a value too short to be recognized (080) is fully hidden (***).
  • "service": the Códigos Não Geográficos (0800 123 4567) and the abbreviated 300X/400X numbers (4004-1234).
  • "auto": "service" for a service number, "international" when value carries a country code, otherwise "nanp" for more than 9 digits, else "sn".
  • obfuscate is a convention of this library, not an official rule: no law, Anatel act or ANPD guidance sets which digits of a phone number to show ("não há um padrão para o mascaramento"), and the Banco Central forbids masking a Pix key, a phone number included, when the DICT lookup returns it.
  • obfuscate keeps 2 digits, the count the gov.br account shows for a registered mobile, and keeps the prefix that names a region or a service instead of a subscriber: the DDD, the 0800-like code and the 300X/400X root.
  • The 2 digits are the last ones the mask itself has room for, so under the default "sn" a DDD-prefixed value is truncated first, exactly as it is without obfuscate, and the visible pair is the 8th and 9th digit rather than the last 2 of value.
  • Under the "service", "auto", "e164" and "international" masks a 3 digit public utility code (190) identifies no one and is returned as it is (the other masks read it as an ordinary short number); a value the "service" mask does not recognize has every digit replaced by a *, which hides the digits but not how many there were. The obfuscated patterns have a fixed number of slots, so under "e164" anything past the 11th national digit is dropped.
import { formatPhone } from '@brazilian-utils/brazilian-utils';

formatPhone('987654321'); // 98765-4321 (default "sn", no DDD)
formatPhone('11900000000', { mask: 'nanp' }); // (11) 90000-0000
formatPhone('11900000000', { mask: 'auto' }); // (11) 90000-0000
formatPhone('1130000000', { mask: 'nanp' }); // (11) 3000-0000 (10 digit landline)
formatPhone('1130000000', { mask: 'auto' }); // (11) 3000-0000 (10 digit landline)
formatPhone('11987654321', { mask: 'e164' }); // +5511987654321
formatPhone('+5511987654321', { mask: 'international' }); // +55 11 98765-4321
formatPhone('+55 11 9', { mask: 'auto' }); // +55 11 9 (typed after +55, the 55 is not read as a DDD)
formatPhone('+5511987654321', { mask: 'nanp' }); // (11) 98765-4321
formatPhone('08001234567', { mask: 'service' }); // 0800 123 4567
formatPhone('40041234', { mask: 'service' }); // 4004-1234
formatPhone('+5511987654321', { mask: 'auto' }); // +55 11 98765-4321 ("auto" detects the +55 prefix and picks "international")
formatPhone('5508001234567', { mask: 'auto' }); // 0800 123 4567 ("auto" reads the 0800 number, not a +55 08 one)
formatPhone('987654321', { obfuscate: true }); // *****-**21
formatPhone('11987654321', { mask: 'auto', obfuscate: true }); // (11) *****-**21
formatPhone('1130000000', { mask: 'auto', obfuscate: true }); // (11) ****-**00
formatPhone('+5511987654321', { mask: 'auto', obfuscate: true }); // +55 11 *****-**21
formatPhone('11987654321', { mask: 'e164', obfuscate: true }); // +5511*******21
formatPhone('08001234567', { mask: 'service', obfuscate: true }); // 0800 *** **67
formatPhone('40041234', { mask: 'service', obfuscate: true }); // 4004-**34
formatPhone('11988887766', { mask: 'service', obfuscate: true }); // *********** (not a service number)
formatPhone('11987654321', { obfuscate: true }); // *****-**43 (BEWARE: "sn" truncates first, so "43", not "21")
formatPhone('11900000000'); // 11900-0000 (BEWARE: default "sn" truncates a DDD-prefixed number)

Source: ITU-T E.164, Resolução Anatel nº 749/2022, conta gov.br for how many digits of a mobile stay visible.

Code: brazilian-utils/javascript
Try it with JavaScript formatPhone
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (169) and the result in each library phone.format

Parse

Removes phone formatting and keeps only digits, capped at 11 digits.

  • An explicit country code, written as +55 or 0055 at the start of the value, is always stripped, however many digits follow, so a number still being typed keeps its DDD: +55 11 9 gives 119. Until 2.4.0 the length rule below applied to the explicit forms too, so +55 11 9 gave 55119.
  • A bare leading 55 is stripped only when 10 or 11 digits are left (DDD plus an 8 or 9 digit subscriber number). This way area code 55 is not mistaken for a country code: 55987654321 is kept, and 55 11 9 gives 55119.
  • A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string (2.4.0 read the digits of any number).
ParameterTypeRequired
valuestring | numberyes
returnsstring

Remove phone formatting, keep only digits, and cap the result to 11 digits.

  • An explicit country code (+55 or 0055) is always stripped first, even while the number is still being typed (+55 11 9 gives 119; up to 2.4.0 it gave 55119). A bare 55 is stripped only when 10 or 11 digits are left (DDD plus subscriber number), so area code 55 is not mistaken for it.
  • Accepts a string or a non-negative safe integer; any other number (negative, fractional, not finite or unsafe) gives an empty string.
import { parsePhone } from '@brazilian-utils/brazilian-utils';

parsePhone('(11) 90000-0000'); // 11900000000
parsePhone('+55 (11) 98765-4321'); // 11987654321
parsePhone('5511987654321'); // 11987654321
parsePhone('+55 11 9'); // 119 (explicit country code, number still short)
parsePhone('55987654321'); // 55987654321 (area code 55, not mistaken for the +55 country code)
Code: brazilian-utils/javascript
Try it with JavaScript parsePhone
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (40) and the result in each library phone.parse

Generate

Generates a random Brazilian phone number, unformatted.

Use phone.format to format it.

  • type: mobile (DDD + 9 digits starting with 9, valid under both numbering versions of phone.isValidMobile), landline (DDD + 8 digits starting with 2 to 5) or service (no DDD: a Código Não Geográfico such as 0800 + 7 digits, or an abbreviated 300X/400X number). When type is omitted, the function picks a mobile or a landline at random, never a service number.
  • A landline never starts with 6 after the DDD: the 2 to 5 range stays valid after Resolução Anatel nº 777/2025 narrows it on 1 March 2027. Until 2.4.0 a 6 could be drawn.
  • phone.isValid accepts a mobile or a landline result, and phone.isValidService a service one.
  • It uses Math.random(), so the result is not cryptographically secure: do not use it for security purposes.
ParameterTypeRequired
typeGeneratePhoneTypeno
returnsstring

Generate a random Brazilian phone number. Accepts 'mobile', 'landline' or 'service' (GeneratePhoneType); when omitted, it generates a mobile or a landline at random, never a service number.

  • A mobile starts with 9 after the DDD (valid under both isValidMobilePhone versions); a landline has 8 digits after the DDD, starting with 2 to 5 (the range that stays valid after Resolução Anatel 777/2025 narrows it on 1 March 2027; up to 2.4.0 a 6 could be drawn); a service number has no DDD.
import { generatePhone } from '@brazilian-utils/brazilian-utils';

generatePhone(); // '11912345678' or '1131234567'
generatePhone('mobile'); // '11912345678'
generatePhone('landline'); // '1131234567'
generatePhone('service'); // '08001234567' or '40041234'
Code: brazilian-utils/javascript
Try it with JavaScript generatePhone
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (7) and the result in each library phone.generate

Is valid landline

Validates a landline number: DDD plus 8 digits starting with 2 to 6.

  • The function accepts a country code (+55, 0055 or a bare 55) and removes it first, as in phone.parse.
  • The DDD must be a valid Brazilian area code (00 is not).
  • Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid. Until 2.4.0 such characters were dropped, so 11 3000-0000x was valid.
  • The first digit of the number is 2 to 6, the STFC and SCM range of Resolução Anatel nº 749/2022, art. 11, I, "a".
  • Scheduled change, not applied yet: from 1 March 2027 Resolução Anatel nº 777/2025, art. 21, leaves only 2 to 5 to the STFC and moves the SCM to 9-digit numbers starting with 6. From that date a landline starting with 6 will have to be rejected.
ParameterTypeRequired
valuestringyes
returnsboolean

Check if a landline phone number is valid. A Brazilian country code (+55, 0055 or a bare 55) is accepted and removed first, as in parsePhone. Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid; up to 2.4.0 such characters were dropped.

  • The number is the DDD plus 8 digits starting with 2 to 6, the STFC and SCM range of Resolução Anatel 749/2022, art. 11, I, "a".
  • Scheduled change, not applied yet: from 1 March 2027 Resolução Anatel 777/2025, art. 21, leaves only 2 to 5 to the STFC, and the SCM moves to 9 digit numbers starting with 6. From that date a landline starting with 6 will have to be rejected.
import { isValidLandlinePhone } from '@brazilian-utils/brazilian-utils';

isValidLandlinePhone('1130000000'); // true
isValidLandlinePhone('+55 11 3000-0000'); // true (country code accepted)

Source: Resolução Anatel nº 749/2022, art. 11, and Resolução Anatel nº 777/2025, art. 21.

Code: brazilian-utils/javascript
Try it with JavaScript isValidLandlinePhone
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (19) and the result in each library phone.isValidLandline

Is valid mobile

Validates a mobile number: DDD plus 9 digits.

  • The function accepts a country code (+55, 0055 or a bare 55) and removes it first, as in phone.parse. A bare 55 is removed only when 10 or 11 digits are left.
  • The DDD must be a valid Brazilian area code (00 is not).
  • Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid. Until 2.4.0 such characters were dropped, so 11 98765-4321x was valid.
  • The first subscriber digit must be 7, 8 or 9 under both numbering rules (Resolução Anatel nº 749/2022, art. 12, I, "a": Serviço Móvel Pessoal). 2.4.0 also accepted 6 under version 1, although 6 is not SMP.
  • options.version (1 or 2, default 1) picks the numbering rule for the 700 series. Version 1 accepts it. Version 2 rejects it, because art. 12, II, "a" gives it to the satellite service.
  • Resolução Anatel nº 777/2025 rewrites art. 12 from 1 March 2027 (only 8 and 9 for SMP, plus the 700 series as satellite SMP). It is not in force yet, so the function does not apply it.
ParameterTypeRequired
valuestringyes
optionsIsValidMobilePhoneOptionsno
options.versionPhoneVersionno
returnsboolean

Check if a mobile phone number is valid. A Brazilian country code (+55, 0055 or a bare 55) is accepted and removed first, as in parsePhone. Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid; up to 2.4.0 such characters were dropped.

  • Options (IsValidMobilePhoneOptions): version (PhoneVersion, default 1) picks the numbering rule. Both follow Resolução Anatel 749/2022, art. 12, I, "a" ("7", "8" e "9": Serviço Móvel Pessoal (SMP)) and accept only a first digit of 7, 8 or 9; 1 also accepts the 700 series, 2 rejects it as satellite (art. 12, II, "a").
  • Up to 2.4.0 version 1 also accepted a first digit of 6, which is not SMP.
  • Scheduled change, not applied yet: Resolução Anatel 777/2025, art. 22, rewrites art. 12 with effect from 1 March 2027. A first digit of 6 becomes SCM (not a mobile), only 8 and 9 stay SMP, the 700 series becomes "SMGS e SMP por Satélite" and any other 7 number becomes reserva técnica. From that date a version: 2 that follows it will have to accept only 8 and 9, plus the 700 series as satellite SMP.
import { isValidMobilePhone } from '@brazilian-utils/brazilian-utils';

isValidMobilePhone('11900000000'); // true
isValidMobilePhone('11712345678', { version: 1 }); // true
isValidMobilePhone('11712345678', { version: 2 }); // true (7 is SMP as well)
isValidMobilePhone('11612345678'); // false (6 is not SMP, under either version)
isValidMobilePhone('11700123456'); // true (version 1 keeps the 700 series)
isValidMobilePhone('11700123456', { version: 2 }); // false (the 700 series is satellite)

Source: Resolução Anatel nº 749/2022 and Resolução Anatel nº 777/2025, art. 22.

Code: brazilian-utils/javascript
Try it with JavaScript isValidMobilePhone
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (30) and the result in each library phone.isValidMobile

Is valid service

Validates a Brazilian service number, dialed without a DDD. The function checks only the structure: the number does not have to be assigned to anyone.

  • A country code (+55, 0055 or a bare 55) is accepted and removed first, as in phone.isValid with accept: ["service"]: +55 0800 123 4567 is valid. Until 2.4.0 it was rejected. A bare 55 is removed only when 11 digits that form a service number are left (5508001234567 is valid; 55190 and 5540041234 are not).
  • Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid. Until 2.4.0 such characters were dropped, so abc190 was valid.
  • Códigos Não Geográficos 0300, 0303, 0500, 0800 and 0900 followed by 7 digits (11 in total; the old 6-digit form, such as 0800 123456, is rejected). The rule of 0500 that encodes a donation amount in the last two digits is not enforced.
  • The abbreviated 300X/400X numbers (8 digits). Other carrier prefixes are rejected.
  • The 3-digit public utility codes designated by Anatel (such as 190 and 192), from Anatel's current SUP list and the Anexo of Ato nº 43.151/2004. 112 is accepted: the current SUP list has it (2.4.0 rejected it).
  • 911 stays rejected. The SUP list names it next to 112, but Resolução Anatel nº 749/2022, art. 13, gives public utility services only the 1N₂N₁ range. The two official texts conflict, so the 2.4.0 answer stays.
ParameterTypeRequired
valuestringyes
returnsboolean

Check if a phone number is a valid Brazilian service number, dialed without a DDD. Only the structure is checked: the number does not have to be assigned to anyone. A Brazilian country code (+55, 0055 or a bare 55) is accepted and removed first, as in isValidPhone with accept: ['service'] (up to 2.4.0 +55 0800 123 4567 was rejected here). Any character other than digits, whitespace and ()+.-/ (a letter, for instance) makes the value invalid; up to 2.4.0 such characters were dropped.

  • The Códigos Não Geográficos 0300, 0303, 0500, 0800 and 0900 followed by 7 digits (11 in total): the 10 digit series of Resolução Anatel 749/2022, art. 18, dialed behind the 0 prefix (art. 28).
  • The abbreviated 300X/400X numbers, 8 digits. Other carrier prefixes such as 4020 and 4062 are rejected.
  • The 3 digit public utility codes Anatel has designated (e.g. 190, 192), as listed on the Anatel SUP page (modified on 22/06/2023) and in the Anexo of Ato 43.151/2004, the last consolidated act. The page lists 112/911 for the Polícia Militar on handsets: 112 is accepted; 911 is rejected, since Resolução 749/2022, art. 13, holds every series outside 1XX in reserva técnica. Up to 2.4.0 112 was rejected too.
import { isValidServicePhone } from '@brazilian-utils/brazilian-utils';

isValidServicePhone('0800 123 4567'); // true
isValidServicePhone('4004-1234'); // true
isValidServicePhone('190'); // true
isValidServicePhone('+55 0800 123 4567'); // true (country code accepted)
isValidServicePhone('11987654321'); // false (geographic number)

Source: Resolução Anatel nº 749/2022, Anatel SUP page, Ato Anatel nº 43.151/2004, Resolução nº 86/1998.

Code: brazilian-utils/javascript
Try it with JavaScript isValidServicePhone
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (63) and the result in each library phone.isValidService

Remove international dialing code

Removes a leading +55 or 55.

JavaScript does not have this function yet. Add it to the library.

Shared test cases (14) and the result in each library phone.removeInternationalDialingCode

Guides

Official sources

See also Area code (DDD)

Last updated on

On this page