# Business Reverse Phone Lookup Scraper (`automation-lab/business-reverse-phone-lookup`) Actor

Resolve public business phone numbers to names, confidence scores, and cited source evidence for CRM enrichment and verification.

- **URL**: https://apify.com/automation-lab/business-reverse-phone-lookup.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Business Reverse Phone Lookup Scraper

Resolve supplied telephone numbers to public business identities with the web-index evidence behind every match. This **business reverse phone lookup** Actor is designed for CRM enrichment, lead verification, and repeatable data-quality workflows—not personal subscriber identification.

The Actor searches an anonymously reachable public web-index surface, accepts only candidates whose indexed title or snippet contains the phone digits, ranks the evidence, and writes one typed result per processed input.

### What does Business Reverse Phone Lookup Scraper do?

For each phone number, the Actor:

1. validates and normalizes the number;
2. searches for the exact public number;
3. filters out results that do not contain the number in their evidence;
4. scores matching candidates;
5. exports the best supported business identity and source citation;
6. retains additional ranked candidates for review.

A result is evidence of a public association, not proof of legal ownership or current control of the number.

### Who is it for

- **CRM operations teams** enriching company records that contain telephone numbers but no business name.
- **Sales operations teams** checking imported business-phone lists before routing leads.
- **Data-quality teams** preserving a source URL and snippet for every automated match.
- **Developers** adding a bounded reverse-number lookup step to an Apify Task, webhook, or data pipeline.
- **Analysts** auditing a small list of known public company numbers.

This Actor is not intended for identifying private individuals, skip tracing, emergency use, or making regulated eligibility decisions.

### Why use evidence-backed phone matching?

A name without a citation is difficult to audit. Every positive result includes the indexed title, snippet, URL, confidence score, and the candidate list used for the decision. Unmatched inputs still produce a `not_found` row, so bulk jobs preserve input-to-output alignment.

The implementation does not claim a match merely because a search result is top-ranked. The supplied phone digits must appear in the indexed evidence itself.

### What data can you extract?

| Field | Meaning |
| --- | --- |
| `inputPhone` | Phone number exactly as supplied |
| `normalizedPhone` | Number normalized to international `+` form |
| `lookupStatus` | `matched`, `possible_match`, `not_found`, or `error` |
| `confidence` | Evidence score from 0 to 1; not an ownership guarantee |
| `businessName` | Business name parsed from the strongest cited result |
| `address` | Street address only when present in indexed evidence |
| `website` | Website only when explicitly labeled in indexed evidence |
| `category` | Category only when explicitly labeled in indexed evidence |
| `sourceUrl` | URL of the strongest result |
| `sourceTitle` | Indexed title retained as evidence |
| `sourceSnippet` | Indexed snippet retained as evidence |
| `candidates` | Ranked matching source candidates |
| `searchedAt` | ISO 8601 lookup timestamp |
| `errorMessage` | Upstream failure summary for an `error` row |

Optional business fields are `null` when the cited evidence does not support them. The Actor does not infer missing addresses, websites, or categories.

### How to find a business with a telephone number

1. Open the Actor input page.
2. Add one or more numbers to **Business phone numbers**.
3. Include the international calling code when possible.
4. Set **Maximum phone numbers** to bound the run.
5. Choose how many evidence candidates to retain.
6. Start the Actor and open the **Business phone matches** dataset view.
7. Filter on `lookupStatus` and review `sourceUrl` for important decisions.

Small inputs are useful for manual verification. Scheduled Tasks can process recurring CRM batches of up to 1,000 supplied numbers per run.

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `phoneNumbers` | string array | `['408-996-1010']` | Required list of 1–1,000 telephone numbers |
| `defaultCountryCode` | string | `+1` | Calling code added to national-format numbers |
| `maxItems` | integer | `100` | Maximum supplied numbers processed, from 1 to 1,000 |
| `maxCandidatesPerPhone` | integer | `3` | Matching evidence candidates retained per row, from 1 to 10 |

Example input:

```json
{
  "phoneNumbers": [
    "408-996-1010",
    "650-253-0000",
    "425-882-8080"
  ],
  "defaultCountryCode": "+1",
  "maxItems": 3,
  "maxCandidatesPerPhone": 3
}
```

National numbers are normalized with `defaultCountryCode`. For non-US numbers, provide the international calling code and use a format commonly indexed on the public web.

### Example output

A real lookup for Apple's public business number produces a record shaped like this:

