Phone Number Validator (libphonenumber) - Bulk E.164 avatar

Phone Number Validator (libphonenumber) - Bulk E.164

Pricing

from $0.35 / 1,000 phone number validateds

Go to Apify Store
Phone Number Validator (libphonenumber) - Bulk E.164

Phone Number Validator (libphonenumber) - Bulk E.164

First 25 numbers free per run, then $0.50 per 1,000. Bulk phone enrichment: country, region, timezone, line type, validity, E.164, formats. Offline libphonenumber, no API key. Accepts phoneNumbers and defaultCountry inputs from other validators.

Pricing

from $0.35 / 1,000 phone number validateds

Rating

0.0

(0)

Developer

Penny Data

Penny Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 minutes ago

Last modified

Share

First 25 numbers per run are free; after that $0.50 per 1,000. Enrichment: country, region, timezone, line type (offline, no API key).

Phone Number Validator - Bulk E.164, Line Type & Format Check ($0.50 per 1,000)

Validate, parse and format phone numbers in bulk using Google's libphonenumber metadata (via libphonenumber-js). Blank or unparseable inputs are returned with an error code.

Try it free: turn on sampleOnly ("Free sample: first 10 numbers, no charge") to validate the first 10 numbers of your list with no charge at all.

Inputs saved for other phone validators also run here: phoneNumbers (or numbers, phone) in place of phones, and defaultCountry / defaultCountryCode in place of defaultRegion. Fields we do not return (includeCarrier, includeGeocoding, includeTimezone, formats, maxConcurrency) are accepted and ignored; maxResults limits the list. Output per row: E.164, validity, line type, country, calling code, national and international format; with includeGeoCarrier, also carrier, region and time zones (offline).

Paste phone numbers in any format, get back E.164, validity, line type and country. 1,000 numbers = $0.50.

inpute164validtypecountry
+1 415-555-2671+14155552671trueFIXED_LINE_OR_MOBILEUS
+44 20 7946 0958+442079460958trueFIXED_LINEGB
(212) 555-0100+12125550100trueFIXED_LINE_OR_MOBILEUS
not a numbernullfalsenullnull

Offline format check (libphonenumber): no carrier lookup, no API key. Unparseable rows are free. Rows above are real output of this actor's validator with defaultRegion US.

Pairs with Bulk Email Validator (no SMTP) for lead-list hygiene.

Features

  • Per-row status and run summary: every output row has rowStatus (ok, invalid or error) and rowReason, and each run saves a RUN_SUMMARY record in the key-value store with counts per status, rows billed and free rows.

Quick start

Input (phones is the only field you need):

{ "phones": ["+1 415-555-2671", "+44 20 7946 0958", "abc"], "defaultRegion": "US" }

Numbers in a Google Sheet? Set sheetUrl to the share link (shared as "Anyone with the link can view"; converted to CSV export automatically) and optionally sheetColumn: { "sheetUrl": "https://docs.google.com/spreadsheets/d/<id>/edit#gid=0", "sheetColumn": "Phone", "defaultRegion": "US" }. Output, one row per number (illustrative shape; values for +14155552671):

{ "input": "+1 415-555-2671", "e164": "+14155552671", "valid": true, "possible": true, "type": "FIXED_LINE_OR_MOBILE", "country": "US", "callingCode": "1", "nationalFormat": "(415) 555-2671", "internationalFormat": "+1 415-555-2671", "error": null }

Pricing event: phone-validated, $0.0005 per parseable number; blank or unparseable inputs are free.

Input: phones (list of numbers in any common format), defaultRegion (ISO 2-letter code, used for numbers without a + prefix, default US) and sampleOnly (process only the first 10 numbers, no charge). Inputs saved for other validators also work: phoneNumbers, numbers or phone are accepted in place of phones; phoneNumbersText takes numbers pasted one per line, defaultCountry works like defaultRegion, and onlyValid returns only valid numbers (invalid ones are left out and not charged).

