# Bulk phone number validator and E.164 formatter

> Bulk phone number validator. Check numbers and format them to E.164. Get country, line type, time zone and carrier. Offline, no login or API key.

URL: https://cliqtomedia.com/actors/phone-number-validator/

Category: Leads, companies & validation · Status: live on Apify Store · Apify page: https://apify.com/cliqtomedia/phone-number-validator?fpr=cliqto

Paste phone numbers in any format. You get the valid ones in E.164, with country and line type. Bad numbers get a short reason, like too short.

## How to use it: 3 steps

1. **Make a free Apify account.** Apify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
2. **Paste your input and press Start.** No code needed: you fill in a form (the input). It already has a working example. For example: `+1 650 253 0000` in Phone numbers. Each start is one run.
3. **Download the results.** When the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

## What it does

Paste a list of phone numbers in any notation, or point the Actor at an Apify dataset. For each number it tells you if the number is valid and returns its E.164 form, country, line type (mobile, fixed line, VoIP, toll-free), time zones and the carrier the number range was given to. It runs offline on Google's libphonenumber metadata: no login, no API key.



### Good for

- Turn a messy CRM export or web form list into E.164 numbers for a CRM, dialer or SMS tool.
- Remove numbers that cannot exist (too short, too long, unknown country code) before you pay for calls or messages.
- Split a list by country, line type (mobile or fixed line) or time zone to plan calls.
- Check the `phone` field of a dataset made by a lead or maps scraper.

### Not a good fit

- It does not check if a number is active, reachable or on WhatsApp. "Valid" means the number fits an assigned range of its country's numbering plan. No HLR lookup, calls or SMS are made.
- It does not find who owns a number (no names, emails or addresses).
- `carrierByPrefix` is the operator the number range was first given to. Ported numbers keep the old operator here. The data has no carrier for US and Canadian numbers.
- No Do-Not-Call or TCPA checks: those need paid external databases.
- Up to 50,000 numbers per run.

## Price

Pay per event. Apify bills you, not us.

| What you pay for | Price | When |
|---|---|---|
| Start fee | $0.0025 | Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more. |
| Phone number checked | $0.0008 (from $0.00068 on paid Apify plans) | One checked phone number saved to the Dataset: valid, invalid or unparseable. Empty lines and skipped duplicates are free. |

- One phone number: about $0.0033.
- 1,000 phone numbers: about $0.80.
- Every day 100 phone numbers, for 30 days: about $2.48 a month.

Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed.

Prices checked on 24 October 2026. Current price: https://apify.com/cliqtomedia/phone-number-validator?fpr=cliqto

## Questions

### Does valid mean the number works?

No. It fits the country's number plan. No calls or SMS are made.

### Why is the carrier empty for US numbers?

The data has no carrier for the US and Canada.

### How many numbers can I check?

Up to 50,000 per run. Empty lines and duplicates are free.

### Do I need an API key?

No. The check runs inside the tool with open-source data.

### Why do I pay for invalid numbers?

Each row is a finished check with an answer: invalid numbers are the ones you want to find. Empty lines and skipped duplicates are free.

### How fresh is the data?

Each build uses one version of the libphonenumber metadata, shown in `RUN_SUMMARY` as `metadataVersion`. New number ranges appear after the library and the Actor are updated.

## Data fields

