Phone Number Validator - Bulk E.164, Line Type & Country avatar

Phone Number Validator - Bulk E.164, Line Type & Country

Pricing

from $1.83 / 1,000 phone number checkeds

Go to Apify Store
Phone Number Validator - Bulk E.164, Line Type & Country

Phone Number Validator - Bulk E.164, Line Type & Country

For CRM hygiene, lead qualification, SMS and voice routing and fraud checks: one row per number with valid and possible, line type (mobile, fixed, toll-free, VoIP and more), country and calling code, E.164, international, national and tel: formats, and time zones. No API key, no outside service.

Pricing

from $1.83 / 1,000 phone number checkeds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

2 days ago

Last modified

Share

For CRM and lead-list cleanup, SMS and call-centre routing, signup validation and deduplicating a customer database: check a list of phone numbers in bulk and get one row per number — whether it is valid and possible, its line type (mobile, fixed line, toll-free, premium rate, shared cost, VoIP, personal number, pager, UAN, voicemail), the country and calling code, the number in E.164, international, national and RFC 3966 (tel:) format, the region for geographic numbers, the time zones it can be in, and the carrier its range was originally assigned to.

Checked against Google's own reference set, not against a claim. Measured on 2026-09-11 with the versions pinned in this Actor: all 1,377 of Google's example numbers (245 regions) were run through this check. valid agreed on 1,377 of 1,377; E.164, calling code and national number on 1,377 of 1,377; the line type on 1,376 — the single difference being Tristan da Cunha +290 8999, where the two sources disagree about one label.

The same number written five ways is charged once. +1 201-555-0123, (201) 555-0123 (with US) and +1 (201) 555 0123 are one number: checked and charged once, with the repeats returned as uncharged duplicate-input rows naming the first input. Full-width digits, , brackets and dash characters of any kind are normalised first, so a pasted +81 90-1234-5678 is read as +81 90-1234-5678.

A number with no country code is not silently assigned one. 020 7946 0000 is a valid London number with GB and an uncharged row with US that shows the E.164 it was read as and tells you to add the country code. International dialling prefixes work too (011 44 20 7946 0000 with US, 0044 20 7946 0000 with GB).

Numbers are checked against Google's libphonenumber numbering plan data (the libphonenumber-js port with its full "max" metadata). No API key, no proxy, no outside service — nothing leaves the run. Export as JSON, CSV or Excel.

{
"phones": ["+1 201-555-0123", "(201) 555-0123", "+44 7400 123456", "+81 90-1234-5678"],
"defaultCountry": "US"
}

What this checks, and what it cannot

This Actor checks the format of a number against each country's numbering plan. It does not dial or query anything. So:

It tells youIt cannot tell you
Whether the digits fall in a number range the country has assigned (valid)Whether the number is in service or switched off today
Whether the length is plausible for the country (possible)Who uses the number
The line type the range is assigned to (mobile, fixed line, toll-free...)The carrier the number uses now - numbers that were ported keep the original carrier in originalCarrier
The region for geographic numbers, the time zones, the countryWhether it can receive SMS or has WhatsApp

valid: true means "this is a correctly formed number from an assigned range", not "this number works". If you need live reachability or the current carrier, you need a service that queries the phone network; this is not one.

What this does that a plain validator does not

Everything below was measured on 2026-09-11 with the versions pinned in this Actor. UK numbers in the examples are from the 020 7946 0xxx range Ofcom reserves for drama; the others are example numbers from Google's metadata.

1. Checked against Google's own examples

Google's libphonenumber (the Java/C++ original, via google-libphonenumber 3.2.46) publishes an example number for every country and line type. All 1,377 of them (245 regions) were run through this Actor's check: valid agreed on 1,377 of 1,377, E.164, calling code and national number on 1,377 of 1,377, and the line type on 1,376. The one difference is Tristan da Cunha +290 8999, which Google calls fixed line and this library calls fixed line or mobile. These comparisons are part of the Actor's tests.

