Bulk Phone Number Validator — E.164, Carrier & Line Type avatar

Bulk Phone Number Validator — E.164, Carrier & Line Type

Pricing

from $0.60 / 1,000 results

Go to Apify Store
Bulk Phone Number Validator — E.164, Carrier & Line Type

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

Haketa

Maintained by Community

Actor stats

0

Bookmarked

13

Total users

1

Monthly active users

a day ago

Last modified

Features

Limited permissions

Share

Bulk Phone Number Validator — E.164 Formatter, Line Type, Carrier, Country & Timezone Lookup

Apify Actor

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

FeatureDetails
🎯 Core capabilityBulk phone validation, E.164 normalization, line-type classification, and carrier/timezone/location enrichment
🌍 Global coverage240+ 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 detectionDistinguishes MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, VOIP, TOLL_FREE, PREMIUM_RATE, SHARED_COST, PERSONAL_NUMBER, PAGER, UAN, VOICEMAIL
💬 SMS & WhatsApp flagDerived isMobile flag ("true" / "false") so you never waste SMS budget texting landlines
🔁 Scale & throughputProcesses 100 to 1,000,000+ phone numbers per run (maxItems: 0 = unlimited) in parallel (maxConcurrency: 50)
🔓 Keyless & zero network lagPowered by embedded international numbering plan metadata — 0 external API calls, 0 rate limits, 100% deterministic
⬇️ Export & APIJSON, 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" and isMobile = "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, and 0014155552671 all 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) and countryName fields 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 clear error reason) 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 phoneNumbers empty 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 3456789 with defaultCountry: "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 clickable uri (tel:+4915123456700).
  • ✅ Carrier, geographic area & timezone enrichment — enriches valid numbers with original mobile carrier (e.g., T-Mobile, Vodafone, Orange, China Mobile), landline location (state/city), and IANA timezone.
  • ✅ 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 in error so your spreadsheet row alignment stays intact.
  • ✅ Key-Value Store OUTPUT summary — writes run totals (totalValidated, validCount, invalidCount, mobileCount) to OUTPUT for instant inspection by automated pipelines.

🎯 Use cases & B2B data hygiene workflows

Team / RoleWorkflow & Value Delivered
📈 B2B Lead Generation & Scraping TeamsPipe 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 MarketingUpload 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 AdministratorsRun 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 TeamsEnrich raw prospect lists with timezone, countryName, location, and national format so dialers automatically schedule calls within legal local calling windows.
⚙️ Backend & Automation EngineersTrigger 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.

FieldTypeDefault / PrefillDescription
phoneNumbersarray<string>[] (runs 100-item sample)Phone numbers to validate, one per line. Accepts E.164, international, or national formats.
defaultCountrystring"" (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 +.
includeCarrierDatabooleantrueEnriches valid numbers with carrier, location, and timezone. Disable only if you want raw validation speed on multi-million-row lists.
maxItemsinteger0 (Unlimited)Maximum number of records to output (0 = process the entire list without limits). Also supports maxResults / maxRecords.
maxConcurrencyinteger50Number 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

FieldTypeCoverageDescription
inputstring🟢 High (100%)Exact raw phone number string as supplied in the input.
isValidstring🟢 High (100%)"true" if the number passes full length, prefix, and country numbering plan rules; "false" otherwise.
isPossiblestring🟢 High (100%)"true" if the digit length is possible for the detected country.
e164string🟢 High (100% of valid)Canonical E.164 format (e.g., +4915123456700) — ideal primary key for CRM deduplication.
internationalstring🟢 High (100% of valid)Human-readable international format (e.g., +49 1512 3456700).
nationalstring🟢 High (100% of valid)Local dialing format within the country (e.g., 01512 3456700).
uristring🟢 High (100% of valid)RFC 3966 clickable dialer URI (tel:+4915123456700).
extensionstring🟡 ConditionalExtension digits parsed from inputs like ext. 123 or #123 (empty string when none).
errorstring🟡 ConditionalDiagnostic message when isValid is "false" (e.g., "number is not valid for its country").

📱 Line Type, Country & Enrichment Fields

FieldTypeCoverageDescription
numberTypestring🟢 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.
isMobilestring🟢 High (100%)"true" when numberType is MOBILE or FIXED_LINE_OR_MOBILE (capable of receiving SMS).
countryCodestring🟢 High (100% of valid)International country calling prefix without + (e.g., 1, 44, 49, 90, 91).
countrystring🟢 High (100% of valid)Two-letter ISO 3166-1 alpha-2 country code (e.g., US, GB, DE, FR, IN).
countryNamestring🟢 High (100% of valid)Full English country name (e.g., United States, United Kingdom, Germany).
carrierstring🟡 Conditional (~80% mobile)Original mobile network operator assigned to the prefix (e.g., T-Mobile, Vodafone, Orange). Empty on landlines.
locationstring🟡 Conditional (Geographic)City, state, or region for geographic/fixed-line numbers (e.g., San Francisco, CA, London).
timezonestring🟢 High (~98% of valid)Comma-separated IANA timezone IDs for the number's region (e.g., Europe/Berlin, America/New_York).
scrapedAtstring🟢 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 phoneNumbers empty and set maxItems: 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

  1. Open the Bulk Phone Number Validator in Apify Console.
  2. Paste your phone numbers into phoneNumbers (or leave it empty to test with the 100-number sample).
  3. Select defaultCountry if your list contains local national numbers without a + prefix.
  4. 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 ApifyClient
client = 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 +, leave defaultCountry on 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 reports FIXED_LINE_OR_MOBILE and sets isMobile: "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 carrier as 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 geographic location (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 e164 number, isMobile status, countryName, and timezone so SDRs always dial clean numbers during local business hours.
  • 💬 Twilio, WhatsApp Business, Klaviyo & Braze: Pre-filter every contact list to isValid == "true" and isMobile == "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 input or e164.
  • 🔗 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 Apify
df = pd.read_json("validated_phones.json")
# 1. Keep only valid numbers and deduplicate on canonical E.164
valid_df = df[df["isValid"] == "true"].drop_duplicates(subset=["e164"])
# 2. Segment into SMS-capable mobile numbers vs. fixed-line / landline numbers
sms_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 scheduling
by_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

SELECT
e164,
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 timezone
FROM validated_phone_numbers
WHERE isValid = 'true'
AND e164 <> ''
GROUP BY e164;


📋 Changelog

  • v1.2 (2026-11) — Unlocked unlimited 1,000+ bulk phone validation (maxItems default & prefill set to 0 so user lists are never truncated at 100), upgraded empty/default sample runs to output 100 realistic international phone records across 25 countries (scalable to 1,000+ via maxItems), and added Key-Value Store OUTPUT summary 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!

⌂ 换网址