```json
{
  "inputPhone": "408-996-1010",
  "normalizedPhone": "+14089961010",
  "lookupStatus": "matched",
  "confidence": 0.94,
  "businessName": "APPLE INC",
  "address": null,
  "website": null,
  "category": null,
  "sourceUrl": "https://npnr.org/408/996/1010",
  "sourceTitle": "408-996-1010 | APPLE INC",
  "sourceSnippet": "Phone number 408-996-1010 is used by APPLE INC located in CUPERTINO, CA...",
  "candidates": [
    {
      "title": "408-996-1010 | APPLE INC",
      "url": "https://npnr.org/408/996/1010",
      "snippet": "Phone number 408-996-1010 is used by APPLE INC located in CUPERTINO, CA...",
      "confidence": 0.94
    }
  ],
  "searchedAt": "2026-08-17T06:35:00.000Z"
}
```

Search indexes change, so the exact source, title, snippet, and confidence can differ on a later run.

### Understanding lookup status and confidence

- `matched`: the best exact-number evidence scored at least 0.75.
- `possible_match`: exact-number evidence exists, but the surrounding business signals are weaker.
- `not_found`: no indexed candidate contained the supplied phone digits.
- `error`: the public search route failed for that input; error rows are not charged as items.

Confidence rewards exact title matches, business language, and direct business sites. It is a deterministic evidence score, not a probability or identity guarantee.

### How much does it cost to look up business phone numbers?

The Actor uses pay-per-event pricing:

- one `start` event when a valid run begins;
- one `item` event for each successfully processed output row;
- no item event for a lookup that ends in an upstream `error`.

The Apify Console displays the active tier for your plan and the exact estimated charge before a run. Larger plan tiers receive lower per-item rates. Runtime and platform usage are included in the Actor charge rather than billed as a separate dataset fee.

For a cost estimate, multiply the displayed `item` rate by the number of processed phones and add the displayed one-time start fee. `maxItems` is the easiest way to cap a batch.

### Bulk CRM enrichment workflow

A practical recurring workflow is:

1. export company phone numbers from your CRM;
2. pass a batch to an Apify Task;
3. schedule the Task daily or weekly;
4. send the dataset to Google Sheets, Make, Zapier, or a webhook;
5. accept `matched` rows automatically only when your policy permits;
6. route `possible_match`, `not_found`, and changed citations for review;
7. retain `sourceUrl`, `sourceSnippet`, and `searchedAt` for auditability.

The Actor emits one row per successfully processed input, which makes joins back to the source file straightforward through `inputPhone`.

### API usage with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~business-reverse-phone-lookup/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumbers": ["408-996-1010", "650-253-0000"],
    "defaultCountryCode": "+1",
    "maxItems": 2
  }'
```

Keep API tokens in environment variables or a secret manager. Do not commit them to source control.

### API usage with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/business-reverse-phone-lookup').call({
  phoneNumbers: ['408-996-1010', '650-253-0000'],
  defaultCountryCode: '+1',
  maxItems: 2,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/business-reverse-phone-lookup').call(run_input={
    'phoneNumbers': ['408-996-1010', '650-253-0000'],
    'defaultCountryCode': '+1',
    'maxItems': 2,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/business-reverse-phone-lookup"
```

#### Claude Desktop, Cursor, and VS Code setup