Output per number: input, e164, valid, possible, type (MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, TOLL_FREE, VOIP, ...; null if unknown), country, callingCode, nationalFormat, internationalFormat, error.

Phone number formatter for WhatsApp: E.164 + wa.me click-to-chat link (format only, no WhatsApp account check). The E.164 digits are what a https://wa.me/<digits> link expects. This Actor does not contact WhatsApp and cannot tell you whether a number has a WhatsApp account.

Validate leads from a Google Maps Scraper run

  1. Run a Google Maps scraper (for example compass/crawler-google-places) and copy the dataset ID of the run (Storage tab).
  2. Paste it into inputDatasetId. The actor reads phoneUnformatted, internationalPhoneNumber or phone from each place (first one present) and validates it. Set defaultRegion to the scrape's country for numbers without a +.
  3. Each result row keeps the place's title, placeId, website and address when present, so you can join results back to the scrape.

Example: { "inputDatasetId": "YOUR_DATASET_ID", "defaultRegion": "US", "onlyValid": true }. This checks format and line type offline; it does not call the number or confirm it is in service.

UK, India and Brazil phone number validator

UK, India and Brazil phone number validator: +44, +91, +55 numbers parsed, validated and formatted offline. Set defaultRegion to GB, IN or BR for local-format numbers, or use the + prefix.

FAQ

How do I convert a list of phone numbers to E.164 in bulk?

Put the numbers in phones and set defaultRegion (for example US, GB, DE) for numbers written without a + prefix. Every row comes back with e164, nationalFormat and internationalFormat. Example input for a mixed list (the first has no +, so defaultRegion is used):

{ "phones": ["(415) 555-2671", "+44 20 7946 0958", "+49 30 123456"], "defaultRegion": "US" }

Numbers that can be parsed cost $0.0005 each ($0.50 per 1,000). Blank or unparseable inputs are returned with an error code and are not charged.

Can I clean a phone list before an SMS campaign?

Partly. Use valid and possible to find numbers that cannot exist (wrong length, no matching numbering-plan range) and type to see line type where the numbering plan says. It does not check whether a number is active, reachable or ported; that needs a paid carrier/HLR lookup. Turn on sampleOnly to run the first 10 numbers of your list free before you pay for the rest.

Is this number mobile or landline?

The type field returns MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, TOLL_FREE, VOIP and other libphonenumber types, or null when unknown. In the US and Canada mobile and landline share ranges, so you will often see FIXED_LINE_OR_MOBILE. This is numbering-plan metadata only, not a carrier check.

Does it work offline, with no API key?

Yes. The Actor runs Google's libphonenumber metadata (via libphonenumber-js) inside the run: no third-party lookup service, no API key and no per-lookup vendor fee. You pay only the Actor's pay-per-event price of $0.50 per 1,000 parseable numbers.

Do I need an API key or external credits?

No. There is no third-party lookup account, API key or prepaid credit balance to top up, so you cannot hit a "no balance" error from an outside service. The only cost is this Actor's pay-per-event charge on your Apify account. Set sampleOnly to validate the first 10 numbers free.

What does it not return?

No live-line / active / reachable / ported status, no WhatsApp or SMS deliverability, no owner name and no personal-data lookup. It returns only what libphonenumber's numbering-plan metadata can say: format, validity, line type and country, plus carrier (original allocation), region and time zones when includeGeoCarrier is on.

I already use libphonenumber. Why pay for this?

You don't have to if you are happy to run it in your own code. Use this Actor when you want phone validation as an API or scheduler step (Make, n8n, Zapier, or a direct API call) or as a one-off CSV job without setting up code. Results match libphonenumber output; there is no extra data beyond that.

What about emails in the same list?

Use Bulk Email Validator (No SMTP) for the email column of the same lead list.

Use it from Google Sheets (=PHONE_E164)

