Phone Number Validator
Pricing
Pay per event
Phone Number Validator
Validate and format phone numbers using Google libphonenumber. Returns validity, type (mobile, fixed-line, VoIP), country, E.164 format, national format, and carrier info. Process up to 10,000 numbers per run. Ideal for CRM cleanup and lead enrichment.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Actor stats
0
Bookmarked
6
Total users
2
Monthly active users
14 days ago
Last modified
Categories
Share
Validate and format phone numbers from any country using Google's libphonenumber — the same library that powers Android, Google Contacts, and billions of other applications. Submit a list of phone numbers and get back validity status, number type (mobile/fixed-line/VoIP/toll-free), E.164 format, national format, country detection, and country calling code.
Whether you are cleaning a CRM database, verifying leads before a campaign, or building a data pipeline that requires standardized phone data, this actor gives you accurate, production-grade results at scale.
🔍 What does it do?
For each phone number you provide, the actor returns:
- Validity check — is it a real, dialable number? (
isValid,isPossible) - Number type — mobile, fixed_line, toll_free, premium_rate, voip, shared_cost, pager, personal_number, uan, voicemail, or fixed_line_or_mobile
- Country detection — ISO 3166-1 alpha-2 country code (e.g.
US,GB,FR) - Country calling code — e.g.
+1,+44,+33 - National number — the subscriber number without the country code
- E.164 format — the universal standard format used in APIs and databases (e.g.
+12025550173) - International format — human-readable international notation (e.g.
+1 202 555 0173) - National format — locally formatted number (e.g.
(202) 555-0173for US) - RFC 3966 format — URI format for click-to-call (e.g.
tel:+12025550173)
👥 Who is it for?
CRM and sales teams — clean your contact database before launching an outreach campaign. Invalid or wrongly formatted numbers cause failed calls, bounced SMS messages, and wasted spend.
Lead generation agencies — verify that phone numbers collected from web scraping, form fills, or purchased lists are valid before handing them to clients. A list with 30% invalid numbers destroys your reputation.
Developers and data engineers — normalize phone numbers to E.164 format for storage in databases, APIs, or Twilio/Vonage pipelines. Consistent formatting eliminates duplicate detection errors.
Marketing operations — segment your audience by phone number type before a campaign. Mobile numbers can receive SMS; fixed-line numbers cannot. Toll-free and premium-rate numbers should be filtered from automated dialers.
Compliance teams — identify and remove invalid numbers from your system before GDPR/TCPA audits. Storing clearly invalid data is a liability.
💡 Why use this actor?
- Google's libphonenumber — the authoritative phone number library used by Android, Google Contacts, WhatsApp, and more. No homegrown regex guesswork.
- Max metadata — uses the full
libphonenumber-js/maxdataset for the most accurate type detection across all countries. - Multiple output formats — get E.164, international, national, and RFC 3966 formats in a single pass.
- Graceful error handling — invalid numbers are returned with
isValid: falseand an error message rather than crashing the run. - Default country fallback — process local-format numbers (without country prefix) by setting a default country code.
- Deduplication — duplicate phone numbers in the input are automatically removed.
- No proxy needed — runs entirely without network requests to external services (all validation is done locally using libphonenumber metadata).
📊 Output data
Each validated phone number produces one dataset row:
| Field | Type | Example | Description |
|---|---|---|---|
input | string | "+1 202-555-0173" | Original input string |
isValid | boolean | true | Whether the number is valid for dialing |
isPossible | boolean | true | Whether the number has the right length (looser check) |
type | string | "fixed_line_or_mobile" | Number type: mobile, fixed_line, toll_free, voip, etc. |
country | string | "US" | ISO 3166-1 alpha-2 country code |
countryCode | string | "+1" | Country calling code with + prefix |
nationalNumber | string | "2025550173" | Subscriber number without country code |
internationalFormat | string | "+1 202 555 0173" | Human-readable international format |
nationalFormat | string | "(202) 555-0173" | Locally formatted number |
e164Format | string | "+12025550173" | E.164 standard format (for APIs/databases) |
rfc3966Format | string | "tel:+12025550173" | RFC 3966 URI format (for click-to-call) |
carrier | string/null | null | Carrier info (not available in libphonenumber-js) |
error | string/null | null | Error message if parsing failed |
validatedAt | string | "2026-01-15T10:30:00.000Z" | ISO timestamp of validation |
💰 How much does it cost to validate phone numbers?
Pricing is pay-per-event (PPE):
- Start fee: $0.01 per run (one-time)
- Per number: $0.001 per phone number validated
Examples:
- 100 numbers → $0.01 (start) + $0.10 (validation) = $0.11
- 1,000 numbers → $0.01 + $1.00 = $1.01
- 10,000 numbers → $0.01 + $10.00 = $10.01
All Apify accounts include a $5/month free tier, which covers ~4,900 validations per month at no cost.
🚀 How to use it
Step 1: Open the actor
Go to Phone Number Validator on Apify Store and click Try for free.
Step 2: Enter your phone numbers
In the Phone Numbers field, enter one phone number per line. Include the country dialing code (e.g. +1 for US, +44 for UK) for the most accurate results.
Step 3: Set a default country (optional)
If you are validating local-format numbers that do not include a country prefix (e.g. (202) 555-0173 for a US number), set the Default Country field to the appropriate ISO 3166-1 alpha-2 code (e.g. US).
Step 4: Run and download
Click Start. Results appear in the dataset as they are processed. Download as JSON, CSV, or Excel from the Storage tab.
⚙️ Input parameters
Phone Numbers (required)
- Type: Array of strings
- Description: The list of phone numbers to validate. One number per entry.
- Best practice: Include the country calling code (e.g.
+1 202 555 0173) for reliable country detection and type identification. Numbers without a country code will be interpreted against thedefaultCountrysetting. - Formats accepted: Any format libphonenumber can parse —
+12025550173,+1 (202) 555-0173,+1-202-555-0173,202-555-0173(with defaultCountry set), etc.
Default Country (optional)
- Type: String (ISO 3166-1 alpha-2, e.g.
US,GB,DE) - Description: Fallback country used when a phone number does not include a country prefix.
- Default: None (international numbers always work regardless of this setting)
- Example: Set to
USto correctly parse(800) 555-0199as a US toll-free number.
📤 Output example
{"input": "+33 6 12 34 56 78","isValid": true,"isPossible": true,"type": "mobile","country": "FR","countryCode": "+33","nationalNumber": "612345678","internationalFormat": "+33 6 12 34 56 78","nationalFormat": "06 12 34 56 78","e164Format": "+33612345678","rfc3966Format": "tel:+33612345678","carrier": null,"error": null,"validatedAt": "2026-01-15T10:30:00.000Z"}
Invalid number example:
{"input": "not-a-phone-number","isValid": false,"isPossible": false,"type": null,"country": null,"countryCode": null,"nationalNumber": null,"internationalFormat": null,"nationalFormat": null,"e164Format": null,"rfc3966Format": null,"carrier": null,"error": "NOT_A_NUMBER","validatedAt": "2026-01-15T10:30:00.000Z"}
💡 Tips and best practices
- Always include the country code (
+) when possible — it eliminates ambiguity and gives you the most accuratetypeandcountrydetection. - Use E.164 for storage — the
e164Formatfield (+12025550173) is the canonical format used by Twilio, Vonage, AWS SNS, and most telecom APIs. Store this, not the original input. - Filter by type before SMS campaigns — only
mobileandfixed_line_or_mobilenumbers can receive SMS. Filter outfixed_line,toll_free,premium_rate, andvoipbefore uploading to your SMS provider. - isPossible vs isValid —
isPossibleis a faster, looser check (correct length for the country).isValidis the full check against the national numbering plan. For strict data quality, useisValid. For quick triage of obviously broken numbers,isPossible: falseis a fast filter. - Batch large lists — the actor handles any size list in a single run. For millions of numbers, use the API and stream results from the dataset.
- Deduplication is automatic — if you send the same number multiple times in one run, it is validated once and billed once.
🔗 Integrations
Twilio / SMS campaign pre-validation
Before uploading contacts to Twilio Messaging Service, run them through this actor and filter for isValid: true and type in ['mobile', 'fixed_line_or_mobile']. Export the e164Format column as your contact list. This eliminates failed message delivery fees.
HubSpot / Salesforce CRM cleanup
Export phone number fields from your CRM, validate them in bulk, then use the Apify API to import results back. Update records where isValid: false with a "phone_invalid" tag. Use e164Format to standardize formatting across all CRM records.
n8n / Make.com automation
Connect this actor to an n8n or Make.com workflow: trigger on new form submissions, pass the phone field through this validator, and branch on isValid. Route valid numbers to your CRM or dialer; route invalid ones to a Slack alert channel for manual review.
Google Sheets
Use the Apify Google Sheets integration to pull validation results directly into a spreadsheet. Create columns for each output field and use conditional formatting to highlight isValid: false rows in red.
🛠️ API usage
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('automation-lab/phone-number-validator').call({phoneNumbers: ['+1 202-555-0173', '+44 20 7946 0958', '+33 6 12 34 56 78'],defaultCountry: 'US',});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
from apify_client import ApifyClientclient = ApifyClient(token='YOUR_APIFY_TOKEN')run = client.actor('automation-lab/phone-number-validator').call(run_input={'phoneNumbers': ['+1 202-555-0173', '+44 20 7946 0958', '+33 6 12 34 56 78'],'defaultCountry': 'US',})for item in client.dataset(run['defaultDatasetId']).iterate_items():print(item)
cURL
curl -X POST \'https://api.apify.com/v2/acts/automation-lab~phone-number-validator/runs?token=YOUR_APIFY_TOKEN' \-H 'Content-Type: application/json' \-d '{"phoneNumbers": ["+1 202-555-0173", "+44 20 7946 0958"],"defaultCountry": "US"}'
Use with Claude AI (MCP)
This actor is available as a tool in Claude AI through the Model Context Protocol (MCP). Add it to Claude Desktop, Cursor, Windsurf, or any MCP-compatible client.
Setup for Claude Code
$claude mcp add --transport http apify "https://mcp.apify.com"
Setup for Claude Desktop, Cursor, or VS Code
Add this to your MCP config file:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com"}}}
Example prompts
- "Validate these phone numbers and tell me which ones are valid mobile numbers: +1 555-123-4567, +44 7911 123456, +33 6 12 34 56 78."
- "I have a list of phone numbers exported from my CRM — validate them all and return only the valid ones in E.164 format."
- "Check if +1 800 555 0100 is a toll-free number and what country it belongs to."
Learn more in the Apify MCP documentation.
⚖️ Legality and data privacy
Phone number validation using libphonenumber operates entirely on the local metadata bundled with the library — no phone numbers are sent to any external service. The validation is purely computational.
Processing phone numbers in bulk for CRM cleanup or lead validation falls under normal data processing activities. However, if you are processing phone numbers of EU residents, ensure your use case complies with GDPR requirements for data minimization and legitimate purpose. The actor does not store data beyond what is in your Apify dataset.
❓ FAQ
Q: Why does a valid-looking number show isValid: false?
A: isValid checks the number against the national numbering plan for its country — the number must be an actual assignable number, not just the right length. For example, +1 555-123-4567 is a US number with valid format but isValid: false because the 555 area code prefix is largely unassigned. Numbers that are isPossible: true but isValid: false have the right length but fail the stricter national plan check.
Q: Why is type showing fixed_line_or_mobile instead of mobile or fixed_line?
A: For some countries (notably the US), the national numbering plan does not distinguish between mobile and fixed-line numbers at the number level — a single block can be assigned to either. This is a data limitation of the numbering plan, not a bug. For countries like France, Germany, UK, and Brazil, the actor correctly identifies mobile vs fixed-line.
Q: I set defaultCountry but numbers with a + prefix are still parsed as foreign numbers.
A: Correct — this is the expected behavior. The + prefix always takes priority over defaultCountry. The defaultCountry only applies to numbers that have no country prefix at all.
Q: Can I validate VoIP numbers?
A: Yes. VoIP numbers that are assigned through a national carrier and registered in libphonenumber's database will show type: "voip" and isValid: true. VoIP numbers from providers that use unregistered ranges may show isValid: false.
Q: What happens if I submit thousands of duplicate numbers?
A: Duplicates are automatically removed at the start of the run. You are only billed for unique numbers that are actually validated.
🔗 Related actors
- Email Syntax Validator — Validate email addresses and check MX records
- IP Address Validator — Validate and geolocate IP addresses
- Domain Availability Checker — Check if domains are registered
- DNS Lookup — Query DNS records for any domain
- Email Enrichment — Enrich email addresses with company and social data