# LinkedIn Phone Number Finder - US Mobile Numbers by Profile (`memo23/linkedin-phone-number-finder`) Actor

Paste LinkedIn profile URLs, get the person's US phone numbers from public records, mobiles first. Each record is matched by name, city and employer; when several people fit, the row is free and says so. No LinkedIn login or cookies. You pay only for a match with a phone.

- **URL**: https://apify.com/memo23/linkedin-phone-number-finder.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Lead generation, Social media
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 phone matches

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

## LinkedIn Phone Number Finder - US Mobile Numbers by Profile

**Paste LinkedIn profile URLs. Get back each person's US phone numbers, mobiles first, from current public records.**

You pay **$0.04 for each profile returned with a phone**, plus a $0.005 start fee per run. When several people share the name and nothing tells them apart, the row is free and says so, because a stranger's number is worth less than no number. No LinkedIn login, no cookies, no API keys.

### Why Use This Scraper?

- **Matched to the person, not the name.** A US name search returns everyone called Chris Adams. A phone comes back only when one record fits: the public record names the same employer as LinkedIn, or exactly one person with that name lives in the LinkedIn state.
- **Live records, not a stale dump.** Numbers come from public people-search records refreshed this year, each with its line type (wireless or landline), carrier and when it was last reported.
- **Mobiles first.** `primaryPhone` is the active mobile when the record has one; landlines and older numbers follow in `phones`.
- **A row for every profile, with the reason.** `found`, `ambiguous` (and how many people fit), `not-found`, `not-us`, `no-name`. Only `found` is billed.
- **No LinkedIn account at risk.** Profiles are read the way a logged-out visitor sees them. You never hand over cookies or a session.

#### How often it finds a phone

Measured on 9 October 2026 over 45 US profiles found by searching LinkedIn for B2B titles (VP of Sales, Marketing Manager, Head of Engineering, Account Executive, HR Manager):

| Result | Profiles | You pay |
| --- | --- | --- |
| Phone found, employer named on the record (`confidence: high`) | 3 | $0.04 each |
| Phone found, only person with the name in that state (`confidence: medium`) | 8 | $0.04 each |
| Several people fit (`ambiguous`) | 20 | free |
| No record with this name near the LinkedIn location (`not-found`) | 9 | free |
| LinkedIn showed no usable name (`no-name`) | 5 | free |

11 of 45 (24%). A second sample the same day, 40 Ohio profiles found by searching for operations, product, finance and sales titles, returned 9 (22%): 1 high, 8 medium, 21 ambiguous, 5 not found, 5 with no usable name or outside the US.

Rare surnames and profiles that show a city find a phone most often; "John Smith, United States" almost never does, and that is deliberate.

### Overview

For sales, recruiting and growth teams who have a list of US people on LinkedIn and want to call them. For each profile URL the actor returns one dataset row: the person's name, title, employer and LinkedIn location, their phone numbers with line type, and how sure the match is.

Only people located in the US are searched. Profiles placed in another country come back as free `not-us` rows.

### Supported Inputs

| Input | Example | Supported |
| --- | --- | --- |
| Public profile URL | `https://www.linkedin.com/in/katemakowski/` | Yes |
| Country subdomain | `https://ca.linkedin.com/in/jane-doe-4b2a1c9` | Yes |
| URL with tracking parameters | `https://www.linkedin.com/in/jane-doe?trk=public_profile` | Yes |
| Company pages, posts, Sales Navigator lead URLs | `linkedin.com/company/...` | No, only `/in/` profiles |

```json
{
    "linkedinUrls": [
        "https://www.linkedin.com/in/katemakowski/",
        "https://www.linkedin.com/in/adamhcarr/"
    ],
    "minConfidence": "medium"
}
```

Paste a whole column into **Bulk paste**, one profile per line. Duplicates are removed.

#### Already scraping LinkedIn?

Profile scrapers return names, titles and work history, and some add an email, but none of them return a phone number. Export the `linkedinUrl` column from any LinkedIn profile, people-search or company-employees scraper and paste it here: the phones come back keyed by the same URL, so the two datasets join on one column.

### Input Configuration

| Field | Default | What it does |
| --- | --- | --- |
| `linkedinUrls` | | Profile URLs, one per entry |
| `linkedinUrlsText` | | Bulk paste, one URL per line |
| `minConfidence` | `medium` | `high` returns phones only when the public record names the LinkedIn employer. Location-only matches then come back as free `unconfirmed` rows without phones |
| `onlyFound` | `false` | Keep only the rows you pay for |
| `maxItems` | `1000` | Most profiles per run. Free Apify plans: 10 |
| `maxConcurrency` | `5` | LinkedIn profiles read in parallel |

### How It Works

1. Reads each public profile as a logged-out visitor: name, title, employer, location. When LinkedIn hides the page, the search engine's listing for that exact profile is used instead.
2. Looks the name up on US public people-search records around the LinkedIn location.
3. Keeps a record only when it is the single one that fits (see **Match rules**), then orders its numbers mobile first.

A batch of 25 new names takes a few minutes; names looked up recently come back in seconds.

#### Match rules