Claude Desktop, Cursor, and VS Code can use this MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/business-reverse-phone-lookup"
    }
  }
}
```

Example prompts:

- “Look up these three public company phone numbers and return names plus evidence URLs.”
- “Run a business reverse number lookup for this CRM export and separate possible matches.”
- “Show only matched rows with confidence of at least 0.75, but retain their source snippets.”

### Integrations and exports

Dataset output can be downloaded as JSON, CSV, Excel, XML, or RSS. It can also flow to:

- Apify webhooks;
- Google Sheets;
- Make and Zapier;
- cloud storage or a data warehouse;
- a CRM import job;
- a human-review queue.

Use `normalizedPhone` as a normalized join key and retain `inputPhone` to trace the original row.

### Limitations

- Results depend on current public search-index evidence; coverage is not guaranteed.
- A public association can be stale, reassigned, duplicated, or incorrect.
- Personal subscriber identity is intentionally not returned.
- Address, website, and category remain null unless directly evidenced.
- Formatting varies internationally; including a calling code improves normalization.
- The Actor supports at most 1,000 supplied numbers in one run.
- The selected route is direct HTTP only; no automatic residential-proxy or browser fallback is enabled.
- Temporary search failures produce `error` rows. If all lookups fail, the run fails rather than silently succeeding.

For business-critical use, verify the cited source and combine the result with another authoritative business record.

### Responsible and legal use

Use only telephone numbers you are authorized to process. Follow privacy, marketing, telecommunications, consumer-protection, and data-retention laws that apply to your jurisdiction and purpose.

Do not use output to harass people, identify private individuals, make eligibility decisions, bypass consent requirements, or represent an indexed association as verified legal ownership. The user is responsible for the lawful basis, downstream decisions, and retention of the data.

### Troubleshooting

**Why did I receive `not_found`?**\
The number may not be publicly indexed, may use a different format, or may no longer be associated with a business. Include an international calling code and check the number for transcription errors.

**Why is `businessName` null even though a source exists?**\
The evidence contained the number but did not expose a safely parseable business name. Review `sourceTitle`, `sourceSnippet`, and `candidates`.

**Why did the run fail?**\
Malformed inputs fail before lookup. A run also fails when every selected lookup encounters an upstream search error. Check the log and retry later rather than treating an empty response as a valid result.

**Can I increase throughput?**\
Set `maxItems` up to 1,000. For recurring large lists, use scheduled bounded batches instead of overlapping runs.

### Related Automation Lab Actors

- [Phone Number Validator](https://apify.com/automation-lab/phone-number-validator) — validate and classify number syntax before enrichment.
- [Website Phone Number Contact Finder](https://apify.com/automation-lab/website-phone-number-contact-finder) — discover public phone contacts starting from a website.
- [Website Email Extractor](https://apify.com/automation-lab/website-email-extractor) — enrich company sites with displayed email evidence.
- [Business Address Scraper](https://apify.com/automation-lab/business-address-scraper) — extract physical addresses from supplied company websites.

### FAQ

**Does this Actor identify private callers?**\
No. It is scoped to public business associations supported by cited web-index evidence.

**Is a `matched` row guaranteed to be current?**\
No. `matched` describes the strength of indexed evidence, not current ownership. Review the source for consequential decisions.

**Are unmatched inputs charged as items?**\
A successfully processed `not_found` row is an item because the lookup work completed. Upstream `error` rows are not charged as items.

**Can I search by business name instead?**\
No. The supported input route starts from supplied telephone numbers.

**Can I monitor changes?**\
Schedule the same Apify Task and compare `lookupStatus`, `businessName`, `sourceUrl`, or `sourceSnippet` in your downstream workflow. The Actor itself does not maintain a historical database or send change alerts.

**What is the maximum batch size?**\
Up to 1,000 supplied numbers per run, further bounded by `maxItems`.

# Actor input Schema

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

Phone numbers to look up. Include a country calling code for the most reliable normalization.

## `defaultCountryCode` (type: `string`):

Calling code added to national-format numbers, such as +1 for the United States and Canada.

## `maxItems` (type: `integer`):

Maximum number of supplied phone numbers to process in this run.

## `maxCandidatesPerPhone` (type: `integer`):

Maximum cited search-result candidates retained in each output record.

## Actor input object example

```json
{
  "phoneNumbers": [
    "408-996-1010",
    "650-253-0000"
  ],
  "defaultCountryCode": "+1",
  "maxItems": 2,
  "maxCandidatesPerPhone": 3
}
```

# Actor output Schema

## `overview` (type: `string`):

Open the default dataset overview with normalized inputs, lookup status, business identity, confidence, and cited source evidence.

# 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": [
        "408-996-1010",
        "650-253-0000"
    ],
    "defaultCountryCode": "+1",
    "maxItems": 2,
    "maxCandidatesPerPhone": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/business-reverse-phone-lookup").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": [
        "408-996-1010",
        "650-253-0000",
    ],
    "defaultCountryCode": "+1",
    "maxItems": 2,
    "maxCandidatesPerPhone": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/business-reverse-phone-lookup").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": [
    "408-996-1010",
    "650-253-0000"
  ],
  "defaultCountryCode": "+1",
  "maxItems": 2,
  "maxCandidatesPerPhone": 3
}' |
apify call automation-lab/business-reverse-phone-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/business-reverse-phone-lookup"
        }
    }
}

```

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/evMGwjneZba5YnTCj/builds/2x3LtDDj9vHLiPh7c/openapi.json
