# Phone Number Validator: E.164, country and line type, offline (`bepolabs/phone-validator`) Actor

Tidy up data from forms, imports and spreadsheets before it reaches your calling tool: standardised output, a plain reason for each rejection, 100,000 per run, fully private. Costs 1 USD per 1,000 checked phone numbers.

- **URL**: https://apify.com/bepolabs/phone-validator.md
- **Developed by:** [BEPO Labs](https://apify.com/bepolabs) (community)
- **Categories:** Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 checked phone numbers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 📞 What is Phone Number Validator?

Stop bounced texts and dead calls: this bulk phone number validator turns a messy sheet in any style into rows with a verdict, the E.164 form your dialler expects, the origin and the kind of carrier service. Checks use bundled libphonenumber data without network lookups, so 10,000 entries finish in seconds and nothing leaves the run.

- **CRM and lead list cleanup**: turn `(202) 456-1111`, `0044 20 7946 0958` and `030 1234567` into one E.164 format and drop numbers that cannot exist
- **SMS and WhatsApp campaigns**: keep only `mobile` numbers before you pay per message
- **Sign-up and checkout forms**: check exported numbers in bulk, or once a day from a schedule
- **Data enrichment**: add country and line type to scraped records, for example from Website Contacts
- **AI agents**: let Claude or ChatGPT validate and format phone numbers through MCP

![Phone Number Validator: Bulk phone number validation offline: valid or not, E.164 format, country and line type (mobile, fixed line, VoIP) for every number.](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/phone-validator-hero.png)

#### ✨ Why use this Actor?

- ✅ **Any input format**: with or without `+`, spaces, dots, brackets, `00` or `011` prefixes and extensions (`ext. 12`)
- ✅ **Every country**: the numbering plans of all countries and territories, kept current by Google's libphonenumber
- ✅ **Service type**: mobile, fixed line, VoIP, toll-free, premium rate, shared cost and more
- ✅ **A reason for every failure**: `problem` says in plain words why a number is not valid
- ✅ **Offline and private**: no carrier or HLR lookup, nothing leaves the run; 100,000 numbers per run
- ✅ **Fair price**: 1 USD per 1,000 numbers, no start fee; with `onlyValid` the rest is free

### 📦 What data can you get with Phone Number Validator?

| | | |
|---|---|---|
| ✅ Valid, possible or invalid | 🌐 E.164 format | 🔢 International and national format |
| 🏳️ Country and country name | ☎️ Calling code | 📱 Line type (mobile, landline, VoIP) |
| ➕ Extension | 💬 Problem in plain words |  |

### 🚀 How to use Phone Number Validator

Phone Number Validator works in a few clicks, no coding needed:

1. [Create a free Apify account](https://console.apify.com/sign-up) (the free plan includes 5 USD of monthly credit).
2. Open [Phone Number Validator](https://apify.com/bepolabs/phone-validator) and click **Try for free**.
3. Paste your phone numbers and, for those written without +, pick the default country.
4. Click **Start** and wait for the run to finish (most runs take seconds).
5. Download your data as JSON, CSV, Excel, XML or HTML, or send it straight to Google Sheets, Make, Zapier or your AI agent.

![How Phone Number Validator works](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/phone-validator-workflow.png)

### ⬇️ Input

Give `phoneNumbers` in any common format. Numbers with `+` or an international prefix keep their own country; the rest are read with `defaultCountry`.

##### Mixed countries

One run can hold numbers from many places: `defaultCountry` applies only to those written without `+`, `00` or `011`.

##### Only valid numbers

`onlyValid` saves and charges only valid numbers; off by default, so every number gets a row with the reason it failed.

##### Duplicates

The same number written twice is checked once; up to 100,000 numbers per run.

| Field | Type | What it does | Default |
|---|---|---|---|
| **Phone numbers** (`phoneNumbers`) | array | Numbers in any common format: +1 202-456-1111, (030) 1234567, 0044 20 7946 0958, with or without an extension. | `["+1 202-456-1111","+44 20 7946 0958","0` |
| **Default country** (`defaultCountry`) | string | Two-letter country code (US, GB, DE ...) used for numbers written without + and country code. | `"DE"` |
| **Only valid numbers** (`onlyValid`) | boolean | Off: every number gets a row with its status and the reason when it fails. | `false` |

![Phone Number Validator input form](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/phone-validator-input.png)

#### Input example

```json
{
    "phoneNumbers": [
        "+1 202-456-1111",
        "+44 20 7946 0958",
        "+49 30 1234567",
        "+33 1 42 68 53 00",
        "+81 3-3224-9999",
        "+61 2 9374 4000"
    ]
}
```

### ⬆️ Output

Every number becomes one row with its status, the formats and the line type. `status` is `valid` (the number lies in an assigned block), `possible` (plausible size, nothing allocated: often a typo), `invalid` (impossible length for its country) or `unparseable` (origin not found, or not a phone number).

![Phone Number Validator output table](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/phone-validator-output.png)

#### Output example

One row of the dataset (a real run of 2026-10-17):

```json
{
    "input": "+1 202-456-1111",
    "status": "valid",
    "valid": true,
    "possible": true,
    "e164": "+12024561111",
    "international": "+1 202 456 1111",
    "national": "(202) 456-1111",
    "country": "US",
    "countryName": "United States",
    "callingCode": "+1",
    "type": "fixed-line-or-mobile",
    "extension": null,
    "problem": null
}
```

View the results as a table or JSON in the Output tab and download them as JSON, CSV, Excel, XML, HTML or RSS, all fields or only those you pick.

### 💰 How much does Phone Number Validator cost?

Phone Number Validator is priced **per event**: **1 USD per 1,000 numbers checked** (0.001 USD each), with no monthly rental. Each number in the dataset is billed once, no start fee. With `onlyValid` on, entries left out are free.

| You get | You pay |
|---|---|
| 100 numbers checked | 0.1 USD |
| 1,000 numbers checked | 1 USD |
| 10,000 numbers checked | 10 USD |
| 100,000 numbers checked | 100 USD |

💡 Apify's free plan gives you 5 USD of credit every month, enough for about **5,000 numbers checked** at no cost. Set a spending limit per run and the Actor stops there.

### ⚖️ Phone Number Validator vs. the alternatives

| | Phone Number Validator | Paid lookup APIs | Spreadsheet formulas |
|---|---|---|---|
| **Every country's numbering plan** | ✅ | ✅ | ❌ |
| **Line type (mobile, landline, VoIP)** | ✅ | ✅ | ❌ |
| **Numbers stay private** | ✅ | ❌ | ✅ |
| **Price per 1,000 numbers** | 1 USD | 5 to 10 USD | free, but manual |
| **Live carrier or HLR check** | ❌ | often | ❌ |

### 🔌 Integrations, API and MCP

#### Connect Phone Number Validator to your AI agent (MCP)

Give Claude, ChatGPT, Cursor or any MCP client direct access to Phone Number Validator through the [Apify MCP server](https://mcp.apify.com). Add this URL to its settings:

```text
https://mcp.apify.com/?actors=bepolabs/phone-validator
```

For Claude Desktop, add it under `mcpServers` in `claude_desktop_config.json`:

```json
{
    "mcpServers": {
        "phone-validator": {
            "command": "npx",
            "args": [
                "-y",
                "@apify/actors-mcp-server",
                "--actors",
                "bepolabs/phone-validator"
            ],
            "env": {
                "APIFY_TOKEN": "<your Apify API token>"
            }
        }
    }
}
```

Then ask: *"Validate these 50 phone numbers, give me each one in E.164 format and tell me which are mobile."*

#### Run it from your code

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("bepolabs/phone-validator").call(run_input={"phoneNumbers":["+1 202-456-1111","+44 20 7946 0958","+49 30 1234567","+33 1 42 68 53 00","+81 3-3224-9999","+61 2 9374 4000"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

JavaScript (`npm install apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('bepolabs/phone-validator').call({"phoneNumbers":["+1 202-456-1111","+44 20 7946 0958","+49 30 1234567","+33 1 42 68 53 00","+81 3-3224-9999","+61 2 9374 4000"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### No-code integrations

Send results to **Google Sheets, Slack, Airtable, HubSpot, Make, Zapier, n8n** and more from the Integrations tab, start runs on a **schedule**, or trigger your own endpoint with a **webhook** when a run finishes. The [Apify API](https://docs.apify.com/api/v2) gives you full control over runs and datasets.

### ❓ FAQ

##### Does it check whether a number is switched on?

No. It tells you whether a number **can** exist and what kind of line its block is for. It does not call the number, ask a carrier or check WhatsApp, so it cannot say who owns a valid number, and a number ported from mobile to VoIP keeps its original type.

##### Why is my local number `unparseable`?

Without `+` and country code the number needs `defaultCountry`. The run log warns when most numbers miss it.

##### Can it check numbers from many countries at once?

Yes. Numbers with `+` or an international prefix are read with their own country; `defaultCountry` applies only to the rest.

##### Why is a UK mobile shown as Guernsey (`GG`) or Jersey (`JE`)?

The Channel Islands and the Isle of Man share the UK's +44 code and own some of its ranges; libphonenumber names the territory that owns the range.

##### Why is a US number `fixed-line-or-mobile`?

The US, Canada and some other countries do not separate mobile and landline ranges in their numbering plan, so no offline check can tell them apart.

##### Is it legal to use Phone Number Validator?

Validation runs offline on public numbering-plan data (libphonenumber by Google, Apache-2.0, through the MIT-licensed libphonenumber-js); no number is called or looked up. Phone numbers are personal data: you are responsible for having a lawful basis to process what you give it and for following GDPR, CCPA and anti-spam rules when you contact people.

##### What if something is missing or does not work?

Open an issue on the **Issues** tab; we read each one and reply. Feature requests are welcome too.

### 💬 Your feedback

Tell us what Phone Number Validator should add on the **Issues** tab or leave a review; your notes decide what we work on next.

### 🔗 Related Actors

| Actor | What it does |
|---|---|
| 📧 [Email Verifier](https://apify.com/bepolabs/email-dns-check) | Bulk email validation over DNS: valid, risky or invalid per address, with the reasons, a score, a typo fix, throwaway and shared-inbox flags. |
| 📊 [Google Sheets Import and Export](https://apify.com/bepolabs/google-sheets) | Send any Apify dataset or JSON to a Google Sheet (append, replace or upsert by key), or read a sheet back as clean rows. |
| 📇 [Website Contacts](https://apify.com/bepolabs/website-contacts) | Company websites to emails, phone numbers and social profiles, one row per site, with a status that says why nothing was found. |
| 🏛️ [SAM.gov Contract Opportunities](https://apify.com/bepolabs/sam-gov) | US federal contract opportunities by keyword, NAICS, set-aside or agency, with deadlines, contacts and attachments. |
| 🏛️ [UK Tenders](https://apify.com/bepolabs/uk-tenders) | UK public contracts from Contracts Finder and Find a Tender by keyword, CPV, value, region and deadline, with daily alerts. |
| 💼 [ATS Jobs](https://apify.com/bepolabs/ats-jobs) | Every open job from company career boards on Greenhouse, Lever, Ashby, Workable, SmartRecruiters and Recruitee in one deduped feed. |
| 🌐 [Domain RDAP and DNS](https://apify.com/bepolabs/domain-rdap) | Domains to registrar, creation and expiry dates, age, status, nameservers, DNSSEC and DNS records from official RDAP, in bulk. |
| 🩺 [NPI Registry Lookup](https://apify.com/bepolabs/npi-registry) | US doctors, nurses, clinics and pharmacies from the official CMS NPI Registry, by specialty, name, NPI or place. |

# Changelog

This Actor's version history is a separate document: https://apify.com/bepolabs/phone-validator/changelog.md

# Actor input Schema

## `phoneNumbers` (type: `array`):

Numbers in any common format: +1 202-456-1111, (030) 1234567, 0044 20 7946 0958, with or without an extension. Numbers without + need a default country. Up to 100,000 per run; duplicates are checked once.

## `defaultCountry` (type: `string`):

Two-letter country code (US, GB, DE ...) used for numbers written without + and country code. Numbers with + keep their own country.

## `onlyValid` (type: `boolean`):

Off: every number gets a row with its status and the reason when it fails. On: only valid numbers are saved and charged.

## Actor input object example

```json
{
  "phoneNumbers": [
    "+1 202-456-1111",
    "+44 20 7946 0958",
    "030 1234567"
  ],
  "defaultCountry": "DE",
  "onlyValid": false
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items, one row per result, in the overview table view.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "phoneNumbers": [
        "+1 202-456-1111",
        "+44 20 7946 0958",
        "030 1234567"
    ],
    "defaultCountry": "DE"
};

// Run the Actor and wait for it to finish
const run = await client.actor("bepolabs/phone-validator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "phoneNumbers": [
        "+1 202-456-1111",
        "+44 20 7946 0958",
        "030 1234567",
    ],
    "defaultCountry": "DE",
}

# Run the Actor and wait for it to finish
run = client.actor("bepolabs/phone-validator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "phoneNumbers": [
    "+1 202-456-1111",
    "+44 20 7946 0958",
    "030 1234567"
  ],
  "defaultCountry": "DE"
}' |
apify call bepolabs/phone-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bepolabs/phone-validator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/nWeQKeIMJVlYX8TL0/builds/dbCuF1gDir79LZsUG/openapi.json