Paste this Apps Script into Extensions > Apps Script, add your own Apify token as script property APIFY_TOKEN (never in the code), then use =PHONE_E164(A2:A50) to get E.164, valid, line type and country per row. It calls this Actor's run-sync-get-dataset-items endpoint on your account.

function PHONE_E164(range, defaultRegion) {
var token = PropertiesService.getScriptProperties().getProperty('APIFY_TOKEN');
if (!token) throw new Error('Set script property APIFY_TOKEN.');
var rows = Array.isArray(range) ? range : [[range]], flat = [];
rows.forEach(function (r) { r.forEach(function (c) { flat.push(String(c == null ? '' : c).trim()); }); });
var phones = flat.filter(function (p, i) { return p && flat.indexOf(p) === i; });
if (!phones.length) return flat.map(function () { return ['', '', '', '']; });
var res = UrlFetchApp.fetch('https://api.apify.com/v2/acts/pennydata~phone-number-validator-offline/run-sync-get-dataset-items?format=json&clean=true', {
method: 'post', contentType: 'application/json', headers: { Authorization: 'Bearer ' + token },
payload: JSON.stringify({ phones: phones, defaultRegion: defaultRegion || 'US' }), muteHttpExceptions: true });
if (res.getResponseCode() >= 300) throw new Error('Apify HTTP ' + res.getResponseCode());
var by = {}; JSON.parse(res.getContentText()).forEach(function (it) { by[it.input] = it; });
return flat.map(function (p) { var it = by[p]; return !p ? ['', '', '', ''] : !it ? ['no result', '', '', ''] : [it.e164 || '', it.valid === true, it.type || '', it.country || '']; });
}

Runs are billed to your Apify account at the per-number price below.

Pricing

Pay per event, no start fee. Prices match .actor/pay_per_event.json.

EventPriceWhen it is charged
phone-validated$0.0005 per number ($0.50 per 1,000)One number that could be parsed and returned (valid or invalid)
Blank or unparseable inputFreeReturned with an error code, never charged

Example: 1,000 inputs of which 40 are blank or unparseable cost 960 x $0.0005 = $0.48. Set a maximum cost per run in the run options; the actor stops charging when that limit is reached. Apify platform usage is billed separately if your plan includes it.

Honest limits

  • Offline only. No carrier lookup, no HLR, no "is this number active/reachable/ported" check, no owner or personal-data lookup. valid means the number matches a real numbering plan range; it may not be assigned to anyone.
  • Line type comes from libphonenumber metadata and is not always determinable (US numbers are often FIXED_LINE_OR_MOBILE).
  • Time zones come from libphonenumber metadata (opt-in via includeGeoCarrier); where an area spans several zones all are returned.
  • Numbers without a + prefix use defaultRegion; a wrong region gives wrong results.
  • Metadata is as current as the bundled library version.

Not affiliated with Google or the libphonenumber project. Written with the assistance of an AI (Claude Sonnet 5.5).

Switching from another phone validator

Paste the input you already use and change only the actor ID. These keys are accepted as aliases:

Other validator's inputUsed here as
phoneNumbers, numbers, phone, phoneNumbersText (list, text or {phone} objects)phones
defaultCountry, defaultCountryCode, countrydefaultRegion
maxResultscap on numbers processed
includeCarrier, includeGeocoding, includeTimezone, formats, maxConcurrencyaccepted and ignored (use includeGeoCarrier for offline carrier, region and time zone)

Input is compatible; the output field names are this actor's own (e164, valid, type, country), so check your downstream mapping once.

Other small pay-per-event Actors from the same publisher:

Geo and carrier (optional)

Set includeGeoCarrier to add carrier, geoLocation (city/region, e.g. US area-code city and state) and timeZones (IANA names) to valid numbers. Offline lookup from libphonenumber metadata: carrier is the original allocation and ignores number porting; many fixed-line numbers have no carrier. Off by default.