Validate Phone Numbers in Bulk (Apify Actor)
Validate phone numbers in bulk for $0.50 per 1,000: valid or not, E.164, line type, country, region and time zone per number. Unparseable rows free. Offline libphonenumber, no API key. Runs as an Apify Actor, callable from MCP clients via the Apify MCP server (https://mcp.apify.com/?actors=pennydata/phone-number-validator-offline).
Hosted MCP Server
npx add-mcp 'https://mcp.apify.com/?actors=pennydata/phone-number-validator-offline'Installs into Claude Code, Codex, Cursor and more
Documentation
Phone Number Validator & Formatter: E.164 by Country, Offline (pennydata/phone-number-validator-offline) Actor
Paste phone numbers, get valid/invalid, E.164, national format, country, line type and time zone per row. $0.0005 per number, unparseable rows free. Prefilled input: +1 415-555-2671 -> +14155552671, US, FIXED_LINE_OR_MOBILE. Offline libphonenumber, no API key. Click Start.
- URL: https://apify.com/pennydata/phone-number-validator-offline.md
- Developed by: Penny Data (community)
- Categories: Lead generation, Developer tools, Agents
- Stats: 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- User rating: No ratings yet
Pricing
from $0.35 / 1,000 phone number validateds
This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events. Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.
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 section below.
Each client library has reference documentation the quickstart does not restate: JavaScript/TypeScript (npm install apify-client) and Python (pip install apify-client).
README
Validate Phone Numbers in Bulk: E.164, Line Type - $0.50 per 1,000
Paste phone numbers, get E.164, valid or not, line type, country and region for each. $0.50 per 1,000 numbers, first 3 per run free, unparseable rows free. Click Start: the prefilled 5 numbers run as is. Output below is a real local run of the prefilled input (about 2 s, fictional 555 numbers).
| input | e164 | valid | type | country | geoLocation | carrier |
|---|---|---|---|---|---|---|
| +1 415-555-2671 | +14155552671 | true | FIXED_LINE_OR_MOBILE | US | San Francisco, CA | null |
| +44 20 7946 0958 | +442079460958 | true | FIXED_LINE | GB | London | null |
| +91 98765 43210 | +919876543210 | true | MOBILE | IN | null | Airtel |
| (212) 555-0100 | +12125550100 | true | FIXED_LINE_OR_MOBILE | US | New York, NY | null |
| not a number | null | false | null | null | null | null |
Try it in Apify Console: the input form opens already filled with a demo input (below), so you can click Start with no setup. A new Apify account includes free monthly credit.
Demo input:
{"phones":["+1 415-555-2671","+44 20 7946 0958","+91 98765 43210","(212) 555-0100","not a number"],"defaultRegion":"US"}
First 3 numbers per run are free (was 25 before 2026-10-25); after that $0.50 per 1,000. Offline libphonenumber, no API key. Enrichment: country, region, timezone, line type.
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.
Drop-in compatible with pink_comic/phone-number-validation input (phoneNumbers, defaultRegion, maxResults, includeCarrier, includeGeocoding, includeTimezone).
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; also carrier, region and time zones (offline, on by default).
Paste phone numbers in any format, get back E.164, validity, line type and country. 1,000 numbers = $0.50.
| input | e164 | valid | type | country | geoLocation |
|---|---|---|---|---|---|
| +1 202-555-0143 | +12025550143 | true | FIXED_LINE_OR_MOBILE | US | Washington D.C. |
| +44 20 7946 0958 | +442079460958 | true | FIXED_LINE | GB | London |
| +49 30 123456 | +4930123456 | true | FIXED_LINE | DE | Berlin |
| (415) 555-2671 | +14155552671 | true | FIXED_LINE_OR_MOBILE | US | San Francisco, CA |
| 12345 | +112345 | false | null | US | null |
Try the sample dataset: the full JSON of these 5 rows, a real run of this actor (public, no login).
Offline format check (libphonenumber): no carrier lookup, no API key. Unparseable rows are free. Rows above are real output of this actor with defaultRegion US (fictional 555 numbers).
Pairs with Bulk Email Validator (no SMTP) for lead-list hygiene.
Features
- Per-row status and run summary: every output row has
rowStatus(ok,invalidorerror) androwReason, and each run saves aRUN_SUMMARYrecord 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 link)
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
- Run a Google Maps scraper (for example
compass/crawler-google-places) and copy the dataset ID of the run (Storage tab). - Paste it into
inputDatasetId. The actor readsphoneUnformatted,internationalPhoneNumberorphonefrom each place (first one present) and validates it. SetdefaultRegionto the scrape's country for numbers without a+. - Each result row keeps the place's
title,placeId,websiteandaddresswhen 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.
Telefonnummern validieren - Español, Deutsch, Português
Español: validar números de teléfono masivo (formato E.164)
Valida y normaliza una lista de teléfonos al formato E.164, con país y tipo de línea (móvil, fijo, VoIP), sin clave de API y sin conexión a servicios externos (libphonenumber). Entrada de ejemplo: { "phones": ["(415) 555-2671", "+34 612 34 56 78"], "defaultRegion": "ES" }. Coste: $0,50 por 1.000 números analizables; los primeros 25 de cada ejecución y las filas no analizables son gratis. Solo comprueba el formato y el plan de numeración: no confirma que el número esté activo.
Deutsch: Telefonnummern prüfen und in E.164 umwandeln (Liste, Massenprüfung)
Prüft eine Liste von Telefonnummern auf Gültigkeit, wandelt sie ins E.164-Format um und liefert Land und Leitungstyp (Mobil, Festnetz, VoIP) - ohne API-Schlüssel, offline mit libphonenumber. Beispiel-Eingabe: { "phones": ["030 123456", "+49 151 23456789"], "defaultRegion": "DE" }. Kosten: $0,50 pro 1.000 auswertbare Nummern; die ersten 25 je Lauf und nicht lesbare Einträge sind kostenlos. Geprüft werden nur Format und Nummernplan, nicht ob die Nummer erreichbar ist.
Português: validar números de telefone em massa (formato E.164)
Valida uma lista de telefones, converte para E.164 e devolve país e tipo de linha (celular, fixo, VoIP), sem chave de API, offline com libphonenumber. Exemplo de entrada: { "phones": ["(11) 91234-5678", "+55 21 2345-6789"], "defaultRegion": "BR" }. Custo: US$ 0,50 por 1.000 números analisáveis; os primeiros 25 por execução e as linhas não analisáveis não são cobrados. Verifica apenas formato e plano de numeração, não se o número está ativo.
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 (includeGeoCarrier, on by default).
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.
| Event | Price | When 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 input | Free | Returned 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.
validmeans 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 (on by default;
includeGeoCarrierfalse drops them); where an area spans several zones all are returned. - Numbers without a
+prefix usedefaultRegion; 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
A khadinakbar/phone-number-lookup-api input (phoneNumbers, defaultCountry, maxConcurrency, maxCostUsd, requireCarrier, include* flags) runs here verbatim, at $0.0005 per number instead of $0.025. Offline only: no WhatsApp, Telegram or reverse lookup.
Paste the input you already use and change only the actor ID. These keys are accepted as aliases:
| Other validator's input | Used here as |
|---|---|
phoneNumbers, numbers, phone, phoneNumbersText (list, text or {phone} objects) | phones |
defaultCountry, defaultCountryCode, country | defaultRegion |
maxResults | cap on numbers processed |
maxCostUsd | stop charging after floor(maxCostUsd / 0.0005) numbers; 0 = no cap |
requireCarrier | only rows with an offline carrier name are returned (others dropped, not charged) |
includeReverseLookupUrls, includeWhatsAppCheck, includeTelegramCheck | accepted and ignored: this actor is offline validation only, with no reverse lookup, WhatsApp or Telegram check |
includeCarrier, includeGeocoding, includeTimezone, formats, maxConcurrency | accepted 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.
Use from Claude, Cursor or any MCP client
Apify's MCP server can expose this actor as a tool. Use this URL (format from the Apify MCP docs, ?tools= takes a comma-separated list of actors):
https://mcp.apify.com/?tools=pennydata/phone-number-validator-offline
Client config (mcpServers format; sign in with OAuth when the client asks):
{"mcpServers": {"apify": {
"url": "https://mcp.apify.com/?tools=pennydata/phone-number-validator-offline"
}}}
Example prompt: "Validate these phone numbers with default region GB and give me E.164 and line type: 020 7946 0958, 07911 123456."
Pair with: Website Contact Extractor (step 1 extract, step 2 validate)
- Extract: run Website Contact Extractor on your list of company websites. Each output row has a
phonesarray (public business contact data only). - Validate: copy those
phonesvalues intophoneshere and setdefaultRegionto the sites' country for numbers without a+. You get E.164, validity and line type per number.
Each step is a separate run billed at its own pay-per-event price.
Related actors
Other small pay-per-event Actors from the same publisher:
- Bulk Email Validator (No SMTP): validate the email column of the same lead list.
- Website Contact Extractor: pulls phone numbers from websites so you can validate them here.
- Shopify Store Leads & Contacts: store contact data to run through the validator.
Phone number lookup (carrier, line type, time zone, region)
Use this actor as an offline phone number lookup. Every valid number comes back with these fields. No API key and no third-party site calls (libphonenumber metadata, Apache-2.0):
| Field | Meaning |
|---|---|
lineType (also type) | MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, TOLL_FREE, VOIP, ... or null |
carrier | original mobile carrier from the numbering-plan allocation, null where the metadata has none |
timeZones | list of IANA time zones, e.g. ["America/New_York"] |
geoLocation | city or region text, e.g. "New York, NY" or "London" |
country, callingCode | ISO country and calling code |
e164, nationalFormat, internationalFormat | the three formats |
Limits: carrier is the original allocation and ignores number porting; this is not an owner lookup and not a live-line check. Set includeGeoCarrier to false to drop carrier, geoLocation and timeZones. Pricing is unchanged.
Actor input Schema
phones (type: array):
List of phone numbers to validate, in any common format. Numbers without a '+' prefix use the default region. Optional: if you leave it at the sample list and set phoneNumbers, numbers, phone or phoneNumbersText instead, that field is used.
inputDatasetId (type: string):
Validate phones from another run's dataset (ID or name), e.g. a Google Maps Scraper (compass/crawler-google-places) run. Fields phoneUnformatted, internationalPhoneNumber and phone are detected automatically and title, placeId, website, address are copied onto each result row. When set, the sample list is ignored.
phoneField (type: string):
Only needed if your dataset uses another column name. Leave empty to auto-detect phoneUnformatted, internationalPhoneNumber, phone.
defaultRegion (type: string):
Two-letter country code (e.g. US, GB, DE) used to interpret numbers written without an international '+' prefix. Leave empty to require the '+' prefix on every number.
phoneNumbersText (type: string):
Alternative to the list above: paste numbers separated by new lines, commas or semicolons. Used when set; takes precedence over the sample list.
defaultCountry (type: string):
Same as Default region; accepted so inputs saved for other validators work. Default region wins when changed from US.
onlyValid (type: boolean):
When on, invalid and unparseable numbers are left out of the output and not charged. Only numbers that pass validation are returned.
sampleOnly (type: boolean):
When on, only the first 10 numbers are processed and no pay-per-event charge is made. Use it to try the output format at no cost.
phoneNumbers (type: array):
Same as Phone numbers; accepted so an input saved for another phone validator runs unchanged. Strings or {phone|number} objects.
numbers (type: array):
Same as Phone numbers (alias).
country (type: string):
Same as Default region; accepted for inputs saved for other validators.
defaultCountryCode (type: string):
Same as Default region; accepted for inputs saved for other validators.
maxResults (type: integer):
Process at most this many numbers from the list. 0 or empty means all.
includeCarrier (type: boolean):
Accepted for compatibility with other validators; this actor is offline and does not return this field, so the flag is ignored.
includeGeocoding (type: boolean):
Accepted for compatibility with other validators; this actor is offline and does not return this field, so the flag is ignored.
includeTimezone (type: boolean):
Accepted for compatibility with other validators; this actor is offline and does not return this field, so the flag is ignored.
formats (type: array):
Accepted for compatibility; every row always includes E.164, national and international formats.
maxConcurrency (type: integer):
Accepted for compatibility; ignored.
includeGeoCarrier (type: boolean):
When on, valid numbers get a carrier name (original mobile carrier, from libphonenumber metadata) and a geoLocation text (city or region) and timeZones (IANA names). Offline lookup, so carrier reflects the original allocation and ignores number porting. On by default (no extra charge); turn off to drop carrier, geoLocation and timeZones from the rows.
sheetUrl (type: string):
Link to a Google Sheet shared as 'Anyone with the link can view' (docs.google.com/spreadsheets/d//edit#gid=0) or a CSV URL. Numbers from the phone column are added to Phone numbers.
sheetColumn (type: string):
Header of the column with phone numbers. Default: first header containing phone, mobile or tel, else the first column.
maxCostUsd (type: number):
Same as maxCostUsd on khadinakbar/phone-number-lookup-api. Stops charging after floor(maxCostUsd / 0.0005) numbers at this actor's price of $0.0005 each. 0 or empty means no cap.
requireCarrier (type: boolean):
Only return numbers that have an offline carrier name; the rest are left out and not charged. Carrier comes from libphonenumber metadata and ignores number porting.
includeReverseLookupUrls (type: boolean):
Accepted so a khadinakbar/phone-number-lookup-api input runs unchanged. This actor is offline libphonenumber validation only and does not do reverse-lookup URLs, so the flag is ignored.
includeWhatsAppCheck (type: boolean):
Accepted so a khadinakbar/phone-number-lookup-api input runs unchanged. This actor is offline libphonenumber validation only and does not do WhatsApp check, so the flag is ignored.
includeTelegramCheck (type: boolean):
Accepted so a khadinakbar/phone-number-lookup-api input runs unchanged. This actor is offline libphonenumber validation only and does not do Telegram check, so the flag is ignored.
Actor input object example
{
"phones": [
"+1 415-555-2671",
"+44 20 7946 0958",
"+91 98765 43210",
"(212) 555-0100",
"not a number"
],
"defaultRegion": "US",
"onlyValid": false,
"sampleOnly": false,
"includeGeoCarrier": true
}
Actor output Schema
runSummary (type: string):
No description
results (type: string):
No description
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
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 = {
"phones": [
"+1 415-555-2671",
"+44 20 7946 0958",
"+91 98765 43210",
"(212) 555-0100",
"not a number"
],
"defaultRegion": "US"
};
// Run the Actor and wait for it to finish
const run = await client.actor("pennydata/phone-number-validator-offline").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
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 = {
"phones": [
"+1 415-555-2671",
"+44 20 7946 0958",
"+91 98765 43210",
"(212) 555-0100",
"not a number",
],
"defaultRegion": "US",
}
# Run the Actor and wait for it to finish
run = client.actor("pennydata/phone-number-validator-offline").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
echo '{
"phones": [
"+1 415-555-2671",
"+44 20 7946 0958",
"+91 98765 43210",
"(212) 555-0100",
"not a number"
],
"defaultRegion": "US"
}' |
apify call pennydata/phone-number-validator-offline --silent --output-dataset
MCP server setup
{
"mcpServers": {
"apify": {
"type": "http",
"url": "https://mcp.apify.com/?tools=fetch-actor-details,pennydata/phone-number-validator-offline"
}
}
}
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/Q2ELhWJDRGnvJUwXa/builds/xzDGz7dAWUcE6nn2t/openapi.json