Phone Number Validator - Bulk E.164, Line Type & Country
Pricing
from $1.83 / 1,000 phone number checkeds
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
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
2 days ago
Last modified
Categories
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 you | It 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 country | Whether 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 incountryCodeFrom(default-country) andassumedCountry. - If it is not valid for that country, the row comes back with
status=not-valid-in-default-countryand 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 0000is a valid London number withGBand an uncharged row withUS. - The international dialling prefix of the default country works:
011 44 20 7946 0000withUS, or0044 20 7946 0000withGBorDE, becomes+44 20 7946 0000(countryCodeFrom:international-prefix).0044 ...withUSis not a US way of dialling and comes back as an uncharged row. - If
defaultCountryis empty, such numbers are not read at all. They come back as unchargedbad-inputrows 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
regionis 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-4567is 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.timeZonesfollows Google's time zone mapper: for geographic numbers, the time zones of the number's prefix (+61 2 9123 4567isAustralia/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.originalCarrieris 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 876and 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 give | Row | Charged |
|---|---|---|
| A number that can be read and is valid | ok, valid: true | Yes |
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 range | ok, valid: false, with validationDetail and a note saying why | Yes - it is a checked result |
A number without a + country code, read with defaultCountry, that is not valid for that country | not-valid-in-default-country, with what it was read as and why | No |
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 reason | No |
A number without a + country code when defaultCountry is empty | bad-input | No |
A country calling code not in use (+999 ...), or an entry whose own country is not a known country code | bad-input | No |
| A number sent as a JSON number too large to be exact (over 2^53) | bad-input, asking to send it as text | No |
| The same number again, written any way | duplicate-input | No |
| Inputs left over when the run reached its maximum total charge, or beyond 100,000 | not-checked, saying how many | No |
Only rows with status = ok are charged.
Input
| Field | What it does |
|---|---|
phones | Phone 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. |
defaultCountry | Two-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
inputIndexto 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.