- `high`: exactly one record with a compatible name (Kate / Katherine, Steve / Stephen) lists the LinkedIn employer in its career history.
- `medium`: no record names the employer, but exactly one person with the name lives in the LinkedIn state. If that person lives in a different city, the name must also be the only one found anywhere.
- Anything else is `ambiguous` or `not-found`, and free.

### Output Sample

```json
{
    "inputIndex": 1,
    "linkedinUrl": "https://www.linkedin.com/in/jane-doe-example/",
    "status": "found",
    "fullName": "Jane Doe",
    "jobTitle": "Social and Digital Marketing Manager",
    "company": "Acme Example",
    "location": "Minneapolis, Minnesota, United States",
    "confidence": "high",
    "matchReason": "The record lists Acme Example as the employer.",
    "primaryPhone": "+16125550142",
    "primaryPhoneType": "Wireless",
    "phones": [
        { "number": "(612) 555-0142", "e164": "+16125550142", "type": "Wireless", "carrier": "Verizon Wireless", "lastReported": "Sep 2026" },
        { "number": "(612) 555-0187", "e164": "+16125550187", "type": "Landline", "carrier": "CenturyLink", "lastReported": "Sep 2021" }
    ],
    "phoneCount": 2,
    "candidates": 1,
    "billed": true
}
```

### Key Output Fields

| Field | Meaning |
| --- | --- |
| `status` | `found` (billed), `unconfirmed`, `no-phone`, `ambiguous`, `not-found`, `not-us`, `no-name`, `charge-limit`, `error` |
| `confidence` | `high` (employer on the record) or `medium` (only namesake in the state) |
| `matchReason` | One sentence on why the row matched, or why it did not |
| `primaryPhone` | The number to call first, E.164 |
| `phones` | Every active number on the record, mobiles first, with type, carrier and last-reported month |
| `candidates` | Records with a compatible name the search returned |
| `lookupQuery` | The name and place that were searched |

### FAQ

#### What exactly am I billed for?

One `phone-found` event, $0.04, for each profile returned with `status: found`, and a $0.005 start fee per run (per GB of memory). Every other row is free.

#### Why is a row ambiguous when the name looks unique?

The record search covers the whole US. If two people with a compatible name fit the LinkedIn state and no record names the employer, the actor will not pick one for you. `candidates` says how many there were.

#### Does it work outside the US?

No. Only US public records are searched.

#### Do I need a LinkedIn account?

No. Nothing is sent to LinkedIn under your name.

### Disclaimer

This actor returns publicly available records for business contact. It is not a consumer reporting agency, and its output must not be used for any purpose covered by the US Fair Credit Reporting Act (FCRA), such as decisions about employment, credit, insurance or housing. Calling or texting the numbers is subject to the TCPA, state telemarketing laws and the national Do Not Call registry; checking your list against them is your responsibility.

# Actor input Schema

## `linkedinUrls` (type: `array`):

Public linkedin.com/in/... profile links, one per entry. Each profile is read as a logged-out visitor (name, employer, location) and the person is looked up on US public records around that location. No LinkedIn login or cookies.

## `linkedinUrlsText` (type: `string`):

Paste a whole column from a spreadsheet or CRM export: one LinkedIn profile URL per line. Duplicates across both fields are removed.

## `minConfidence` (type: `string`):

"medium" (default) returns a phone when exactly one person with this name lives in the LinkedIn state, or when the record names the LinkedIn employer. "high" returns phones only when the public record names the same employer; location-only matches come back as free "unconfirmed" rows without phones.

## `onlyFound` (type: `boolean`):

Off by default: every profile gets a row that says why it has no phone (several people fit, no record, outside the US). Those rows are free. Turn on to keep only the rows you are billed for.

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

Most profiles to process in this run, after duplicates are removed. Free Apify plans are capped at 10 per run.

## `maxConcurrency` (type: `integer`):

LinkedIn profiles read in parallel.

## Actor input object example

```json
{
  "linkedinUrls": [
    "https://www.linkedin.com/in/katemakowski/",
    "https://www.linkedin.com/in/adamhcarr/"
  ],
  "minConfidence": "medium",
  "onlyFound": false,
  "maxItems": 1000,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `phones` (type: `string`):

Name, employer, LinkedIn location, primary phone and type, confidence, the reason for the match (or for no match) and whether the row was billed.

## `all` (type: `string`):

Every field, including every phone on the record with its type, carrier and last-reported month.

# 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 = {
    "linkedinUrls": [
        "https://www.linkedin.com/in/katemakowski/",
        "https://www.linkedin.com/in/adamhcarr/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/linkedin-phone-number-finder").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 = { "linkedinUrls": [
        "https://www.linkedin.com/in/katemakowski/",
        "https://www.linkedin.com/in/adamhcarr/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/linkedin-phone-number-finder").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 '{
  "linkedinUrls": [
    "https://www.linkedin.com/in/katemakowski/",
    "https://www.linkedin.com/in/adamhcarr/"
  ]
}' |
apify call memo23/linkedin-phone-number-finder --silent --output-dataset

```

## MCP server setup

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

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/S4ay7YHfII4P0ZtXy/builds/5CDLvTtyBMm1clLLR/openapi.json