It uses the full metadata. With the small default metadata of the same library, isValid() only checks length: +49 10123456 is "valid" there and not valid here (Google agrees it is not valid).

2. US and Canadian numbers are not called "mobile"

In the North American Numbering Plan (+1), mobile and landline numbers share the same area codes, so the number alone cannot tell them apart. Every valid US and Canadian geographic number comes back as fixed-line-or-mobile, as in Google's library. A validator that labels US numbers "mobile" or "landline" from the digits is guessing.

3. No country is guessed, and a wrong assumption is not charged

A number written without a + country code, such as 020 7946 0000, can only be read as a number of some country.

  • If you set defaultCountry, it is read as a number of that country, and the row says so in countryCodeFrom (default-country) and assumedCountry.
  • If it is not valid for that country, the row comes back with status = not-valid-in-default-country and is not charged: the country was an assumption, so an assumption that turns out wrong is not billed. The row still shows the E.164 it was read as and why it is not valid, and says to add + and the country code, or to give its country with it. 020 7946 0000 is a valid London number with GB and an uncharged row with US.
  • The international dialling prefix of the default country works: 011 44 20 7946 0000 with US, or 0044 20 7946 0000 with GB or DE, becomes +44 20 7946 0000 (countryCodeFrom: international-prefix). 0044 ... with US is not a US way of dialling and comes back as an uncharged row.
  • If defaultCountry is empty, such numbers are not read at all. They come back as uncharged bad-input rows saying the country is unknown. The Actor never picks a country for you.

4. The same number is charged once

+1 201-555-0123, (201) 555-0123 (with US) and +1 (201) 555 0123 are the same number. It is checked and charged once; the repeats come back as uncharged duplicate-input rows that name the first input and its E.164. Numbers are compared by E.164 plus extension, so +1 201-555-0123 ext. 7 is a different number.

5. Full-width characters and bracketed country codes

Numbers typed on Japanese, Chinese or Korean keyboards often use full-width characters: +81 90-1234-5678 is read as +81 90-1234-5678. Full-width digits, + and brackets, and a country code in brackets such as (+44) 20 7946 0000 or +(44) 20 7946 0000, are converted before the number is read; dash characters of any kind (, , , ) are accepted as separators. The input column keeps exactly what you sent.

6. Region, time zones and carrier follow Google's rules

  • region is filled only for number types Google treats as geographic: fixed line, fixed line or mobile, and mobile numbers in Mexico, Argentina and Brazil (for example +55 11 96123-4567 is São Paulo). A UK mobile or a toll-free number has no region, rather than a guessed one. The region comes from Google's area-code tables, in English.
  • timeZones follows Google's time zone mapper: for geographic numbers, the time zones of the number's prefix (+61 2 9123 4567 is Australia/Sydney); for mobile, toll-free and other non-geographic numbers, every time zone of the country code, because the number is not tied to a place. An Australian mobile gets 8 time zones, a UK mobile 4, a US toll-free number 42.
  • originalCarrier is filled only for mobile, fixed-line-or-mobile and pager numbers, and only where Google has a table. For +1, Google's table (696 ranges) is almost all Caribbean and US-territory numbers (for example Jamaica +1 876 and Puerto Rico); it has only 15 mainland US ranges, all in area code 659, and none in Canada, so most US numbers and all Canadian numbers have no carrier.

Charging

What you giveRowCharged
A number that can be read and is validok, valid: trueYes
A number with a + country code (or with its own country) that can be read but is not valid - wrong length, or digits outside any assigned rangeok, valid: false, with validationDetail and a note saying whyYes - it is a checked result
A number without a + country code, read with defaultCountry, that is not valid for that countrynot-valid-in-default-country, with what it was read as and whyNo
Something that is not written as a phone number (letters only, a label such as Tel: in the entry, two numbers in one entry, 1-2 digits, over 17 digits)bad-input, with the reasonNo
A number without a + country code when defaultCountry is emptybad-inputNo
A country calling code not in use (+999 ...), or an entry whose own country is not a known country codebad-inputNo
A number sent as a JSON number too large to be exact (over 2^53)bad-input, asking to send it as textNo
The same number again, written any wayduplicate-inputNo
Inputs left over when the run reached its maximum total charge, or beyond 100,000not-checked, saying how manyNo

