Phone Number Validator - Bulk Format, Type & Carrier
Pricing
from $0.25 / 1,000 numbers
Phone Number Validator - Bulk Format, Type & Carrier
Validate phone numbers in bulk: valid or not and why, mobile or landline, country, and E.164, international and national forms. Valid numbers also get region, original carrier and time zones. Paste a list or check a dataset field. Nobody is called. $0.26 per 1,000 numbers.
Pricing
from $0.25 / 1,000 numbers
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 hours ago
Last modified
Categories
Share
Validate phone numbers in bulk: valid or not, line type, carrier and clean E.164 format: paste
a list of numbers, or point it at a field in one of your own Apify datasets. Every distinct number
comes back as a row: valid or not and why not, the E.164, international, national and tel: forms,
the country, the calling code, and whether it is a mobile or a landline.
Nobody is called and nothing is texted. This is a check against the world's numbering plans, so it tells you whether a number can be right at all, not whether it is switched on today.
| Input | A list of numbers, a field in one of your datasets, or both |
| Output | One row per distinct number: verdict and reason, E.164 and other formats, country, line type, region, carrier, time zones |
| Ceiling | 500,000 numbers per run |
| Speed | A few seconds for a short list; 100,000 numbers took 93 to 139 seconds on measured runs |
| Account needed | None |
| Price | $0.26 per 1,000 numbers checked, flat on every plan. The free plan's $5 a month covers about 19,000 |
🔍 What Phone Number Validator does
Write the numbers however you have them. +44 20 7946 0018, (201) 555-0123,
0033 6 12 34 56 78 and tel:+81-3-1234-5678 all parse. A leading 00 becomes +, a tel:
prefix is dropped, and spaces, brackets and dashes do not matter.
A number without + or 00 has no country in it, so the run uses your Default country to read
it. (201) 555-0123 is a valid United States number and is nonsense as a French one, which is the
whole reason that field exists.
For the numbers that pass, you also get the region the range belongs to, which for a landline is usually a town or city, the carrier the range was first handed to, and the time zones it covers. Region and carrier names come back in any of 33 languages.
The datasetId field is the part that saves real work. Point it at the output of a business-listing
scraper, name the field that holds the number, and the two run back to back without you
exporting anything.
📋 What data you get from each phone number
| What you get | Field |
|---|---|
| Whether it passes, and why not when it does not | valid, possible, reason |
The number in E.164, international, national and tel: form, plus any extension | e164, international, national, rfc3966, extension |
| The country, its code and the calling code | country, countryCode, callingCode |
| Mobile, landline and the other line types, and whether it takes texts | numberType, smsCapable |
| The place the range belongs to, its original carrier and its time zones | region, carrier, timeZones |
| What you sent, and where it came from in your list or dataset | input, source, sourceIndex |
▶️ How to validate phone numbers in bulk
- Open Phone Number Validator and click Try for free.
- Paste numbers into Phone numbers, or pick a dataset under Dataset and name the field.
- Set Default country if your list has local numbers in it.
- Add filters under Only valid numbers, Only these line types or Only these countries.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it from the Apify API.
Start it with nothing to check and you get one free sample row showing the output shape.
💰 How much does it cost to validate phone numbers?
$0.26 per 1,000 numbers checked. The same rate on every Apify plan, with no volume tiers. On the free plan, the $5 Apify gives you each month covers about 19,000 numbers.
One charge per row delivered. Blanks, repeats of a number already in the run, and anything your filters remove are not charged, and neither is the sample row. Region, carrier and time zones cost nothing extra.
📥 What you give it
{"phoneNumbers": ["+44 20 7946 0018", "(201) 555-0123", "06 12 34 56 78"],"defaultCountry": "US","onlyValid": true,"numberTypes": ["mobile"],"maxNumbers": 5000}
| Field | Default | What it is |
|---|---|---|
phoneNumbers | none | One per line, up to 500,000. Leave it empty to check a dataset instead. The form starts with four examples, which are a prefill. |
defaultCountry | none | Two-letter code, from a list of 245. Used only for numbers written without + or 00. The form starts on US, which is a prefill, not a default. |
datasetId | none | One of your own datasets, picked from a list in the form or passed as an ID through the API. Works alongside the list. |
datasetField | phone | Which field holds the number. Dots reach a nested one, like contact.phone. A field holding a list checks every number in it. |
addRegionAndCarrier | true | Adds region, carrier and time zones to valid numbers. Off leaves those three empty. |
language | en | For region and carrier names, from 33 languages. Names missing in your language come back in English. |
onlyValid | false | Leave out numbers that fail the check. |
numberTypes | none | Keep only these line types: mobile, landline, landline or mobile, toll-free, VoIP and six more. |
countries | none | Keep only numbers belonging to these countries. |
maxNumbers | 10000 | 1 to 500,000. Only distinct numbers that get past your filters count towards it. |
Anything a filter leaves out is not charged, and neither are blanks or repeats. So
onlyValid: true on a list that is half rubbish costs you roughly half.
In the United States and Canada, pick landline or mobile too if you are filtering by line
type. Those two countries share number ranges between mobiles and landlines, so most numbers there
honestly cannot be told apart and come back under that label.
📤 What you get back
Two real rows from a run on 3 October 2026 with the form's own example numbers: a London landline, which gets a region, and a French mobile, which gets a carrier.
[{"input": "+44 20 7946 0018","valid": true,"possible": true,"reason": null,"e164": "+442079460018","international": "+44 20 7946 0018","national": "020 7946 0018","rfc3966": "tel:+442079460018","extension": null,"countryCode": "GB","country": "United Kingdom","callingCode": "+44","numberType": "landline","smsCapable": false,"region": "London","carrier": null,"timeZones": ["Europe/London"],"source": "list","sourceIndex": 1},{"input": "+33 6 12 34 56 78","valid": true,"possible": true,"reason": null,"e164": "+33612345678","international": "+33 6 12 34 56 78","national": "06 12 34 56 78","rfc3966": "tel:+33612345678","extension": null,"countryCode": "FR","country": "France","callingCode": "+33","numberType": "mobile","smsCapable": true,"region": null,"carrier": "SFR","timeZones": ["Europe/Paris"],"source": "list","sourceIndex": 3}]
| Field | How to read it |
|---|---|
valid | The number fits its country's numbering plan. This is the one to filter on. |
possible | A length check only, set for anything that parses at all. A number can be possible and not valid. |
reason | Why a number failed, in plain words: "too short", "wrong length for France", "not a number in use in Germany", "unknown country code", "no country code: start it with + or set a default country". null when it passed. |
carrier | Filled for mobile ranges. A landline has a region instead. |
smsCapable | true for mobiles, false for landlines and other fixed types, null where the plan cannot say, which includes "landline or mobile" and VoIP. |
sourceIndex | The line number in your list, or the item's offset in your dataset, so you can join the row back. |
Formats, region, carrier and time zones are filled in only for numbers that pass. In the same
run, 06 12 34 56 78 read with the US default came back valid: false with "not a number in use in
United States", and nothing invented around it.
🧾 Reading the output
One row per distinct number, and that is the whole dataset. No refusal rows and no blank lines. A
sample row carries _sample: true and turns up only when you run with nothing to check.
Everything else about the run is in a key-value record called RUN_REPORT:
| In the report | What it tells you |
|---|---|
| Counts by verdict, reason, type and country | The shape of your list in one place. |
| Entries skipped | How many were blank, how many were repeats, how many your filters removed. |
| The filters used | Written out, including any value that was not recognised and dropped. |
| The dataset read | Items seen, items with no number in the named field, and any error reading it. |
| Stop reason and seconds taken | Whether it finished the list or hit maxNumbers, the deadline or your budget. |
A run whose filters match nothing finishes normally and says so in the status message. A run with nothing to check at all fails.
💡 What people use it for
- Cleaning a list of numbers down to the ones that can actually be dialled.
- Splitting a list into mobiles and landlines.
- Normalising a CRM export to E.164 so two systems finally agree on a format.
- Working out which countries a list is really from, by counting
countryCode.
From business listings to a checked list of numbers, in three runs:
- Run Yellow Pages US Scraper for the businesses you want.
- Here, pick that run's dataset under Dataset, leave the field as
phone, set Default country to United States and tick Only valid numbers. - Join the rows back to the listings on
sourceIndex, which is each listing's position in that dataset.
🚧 What it does not do
- It does not call or text anything. No answer test, no ring test, no HLR lookup. Nothing tells you whether a number is live, disconnected or answered today.
- No names, no owners, no WhatsApp check.
carrieris the carrier the range was first given to. A ported number shows the old one. Take it as a hint about the range, not as fact about the handset.- United States and Canada numbers come back as "landline or mobile" most of the time, because
the ranges are genuinely shared.
smsCapableisnullfor those. - The numbering data has a date. A range that opened after the last update reads as not in use.
- A number not tied to one place lists every time zone of its country. A US toll-free number names 42 of them.
- 500,000 numbers in a run, and a large run wants the memory to match.
- It is not an official tool of any platform or company named on this page. Dami's Studio is independent and is not affiliated with or endorsed by any of them.
🧭 Which list-cleaning tool do you need?
| If you want | Use |
|---|---|
| Phone numbers checked and formatted | This one |
| Email addresses checked | Email Verifier |
| Business listings with phone numbers to clean | Google Maps Scraper |
| US business listings with phone numbers | Yellow Pages US Scraper |
| Social profiles from a name or domain | Social Profile Finder |
❓ Questions people ask
Does it ring the phone number?
No. Everything is worked out from the numbering plans, so nobody's phone lights up and nothing leaves the run.
Why did a number I know is fine come back invalid?
Nearly always a missing country. Set Default country to match where the local numbers were
written, or put them in + form.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has ready-made
code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/phone-number-validator. Either way the
run happens on your Apify account at the same price.
Is checking phone numbers legal?
Nothing is called or texted. A phone number is still personal data under GDPR and similar laws, so have a reason for holding the list. Apify's write-up on scraping and the law is a good start, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and a number that came back wrong. The
RUN_REPORT record in the run's key-value store carries the counts, the filters and the stop reason,
which usually explains a short result on its own.