Bulk Phone Number Validator — E.164, Carrier & Line Type
Pricing
from $0.60 / 1,000 results
Bulk Phone Number Validator — E.164, Carrier & Line Type
Validate and format thousands of phone numbers at once: validity, E.164 / international / national format, line type (mobile, landline, VoIP, toll-free), country, carrier, timezone and area. Fast, offline, keyless phone-list cleaning for CRM, SMS and leads.
Pricing
from $0.60 / 1,000 results
Rating
0.0
(0)
Developer
Haketa
Maintained by CommunityActor stats
0
Bookmarked
13
Total users
1
Monthly active users
a day ago
Last modified
Categories
Features
Share
Bulk Phone Number Validator — E.164 Formatter, Line Type, Carrier, Country & Timezone Lookup
Validate, clean, format, and enrich thousands of phone numbers in seconds. This bulk phone number validator takes any raw phone list—in E.164, international, or local national format—and returns a structured record for every number: validity (isValid), possibility (isPossible), canonical E.164 format (e164), international and national formatting, tel: URI, extension, line type (MOBILE, FIXED_LINE, VOIP, TOLL_FREE, etc.), SMS-readiness (isMobile), ISO country & calling code, original network carrier, geographic area, and IANA timezone.
Fast, keyless, and rate-limit-free — no third-party per-lookup validation API fees, no external API keys, and no throttling. Bulk export your cleaned phone list to JSON, CSV, Excel (XLSX), HTML, or via the Apify API.
🎯 Built for B2B sales, growth, and RevOps teams doing CRM phone hygiene, SMS & WhatsApp marketers protecting campaign deliverability, lead-generation agencies filtering scraped leads, call centers scheduling timezone-aware dialing, and developers who need a high-throughput phone number validation API.
⚡ At a glance
| Feature | Details |
|---|---|
| 🎯 Core capability | Bulk phone validation, E.164 normalization, line-type classification, and carrier/timezone/location enrichment |
| 🌍 Global coverage | 240+ countries and territories (US, UK, DE, FR, ES, IT, NL, SE, PL, TR, AE, SA, IN, CN, JP, BR, MX, AU, CA & more) |
| 📱 Line-type detection | Distinguishes MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, VOIP, TOLL_FREE, PREMIUM_RATE, SHARED_COST, PERSONAL_NUMBER, PAGER, UAN, VOICEMAIL |
| 💬 SMS & WhatsApp flag | Derived isMobile flag ("true" / "false") so you never waste SMS budget texting landlines |
| 🔁 Scale & throughput | Processes 100 to 1,000,000+ phone numbers per run (maxItems: 0 = unlimited) in parallel (maxConcurrency: 50) |
| 🔓 Keyless & zero network lag | Powered by embedded international numbering plan metadata — 0 external API calls, 0 rate limits, 100% deterministic |
| ⬇️ Export & API | JSON, CSV, Excel, HTML, plus Key-Value Store OUTPUT summary for synchronous API / webhook pipelines |
🔎 Why validate and normalize phone numbers in bulk?
Raw phone lists from web scrapers, lead forms, CRM exports, and event signups are notoriously messy: numbers arrive with spaces, dashes, parentheses, extensions, missing + signs, local trunk prefixes (0), typos, and fake digits—with landlines and VoIP numbers mixed right alongside mobile numbers.
Dialing or texting an uncleaned list costs money and damages sender reputation:
- 💬 Stop wasting SMS & WhatsApp spend on landlines — filter to
isValid = "true"andisMobile = "true"before launching any Twilio, WhatsApp Business, or SMS broadcast. - 🧹 Eliminate CRM duplicates with canonical E.164 keys —
+1 (415) 555-2671,415.555.2671, and0014155552671all normalize to+14155552671(e164), letting you deduplicate HubSpot, Salesforce, or Pipedrive contacts instantly. - ⏰ Call prospects during local business hours — use the enriched
timezone(America/New_York,Europe/Berlin,Asia/Dubai) andcountryNamefields to route outbound calls to the right regional sales pod at the right hour. - 🛡️ Catch bad leads at capture — flag impossible or invalid numbers (
isValid = "false", with a clearerrorreason) from ad forms and B2B lead lists before they pollute your database. - 💰 Replace expensive per-lookup APIs — commercial lookup APIs charge $0.005–$0.01 per number ($5–$10 per 1,000 numbers). This Actor validates thousands of numbers in a single run for fractions of a cent in compute.
✨ What this bulk phone validator does
- ✅ Unlimited 1,000+ bulk processing (
maxItems: 0) — paste 100, 1,000, 50,000, or 500,000+ phone numbers; by default (maxItems: 0), the Actor processes your entire list without truncating. - ✅ 100-record instant demo on empty runs — leave
phoneNumbersempty and click Start to immediately validate a built-in sample of 100 diverse international phone numbers across 25+ countries in ~2 seconds. - ✅ Accepts any input format — parses E.164 (
+442079460100), international (+44 20 7946 0100), national (01512 3456789withdefaultCountry: "DE"), and numbers with extensions (+1 415 555 2671 ext. 42). - ✅ 4 ready-to-use output formats per number —
e164(+4915123456700),international(+49 1512 3456700),national(01512 3456700), and clickableuri(tel:+4915123456700). - ✅ Carrier, geographic area & timezone enrichment — enriches valid numbers with original mobile
carrier(e.g.,T-Mobile,Vodafone,Orange,China Mobile), landlinelocation(state/city), and IANAtimezone. - ✅ 1-to-1 row preservation — invalid or unparseable inputs are never silently dropped; they are returned in order with
isValid: "false"and a clear explanation inerrorso your spreadsheet row alignment stays intact. - ✅ Key-Value Store
OUTPUTsummary — writes run totals (totalValidated,validCount,invalidCount,mobileCount) toOUTPUTfor instant inspection by automated pipelines.
🎯 Use cases & B2B data hygiene workflows
| Team / Role | Workflow & Value Delivered |
|---|---|
| 📈 B2B Lead Generation & Scraping Teams | Pipe phone numbers extracted from Google Maps, Justdial, Yellow Pages, or company websites directly into this Actor. Standardize every lead to e164 and tag mobile vs. fixed-line numbers before delivering the dataset to clients. |
| 💬 SMS, WhatsApp & Mobile Marketing | Upload campaign contact lists, filter for isValid == "true" and isMobile == "true", and segment by country and carrier to maximize delivery rates and avoid carrier filtering. |
| 🏢 RevOps & CRM Administrators | Run quarterly hygiene sweeps across Salesforce, HubSpot, or Zoho exports. Use e164 as the unique merge key to collapse duplicate contact records written in different punctuation styles. |
| 📞 Outbound Call Centers & SDR Teams | Enrich raw prospect lists with timezone, countryName, location, and national format so dialers automatically schedule calls within legal local calling windows. |
| ⚙️ Backend & Automation Engineers | Trigger the Actor via Apify API or Make/Zapier/n8n webhooks whenever a new batch of leads lands in Google Sheets, Airtable, or Postgres. |
📥 Input configuration
All fields are optional ("required": []). Paste your phone numbers one per line, or leave phoneNumbers empty to run the 100-number international sample.
| Field | Type | Default / Prefill | Description |
|---|---|---|---|
phoneNumbers | array<string> | [] (runs 100-item sample) | Phone numbers to validate, one per line. Accepts E.164, international, or national formats. |
defaultCountry | string | "" (Auto-detect) | Two-letter ISO country code (US, GB, DE, FR, TR, IN, AE, BR, etc.) used to interpret numbers written in national format without a leading +. |
includeCarrierData | boolean | true | Enriches valid numbers with carrier, location, and timezone. Disable only if you want raw validation speed on multi-million-row lists. |
maxItems | integer | 0 (Unlimited) | Maximum number of records to output (0 = process the entire list without limits). Also supports maxResults / maxRecords. |
maxConcurrency | integer | 50 | Number of phone numbers enriched concurrently (1–200). |
Example input — validate an international phone list (1,000+ ready)
{"phoneNumbers": ["+14155552671","+447700900200","+4915123456700","+33612345678","+971501234567","+919820112300"],"defaultCountry": "","includeCarrierData": true,"maxItems": 0,"maxConcurrency": 50}
Example input — validate national-format numbers with a default country
{"phoneNumbers": ["0170 1234567","030 12345678","0151 22334455 ext. 19"],"defaultCountry": "DE","includeCarrierData": true}
📤 Output schema & field reference
The Actor writes one structured record per phone number. Boolean flags (isValid, isPossible, isMobile) are emitted as "true" / "false" strings so they export cleanly across CSV, Excel, and schema-strict pipelines.
Example output — valid US number with geographic area & timezone
{"input": "+14155552600","isValid": "true","isPossible": "true","e164": "+14155552600","international": "+1 415 555 2600","national": "(415) 555-2600","uri": "tel:+14155552600","extension": "","countryCode": "1","country": "US","countryName": "United States","numberType": "FIXED_LINE_OR_MOBILE","isMobile": "true","location": "San Francisco, CA","carrier": "","timezone": "America/Los_Angeles","error": "","scrapedAt": "2026-11-09T15:10:00.000Z"}
Example output — valid German mobile number with carrier & timezone
{"input": "+4915123456700","isValid": "true","isPossible": "true","e164": "+4915123456700","international": "+49 1512 3456700","national": "01512 3456700","uri": "tel:+4915123456700","extension": "","countryCode": "49","country": "DE","countryName": "Germany","numberType": "MOBILE","isMobile": "true","location": "","carrier": "T-Mobile","timezone": "Europe/Berlin","error": "","scrapedAt": "2026-11-09T15:10:00.000Z"}
✅ Validation & Formatting Fields
| Field | Type | Coverage | Description |
|---|---|---|---|
input | string | 🟢 High (100%) | Exact raw phone number string as supplied in the input. |
isValid | string | 🟢 High (100%) | "true" if the number passes full length, prefix, and country numbering plan rules; "false" otherwise. |
isPossible | string | 🟢 High (100%) | "true" if the digit length is possible for the detected country. |
e164 | string | 🟢 High (100% of valid) | Canonical E.164 format (e.g., +4915123456700) — ideal primary key for CRM deduplication. |
international | string | 🟢 High (100% of valid) | Human-readable international format (e.g., +49 1512 3456700). |
national | string | 🟢 High (100% of valid) | Local dialing format within the country (e.g., 01512 3456700). |
uri | string | 🟢 High (100% of valid) | RFC 3966 clickable dialer URI (tel:+4915123456700). |
extension | string | 🟡 Conditional | Extension digits parsed from inputs like ext. 123 or #123 (empty string when none). |
error | string | 🟡 Conditional | Diagnostic message when isValid is "false" (e.g., "number is not valid for its country"). |
📱 Line Type, Country & Enrichment Fields
| Field | Type | Coverage | Description |
|---|---|---|---|
numberType | string | 🟢 High (~99% of valid) | Line classification: MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, VOIP, TOLL_FREE, PREMIUM_RATE, SHARED_COST, PERSONAL_NUMBER, PAGER, UAN, VOICEMAIL. |
isMobile | string | 🟢 High (100%) | "true" when numberType is MOBILE or FIXED_LINE_OR_MOBILE (capable of receiving SMS). |
countryCode | string | 🟢 High (100% of valid) | International country calling prefix without + (e.g., 1, 44, 49, 90, 91). |
country | string | 🟢 High (100% of valid) | Two-letter ISO 3166-1 alpha-2 country code (e.g., US, GB, DE, FR, IN). |
countryName | string | 🟢 High (100% of valid) | Full English country name (e.g., United States, United Kingdom, Germany). |
carrier | string | 🟡 Conditional (~80% mobile) | Original mobile network operator assigned to the prefix (e.g., T-Mobile, Vodafone, Orange). Empty on landlines. |
location | string | 🟡 Conditional (Geographic) | City, state, or region for geographic/fixed-line numbers (e.g., San Francisco, CA, London). |
timezone | string | 🟢 High (~98% of valid) | Comma-separated IANA timezone IDs for the number's region (e.g., Europe/Berlin, America/New_York). |
scrapedAt | string | 🟢 High (100%) | ISO 8601 UTC timestamp of when the validation run executed. |
🔁 Scaling to 1,000+ and 100,000+ phone numbers
Unlike web scrapers that paginate across external web pages, this Actor processes your entire input array locally in memory using an asynchronous worker pool (maxConcurrency: 50) and flushes validated records to the Apify Dataset in 500-item batches:
- 100 numbers (default sample run): finishes in ~2–4 seconds.
- 1,000+ numbers: finishes in ~5–10 seconds with zero external network bottlenecks.
- 10,000–100,000+ numbers: streams smoothly in batches of 500 records without hitting rate limits or proxy costs.
- Want to test 1,000+ scale without uploading a file? Leave
phoneNumbersempty and setmaxItems: 1000—the Actor's built-in international sample generator will automatically synthesize and validate 1,000 unique international phone numbers across 25 countries!
⚙️ How to use & integrate via API
- Open the Bulk Phone Number Validator in Apify Console.
- Paste your phone numbers into
phoneNumbers(or leave it empty to test with the 100-number sample). - Select
defaultCountryif your list contains local national numbers without a+prefix. - Click Start and download your validated table as CSV, Excel, or JSON.
API example (cURL)
curl -X POST "https://api.apify.com/v2/acts/haketa~bulk-phone-validator/runs?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"phoneNumbers": ["+14155552671", "+447700900200", "+4915123456700"],"includeCarrierData": true}'
API example (Python)
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("haketa/bulk-phone-validator").call(run_input={"phoneNumbers": ["+14155552671", "01512 3456700", "+971501234567"],"defaultCountry": "DE","includeCarrierData": True,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(f"{row['input']} -> valid={row['isValid']} e164={row['e164']} type={row['numberType']} carrier={row['carrier']}")
API example (Node.js)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('haketa/bulk-phone-validator').call({phoneNumbers: ['+14155552671', '+447700900200', '+33612345678'],includeCarrierData: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Validated ${items.length} phone numbers.`);
💡 Pro tips for phone list cleaning
- 🌍 Always keep
+country codes when scraping: If your numbers already start with+, leavedefaultCountryon Auto-detect ("")—the validator will automatically detect all 240+ countries in the same mixed list. - 📱 Why US & Canadian numbers show
FIXED_LINE_OR_MOBILE: In the North American Numbering Plan (+1), mobile and landline numbers share the same area-code prefixes. The validator accurately reportsFIXED_LINE_OR_MOBILEand setsisMobile: "true"so North American numbers are included in SMS-eligible segments. - 🔄 Original carrier vs. ported numbers: Prefix-based carrier resolution identifies the original network operator assigned to a number block. Because of mobile number portability (MNP), treat
carrieras an initial network signal rather than a live HLR dip.
⚠️ Honest limitations
- Offline numbering plan validation (not a live HLR/ping check): This Actor validates syntax, country prefix, digit length, and numbering-plan assignment offline. It does not place a live call or HLR network ping to check whether a handset is currently powered on.
- Carrier vs. Location mutual exclusivity: In most countries, mobile prefixes map to a
carrier(e.g.,Vodafone) without a fixed city, whereas landline prefixes map to a geographiclocation(e.g.,London,New Jersey) without a single carrier.
❓ Frequently asked questions (FAQ)
How many phone numbers can I validate in a single run?
There is no hard limit (maxItems: 0 by default). You can validate 100, 1,000, 50,000, or 1,000,000+ phone numbers in a single job.
Does it require any external API key or Twilio/Numverify subscription? No. Everything runs self-contained inside the Actor with zero external API keys, zero per-number lookup fees, and zero rate limits.
Does it dial or send an SMS to the phone numbers? No. Validation is 100% passive and offline—the phone owner is never contacted or alerted.
What happens if I run the Actor with empty input?
It automatically generates and validates a diverse sample of 100 international phone numbers across 25 countries (or N numbers if you set maxItems: N) so you can test downstream integrations immediately.
Do I need proxies for this Actor? No proxies are needed because no external websites or third-party APIs are queried.
🔌 CRM & marketing automation integrations
Drop this Bulk Phone Number Validator directly into your data-ingestion and outbound workflows:
- 🏢 HubSpot, Salesforce & Pipedrive: Trigger via Make, Zapier, or n8n whenever new leads arrive. Write back the normalized
e164number,isMobilestatus,countryName, andtimezoneso SDRs always dial clean numbers during local business hours. - 💬 Twilio, WhatsApp Business, Klaviyo & Braze: Pre-filter every contact list to
isValid == "true"andisMobile == "true"before importing into SMS/WhatsApp platforms—eliminating landline bounce fees and protecting sender reputation. - 📊 Google Sheets, Airtable & Supabase: Clean entire spreadsheet columns in bulk on a schedule or via webhook and export ready-to-join tables keyed on
inputore164. - 🔗 Chained Apify Lead Pipelines: Pair this Actor directly after Google Maps Scraper, Justdial Scraper, or Email & Contact Extractor via an Actor-to-Actor webhook to automatically validate every scraped business phone number.
📊 Downstream deduplication & SMS segmentation recipe (Python / Pandas)
Once your validation run completes, you can split your list into SMS-ready mobiles, callable landlines, and invalid leads in just a few lines of Python:
import pandas as pd# Load validated phone dataset from Apifydf = pd.read_json("validated_phones.json")# 1. Keep only valid numbers and deduplicate on canonical E.164valid_df = df[df["isValid"] == "true"].drop_duplicates(subset=["e164"])# 2. Segment into SMS-capable mobile numbers vs. fixed-line / landline numberssms_ready = valid_df[valid_df["isMobile"] == "true"]landlines = valid_df[valid_df["numberType"] == "FIXED_LINE"]invalid_rows = df[df["isValid"] == "false"]print(f"Unique valid numbers: {len(valid_df)}")print(f"SMS/WhatsApp mobile numbers: {len(sms_ready)}")print(f"Fixed-line landlines: {len(landlines)}")print(f"Invalid / rejected inputs: {len(invalid_rows)}")# 3. Group valid mobile leads by country and timezone for campaign schedulingby_tz = (sms_ready.groupby(["country", "countryName", "timezone"]).size().reset_index(name="mobile_leads").sort_values("mobile_leads", ascending=False))print(by_tz.head(10))
Equivalent SQL query for CRM deduplication
SELECTe164,ANY_VALUE(international) AS international_format,ANY_VALUE(national) AS national_format,ANY_VALUE(country) AS country_iso,ANY_VALUE(countryName) AS country_name,ANY_VALUE(numberType) AS line_type,ANY_VALUE(isMobile) AS is_mobile,ANY_VALUE(carrier) AS carrier,ANY_VALUE(timezone) AS timezoneFROM validated_phone_numbersWHERE isValid = 'true'AND e164 <> ''GROUP BY e164;
🔗 Related B2B contact & verification actors
- Bulk Email Verifier — MX, Disposable & Deliverability
- Email & Contact Extractor — Emails, Phones, Socials
- Email Finder & Verifier — B2B Email Lookup API
- Email Pattern Finder — Name + Domain to Business Email
- Bulk Company Name to Domain Finder — Website, Logo & Match
📋 Changelog
- v1.2 (2026-11) — Unlocked unlimited 1,000+ bulk phone validation (
maxItemsdefault & prefill set to0so user lists are never truncated at 100), upgraded empty/default sample runs to output 100 realistic international phone records across 25 countries (scalable to1,000+viamaxItems), and added Key-Value StoreOUTPUTsummary statistics (totalValidated,validCount,invalidCount,mobileCount). - v1.1 (2026-10) — Serialized batch dataset flushing (
flushChain) to guarantee zero dropped records on fast runs. - v1.0 (2026-09) — Initial release with E.164 normalization, line-type detection, and carrier/timezone/location lookup.
▶️ Ready to clean and standardize your phone list? Paste your numbers, click Start, and export validated E.164 records in seconds!