Only rows with status = ok are charged.

Input

FieldWhat it does
phonesPhone numbers, one per line, in any common format: +1 201-555-0123, (201) 555-0123, +44 (0) 20 7946 0000, (+44) 20 7946 0000, full-width +81 90-1234-5678, with an extension such as ext. 12. Several per line are split on commas, semicolons and line breaks. A number that starts with an international dialling prefix instead of + (011 44 ..., 0044 ...) is read only when that prefix is the one used in defaultCountry. Through the API an entry can also be {"phone": "020 7946 0000", "country": "GB"} to give that number its own country. Send numbers as text: a JSON number over 2^53 has already lost digits and is not read. Up to 100,000 per run. If left empty, seven example numbers from Google's metadata are checked, and the log says so.
defaultCountryTwo-letter ISO 3166 code (US, GB, DE, JP, BR, IN...) used to read numbers written without a + country code. Numbers read this way that are not valid for that country are returned but not charged. The form pre-fills US. Through the API it has no default: if you leave it out, numbers without a country code are not read.

Neither field has a default value in the input schema, so nothing is ever added to your input that you did not send.

Entries are read strictly as phone numbers: text around the number is not searched, so an entry such as Call +44 20 7946 0000 is a bad-input row rather than a guess at which digits you meant. Vanity numbers with letters (1-800-FLOWERS) are not converted.

What you get

Verdict: valid, possible, validationDetail (valid, too-short, too-long, invalid-length, not-in-numbering-plan), type (mobile, fixed-line, fixed-line-or-mobile, toll-free, premium-rate, shared-cost, voip, personal-number, pager, uan, voicemail, or unknown when the number is not valid) and typeCode (the library's own name, such as FIXED_LINE_OR_MOBILE).

Formats: e164, international, national, rfc3966. e164 is given for every number that could be read, so you can spot repeats; for a number that is not valid it is just your digits after the calling code, not a dialable number. The other three formats are given only for valid numbers.

Country: country (ISO code), countryName, callingCode, nationalNumber, extension, isNonGeographic (for example +800 international freephone). For a number that is not valid, country is empty when the calling code is shared by several countries (+1 covers more than 20).

How it was read: input (exactly what you sent, trimmed), inputIndex (its position in your list after entries are split on commas, semicolons and line breaks, from 1; empty entries are skipped), inputCountry (a country you gave with that entry), countryCodeFrom (plus-sign, international-prefix, row-country, default-country), assumedCountry.

Location: region, timeZones, originalCarrier.

Every row also has status, note, library (the library and version the verdict comes from) and checkedAt.

Speed and limits

  • One run checks up to 100,000 numbers. On Apify, a run of 100,000 different numbers finished in 92 seconds with 512 MB of memory (peak 220 MB). Checking itself takes a few seconds; most of the run time is writing rows to the dataset. Anything beyond 100,000 is not checked and is listed in one uncharged row.
  • Rows are written in blocks of 1,000 inputs. Within a block the charged rows come first and the uncharged rows after them; sort by inputIndex to get your original order back.
  • Numbering plans change. The verdict is as current as the pinned library version shown in library (libphonenumber-js 1.13.13, published 2026-09-10). A range a country opened after that can come back as not valid.

Source and licence

  • Validation, line type and formats: libphonenumber-js (MIT), a port of Google's libphonenumber with its metadata (Apache License 2.0).
  • Region, time zones and original carrier: Google libphonenumber's geocoding, carrier and time zone tables (Apache License 2.0), in the files packaged by libphonenumber-geo-carrier (MIT).

This Actor is not affiliated with Google.

Support

Found a number that comes back wrong? Open an issue in the Issues tab with the number (or one of the same shape), the country, and what you expected.