Bulk Phone Number Validator - Format, Type & Country
Pricing
from $0.64 / 1,000 phone number validateds
Bulk Phone Number Validator - Format, Type & Country
Validate and format phone numbers in bulk, offline: valid or not, E.164 / international / national format, country, line type (mobile, fixed line, toll free, VoIP) and time zones. CSV upload or another Actor's dataset. Invalid numbers are free. $0.80 per 1,000.
Pricing
from $0.64 / 1,000 phone number validateds
Rating
0.0
(0)
Developer
Yukai Lin
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
What does Bulk Phone Number Validator do?
Phone number validator and formatter for lists you are about to import into a CRM, a dialer or an SMS tool: give it a list, a CSV or the dataset of a lead scraper and get, for every number, valid or not, the E.164, international, national and RFC 3966 formats, the country, the line type (mobile, fixed line, toll free, VoIP…) and the reason when it is invalid. $0.80 per 1,000 valid numbers, no start fee, invalid numbers free.
It is an offline check against the official numbering plans (the metadata of Google's libphonenumber, through the MIT-licensed libphonenumber-js). Nothing is dialled, texted or looked up at a carrier, so it is fast (10,000 numbers in seconds), private and cheap. The trade-off, stated honestly: valid means the number belongs to an assigned number range of its country, not that the line is currently active or who the carrier is (liveCheck is always false).
- ✅ Valid / possible per country: length and number-range rules for 240+ countries and territories
- 🔢 Four formats: E.164 (
+886912345678), international (+886 912 345 678), national (0912 345 678), RFC 3966 (tel:+886912345678); pick the one that goes into thephonecolumn - 🌍 Country, ISO code and calling code, also for shared codes such as +1 (US, Canada, Caribbean) and +44 (UK, Jersey, Guernsey, Isle of Man)
- 📱 Line type:
MOBILE,FIXED_LINE,FIXED_LINE_OR_MOBILE(US/Canada cannot tell them apart),TOLL_FREE,PREMIUM_RATE,VOIP,PERSONAL_NUMBER,PAGER,SHARED_COST,UAN,VOICEMAIL - ☎️ Extensions (
ext. 12,x12,#12,;ext=12),tel:links,00/ full-width digits, labels such asPhone:and vanity letters (1-800-FLOWERS) are understood - 🕒 Time zones of the country (country level, e.g. all 29 US zones; not per area code)
- 📥 Any list shape: a list field, pasted text, a CSV upload (the phone column is found automatically; other columns can be copied to the output) or the dataset of another Actor (e.g. Contact Details Extractor's
phones) - 🔁 Duplicates merged on the E.164 form:
0912 345 678(default country TW) and+886 912 345 678count once - 📤 Clean list: the run also saves
VALID_NUMBERSas plain text, one valid number per line in your chosen format
Why a number is invalid
reasonCode | Meaning |
|---|---|
INVALID_COUNTRY | No +country code and no "Default country" set, or the country code does not exist |
TOO_SHORT / TOO_LONG / INVALID_LENGTH | The length does not fit any number of that country |
NOT_VALID_FOR_REGION | Right length, but no assigned number range starts like this (e.g. US area code 123) |
NOT_A_NUMBER | Not readable as a phone number |
MULTIPLE_NUMBERS | Several + numbers in one entry that could not be split; put each on its own line |
An invalid number has no e164, type or countryCode (the country is not guessed; with a "Default country" and no +, that country is kept). Short codes such as 911 or 112 are reported as too short: this is a check of full phone numbers.
Entries with fewer than 3 digits, e-mail addresses and links get a row with errorType: "invalid_input" and are not charged.
How much does it cost?
| Event | Free / Bronze | Silver | Gold and above |
|---|---|---|---|
| Phone number validated | $0.0008 ($0.80 per 1,000) | $0.00072 | $0.00064 |
No start fee. Charged: each unique number that is valid for its country (valid: true). Not charged: invalid numbers, entries that are not phone numbers (fewer than 3 digits, e-mail addresses, links), and duplicates merged on the E.164 form. Every row says charged: true/false.
How it compares
Checked October 2026 on the Apify Store (search "phone number validator", "phone validator", "validate phone numbers"), prices on the Free plan from the Store API. Users are the Store's 30-day counts.
| Actor | Does | Price on the Free plan | 30-day users |
|---|---|---|---|
| This Actor | Offline format, country, line type, time zone; CSV and dataset input | $0.0008 per valid number; no start fee; invalid free | new |
| memo23/phone-enrichment | Offline validation plus US reverse lookup | $0.001 per number + $0.005 start | 31 |
| pink_comic/phone-number-validation | Validation with carrier lookup | $0.001 per result | 19 |
| scrapersdelight/phone-number-validator-scraper | Validation, carrier and line type | $0.001 per number | 10 |
| automation-lab/phone-number-validator | Validation | $0.00115 per number + $0.0115 start | 9 |
| santamaria-automations/phone-validator | International validation | $0.001 per result + $0.001 start | 4 |
| khadinakbar/phone-number-lookup-api | Carrier and line-type lookup | $0.025 per number | 48 |
| checkthatphone/phone-validator | US/Canada carrier lookup and TCPA litigator scrub | $0.015 per credit | 70 |
What this one is: a fast offline format check, priced below the other offline validators (and with no start fee), with invalid numbers and duplicates free, CSV and dataset input and a stop at your maximum charge per run. What it is not: a carrier or live-line check. If you need the carrier name, ported-number status, a reverse lookup or TCPA screening, the tools above that do lookups do something this one deliberately does not.
Control your cost
At the start the run logs its plan, e.g. Plan: 10 valid numbers × $0.0008 = at most $0.008. It never charges more than your maximum charge per run: when the limit is reached, the remaining valid numbers are not processed and are listed in SUMMARY.notProcessed (invalid numbers are still reported, free). "Max numbers" caps how many unique numbers one run processes. A run restarted by Apify skips numbers it already charged.
How to use it
- Paste numbers into Phone numbers (or paste a list, upload a CSV, or give a dataset ID).
- Set Default country for numbers written without
+country code(e.g.USfor(650) 253-0000,TWfor0912 345 678). - Choose the format of the
phonecolumn (E.164 is best for CRMs and SMS tools) and run.
Input example
{"phones": ["+1 650-253-0000", "+44 20 7946 0958 ext. 12", "0912 345 678", "(02) 2345-6789", "+1 123 456 7890"],"defaultCountry": "TW","outputFormat": "E164"}
Output example (local test run, 2 October 2026)
{"input": "0912 345 678","valid": true,"possible": true,"phone": "+886912345678","e164": "+886912345678","international": "+886 912 345 678","national": "0912 345 678","rfc3966": "tel:+886912345678","countryCode": "TW","country": "Taiwan","callingCode": "+886","nationalNumber": "912345678","type": "MOBILE","extension": null,"timezones": ["Asia/Taipei"],"defaultCountryUsed": "TW","reasonCode": null,"liveCheck": false,"charged": true,"source": "list","duplicates": 2}
An invalid number from the same run (not charged):
{ "input": "+1 123 456 7890", "valid": false, "possible": true, "phone": null, "callingCode": "+1", "reasonCode": "NOT_VALID_FOR_REGION", "reason": "right length, but no assigned number range of this country code starts like this", "charged": false }
The key-value store holds SUMMARY (counts by line type, country and invalid reason; notProcessed when the run stopped at your limit) and VALID_NUMBERS.
Integrations
Run it after a lead or contact scraper: set Or read from a dataset to that run's dataset ID (the phones field is found automatically) and copy fields such as url or name with Copy these source columns. Pairs with Email List Cleaner to clean both columns of a lead list.
Use with AI agents (MCP)
Connect Apify's MCP server (https://mcp.apify.com?tools=tidytools/phone-validator) to Claude, Cursor or any MCP client, then ask e.g. "Validate these phone numbers and give me the mobile ones in E.164: …".
{ "phones": ["+1 650-253-0000", "0912 345 678"], "defaultCountry": "TW" }
Invalid numbers are not charged and carry a reasonCode; entries that are not phone numbers carry errorType: "invalid_input".
Tips and limitations
- Not a live check. No HLR, carrier or "line in use" lookup. Ported numbers keep their original range, so the line type is the type of the range.
- US and Canada numbers are
FIXED_LINE_OR_MOBILE: the numbering plan does not separate them. - Time zones are per country, not per area code.
- The numbering metadata is updated with each libphonenumber-js release; this Actor pins the version in its build.
Responsible use
This Actor works offline: numbers are checked inside the run against numbering-plan rules, nothing is dialled, texted or sent to a carrier or to any outside service, and the results stay in your own Apify run storage. Use the results to clean and format contact data you are allowed to process. Validating a number does not give consent to call or text it: telemarketing and SMS rules (e.g. TCPA in the US, GDPR/ePrivacy in the EU, do-not-call registers) still apply.
FAQ
Does the Actor collect usage data? The Actor sends one anonymous usage counter per run (input type, item count range, outcome) to improve the tool; no URLs, content or account data.
Does "valid" mean the number is in use? No. It means the number belongs to an assigned number range of its country. The Actor does not call, text or query carriers, so it cannot tell whether a line is active or who the carrier is today.
What happens to numbers without a country code? They are read with your Default country. Without one, they are invalid with reasonCode: "INVALID_COUNTRY" (and free).
How are lists split, and what about numbers inside text? New lines, semicolons, tabs, pipes, / and and / or / & between numbers separate entries; a comma separates only when every part has 6+ digits. A number inside a sentence ("call +1 650 253 0000 today") is found and validated; a sentence with no number is NOT_A_NUMBER. Vanity letters are converted only in entries that start with a digit, + or ( and have at most 8 digits ("1-800-FLOWERS").
Is the same number with a different extension a duplicate? No: +1 650 253 0000 x12 and +1 650 253 0000 x13 are two entries (each charged if valid); the same number and extension written two ways is one.
Can I keep the other columns of my CSV or dataset? Yes: list them in Copy these source columns to the output (for example name, url), and each result row carries them next to the phone fields.
I only want the clean list. Turn on Leave invalid numbers out of the results, or download VALID_NUMBERS from the key-value store: one valid number per line in your chosen format.
What if my input is empty or has no phone numbers? The run still ends normally (it does not fail): you get one row with errorType: "invalid_input", charged: false and a message saying what to add, and SUMMARY.status is NO_RESULTS. Nothing is charged.