- `input` (string): The number as given (trimmed).
- `inputIndex` (integer): 1-based position of the input item the number came from: phones list items first, then dataset items. Several numbers in one line share the index; empty items keep their position.
- `status` (string): valid: a number in an assigned range of its country. invalid: parsed, but wrong length or not an assigned range. unparseable: not a phone number, or no country code and no default country.
- `valid` (boolean): true only for status valid.
- `possible` (boolean): Length check only (looser than valid). null when the text could not be parsed.
- `reason` (string): Why a number is not valid: MISSING_COUNTRY_CODE, MISSING_OR_INVALID_COUNTRY_CODE, NOT_A_NUMBER, TOO_SHORT, TOO_LONG, INVALID_LENGTH, POSSIBLE_LOCAL_ONLY, INVALID_COUNTRY_CODE, NOT_IN_NUMBERING_PLAN. null for valid numbers.
- `error` (string): Plain-English explanation of reason.
- `e164` (string): E.164 format, e.g. +16502530000. Only for valid numbers; present when E164 is selected in output formats.
- `international` (string): International format, e.g. +1 650-253-0000. Only for valid numbers.
- `national` (string): National format, e.g. (650) 253-0000. Only for valid numbers.
- `rfc3966` (string): RFC 3966 tel: URI, e.g. tel:+1-650-253-0000. Only for valid numbers when selected.
- `countryCode` (integer): Country calling code, e.g. 1, 44. Known whenever the number parses.
- `regionCode` (string): ISO 3166-1 alpha-2 country/region, e.g. US, GB; 001 for non-geographic numbers. null when not known.
- `country` (string): English country name, valid numbers only; null for non-geographic numbers (region 001).
- `location` (string): City or area from the number prefix (e.g. Mountain View, CA), valid numbers only; null when the prefix only tells the country.
- `numberType` (string): Line type from the numbering plan. FIXED_LINE_OR_MOBILE where the plan does not separate them (US, Canada). null for numbers that are not valid.
- `carrierByPrefix` (string): Operator the number range was originally allocated to (mobile numbers in most countries). Numbers can be ported, so this is not the current carrier. null when unknown.
- `timezones` (array): IANA time zones for the number prefix; several when the prefix covers a large area. null when unknown.
- `extension` (string): Extension written after the number (ext. 123), if any.
- `defaultCountryApplied` (boolean): true when the number had no country code and the default country was used.
- `source` (string): Always libphonenumber (offline).
- `checkedAt` (string): ISO 8601 time of the check (UTC).

## Input settings

- `phones` (array): Up to 50,000 numbers per run, in any notation: +1 650-253-0000, (650) 253 0000, tel:+44-20-7031-3000. One per line; a line with several numbers separated by commas, semicolons or tabs is split. Numbers without a + country code need the default country below.
- `defaultCountry` (string): Country used for numbers written without + and a country code, e.g. (212) 555-0100 with United States. Numbers that start with + keep their own country, and so do numbers with the international dialing prefix of the default country (011 for the United States, 00 for most of Europe). Leave empty when every number has a country code.
- `outputFormats` (array): Formatted versions to add for valid numbers. E.164 (+16502530000) is best for CRMs and SMS tools; international (+1 650-253-0000) and national ((650) 253-0000) are for display; RFC 3966 (tel:+1-650-253-0000) is for links.
- `deduplicate` (boolean): Skip repeats of a number, even when it is written differently (+1 650 253 0000 and (650) 253-0000 with default country US are the same number; a different extension counts as a different number). Skipped duplicates are not charged. Off: one output row per input line.
- `inputDatasetId` (string): Read numbers from an existing Apify dataset, e.g. the output of a lead or maps scraper. Combined with the list above. A run checks at most 50,000 numbers and reads at most 100,000 dataset items; a bigger dataset is checked up to that limit. The run stops with an error if, after the first 200 items, fewer than 10% of the items read have a phone value (with deduplication: a different phone value); if that happens later, reading stops and the numbers found are checked.
- `phoneField` (string): Name of the dataset field with the phone number. A field with a list of numbers is also read. Items without it are counted in the run summary.

## Step by step on Apify

1. Open the Input tab.
2. Paste numbers into Phone numbers (`phones`), one per line. The form already has four examples.
3. Keep Default country (`defaultCountry`) as United States, or choose the country of numbers written without `+`.
4. Click Start.
5. Open the Output tab. In the Overview view, check `status` and `e164` for each number.

## Use cases

| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| Clean numbers before a CRM import | `phones` + `defaultCountry` | One row per number | `valid`, `e164`, `reason` | Export CSV, map `e164` to the CRM phone field |
| Check numbers found by a scraper | `inputDatasetId` + `phoneField` | One row per number in the dataset | `e164`, `regionCode`, `numberType` | Join back by `input` |
| Keep only mobile numbers for SMS | `phones` | One row per number | `numberType`, `e164` | Filter `numberType` = `MOBILE` or `FIXED_LINE_OR_MOBILE` |
| Plan call times by region | `phones` | One row per number | `timezones`, `location` | Sort or group by `timezones` |

## Tips

- Set a default country for numbers written without a + code.
- Filter numberType for MOBILE before an SMS campaign.
- Group by time zone to plan good call times.

## Limits



- 50,000 numbers per run (`phones` and dataset together). More than 50,000 in `phones` fails with `INVALID_INPUT`; split the list. A bigger dataset is checked up to the limit (`PARTIAL`, `INPUT_LIMIT`).
- Up to 100,000 dataset items are read; the run stops early on a dataset where the phone field is (almost) empty or repeats.
- Inputs longer than 250 characters are `unparseable` with reason `TOO_LONG`.
- Run time at the default 512 MB memory: about 4 seconds for 2,500 numbers and about 85 seconds for 50,000. Reading 50,000 items of an input dataset adds about 25 seconds. At the minimum of 256 MB, 50,000 numbers take about 2 minutes.

## Sample result

```json
{
  "input": "+44 20 7031 3000",
  "inputIndex": 2,
  "status": "valid",
  "valid": true,
  "possible": true,
  "reason": null,
  "error": null,
  "e164": "+442070313000",
  "international": "+44 20 7031 3000",
  "national": "020 7031 3000",
  "countryCode": 44,
  "regionCode": "GB",
  "country": "United Kingdom",
  "location": "London",
  "numberType": "FIXED_LINE",
  "carrierByPrefix": null,
  "timezones": ["Europe/London"],
  "extension": null,
  "defaultCountryApplied": false,
  "source": "libphonenumber (offline)",
  "checkedAt": "2026-10-13T12:00:00Z"
}
```

## Use it from code

Actor ID: `cliqtomedia/phone-number-validator`

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/phone-number-validator").call(run_input={
    "phones": [
        "+1 650 253 0000",
        "+44 20 7031 3000",
        "12345",
        "(212) 555-0100"
    ],
    "defaultCountry": "US"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

```bash
curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~phone-number-validator/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"phones": ["+1 650 253 0000", "+44 20 7031 3000", "12345", "(212) 555-0100"], "defaultCountry": "US"}'
```

```python
# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("cliqtomedia/phone-number-validator")
result = tool.invoke({"run_input": {"phones": ["+1 650 253 0000", "+44 20 7031 3000", "12345", "(212) 555-0100"], "defaultCountry": "US"}})
print(result)
```

run-sync waits up to 300 seconds; for longer runs start a run and use a webhook. LlamaIndex and MCP: https://cliqtomedia.com/actors/ai-agents/

## Use cases with this tool

- [Lead lists from public data](https://cliqtomedia.com/actors/use-cases/lead-generation/): Build lists of companies and contacts from public sites. Check emails and phones before you send.

## Similar tools

- [Bulk Email Verifier: MX, Disposable, Role & Typo Check](https://cliqtomedia.com/actors/email-verifier/)
- [Website Contact Scraper](https://cliqtomedia.com/actors/website-contacts-scraper/)
- [Domain WHOIS (RDAP) & DNS Lookup, No Login](https://cliqtomedia.com/actors/domain-whois-dns-lookup/)
- [EU VAT Number Validator (VIES) - Bulk Check, No Login](https://cliqtomedia.com/actors/vat-number-validator/)
- [Europages Scraper: B2B Suppliers & Certificates (No Login)](https://cliqtomedia.com/actors/europages-companies-scraper/)
- [France Company & SIRET Search](https://cliqtomedia.com/actors/france-sirene-company-search/)
