# LinkedIn Profile URL Finder (`automation-lab/linkedin-profile-url-finder`) Actor

Find likely public LinkedIn profile URLs from names, companies, domains, titles, and locations with confidence scores for enrichment workflows.

- **URL**: https://apify.com/automation-lab/linkedin-profile-url-finder.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation
- **Stats:** 90 total users, 36 monthly users, 93.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 item extracteds

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?

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

## LinkedIn Profile URL Finder

Find likely public LinkedIn profile URLs from person names, company/domain hints, job titles, and locations.

### What does LinkedIn Profile URL Finder do?

LinkedIn Profile URL Finder helps recruiting, sales, operations, and enrichment teams turn a list of people into likely public LinkedIn profile URLs.

It searches public search results for `linkedin.com/in` pages, extracts visible result titles and snippets, normalizes profile URLs, and scores each candidate.

The actor does not require LinkedIn cookies, LinkedIn login, or private profile access.

It is designed for bulk workflows where you already have a lead list and need a reliable best-effort URL column.

### Who is it for?

- Recruiters enriching candidate spreadsheets.
- Sales teams preparing account-based prospect lists.
- RevOps teams cleaning CRM contacts.
- Data enrichment teams building Clay, Zapier, Make, or Airtable workflows.
- Agencies preparing lead lists for outreach.
- Founders validating people data before manual research.

### Why use this actor?

Manual LinkedIn URL lookup is slow.

Search result pages often contain enough public information to identify the right profile.

This actor makes that process repeatable, structured, and easy to export.

You get one output row per input person, plus confidence evidence you can filter before sending data downstream.

### How it works

1. You provide people with `fullName` and optional company, domain, title, location, and keywords.
2. The actor builds a public search query using `site:linkedin.com/in`.
3. It tries Google first, detects blocked or changed result pages, and uses a bounded Brave Search fallback when needed.
4. It extracts LinkedIn `/in/` profile candidates from both structured result containers and normalized result links.
5. It scores candidates by name, company, domain keyword, title, and location matches.
6. It saves the best URL and optional candidate list to the dataset.

### Data you can extract

| Field | Description |
| --- | --- |
| `fullName` | Input person name |
| `company` | Input company hint |
| `domain` | Input company domain hint |
| `title` | Input job title hint |
| `location` | Input location hint |
| `searchQuery` | Query used for public search |
| `bestProfileUrl` | Best normalized LinkedIn profile URL |
| `bestProfileTitle` | Search result title for the best match |
| `bestProfileSnippet` | Search result snippet for the best match |
| `confidence` | `high`, `medium`, `low`, or `none` |
| `score` | Numeric match score from 0 to 100 |
| `candidateCount` | Number of LinkedIn candidates found |
| `candidates` | Optional scored candidate list |
| `reasons` | Why the best match was selected |
| `status` | `found`, `not_found`, or `error` |
| `searchedAt` | ISO timestamp |

### How much does it cost to find LinkedIn profile URLs?

This actor uses pay-per-event pricing.

You pay a small start fee for each run and a per-person fee for each processed row.

Start with a small test batch, review confidence scores, and then scale to larger lists.

Because the actor uses a dedicated SERP proxy, the pricing is designed to include search infrastructure costs.

### Input example

```json
{
  "people": [
    {
      "fullName": "Satya Nadella",
      "company": "Microsoft",
      "domain": "microsoft.com",
      "title": "CEO",
      "location": "Redmond"
    },
    {
      "fullName": "Sundar Pichai",
      "company": "Google",
      "domain": "google.com",
      "title": "CEO",
      "location": "Mountain View"
    }
  ],
  "maxCandidates": 5,
  "includeCandidates": true,
  "requestDelayMs": 500
}
```

### Output example

```json
{
  "fullName": "Satya Nadella",
  "company": "Microsoft",
  "domain": "microsoft.com",
  "title": "CEO",
  "location": "Redmond",
  "bestProfileUrl": "https://www.linkedin.com/in/satyanadella",
  "confidence": "high",
  "score": 100,
  "candidateCount": 5,
  "status": "found",
  "reasons": [
    "all name tokens matched in result title",
    "company matched",
    "domain keyword matched",
    "title matched",
    "location matched",
    "public LinkedIn profile URL"
  ]
}
```

### Input fields

#### `people`

Required array of people to enrich.

Each row needs `fullName`.

Optional hints improve matching and reduce false positives.

#### `maxCandidates`

Number of candidates to keep per person.

Use 3 to 5 for most workflows.

#### `includeCandidates`

Set to `true` when you want evidence and alternatives.

Set to `false` when you only need the best URL column.

#### `requestDelayMs`

Delay between searches.

Use the default for normal batches.

Increase it for very large runs.

### Tips for better matches

- Include company names when possible.
- Include company domains for stronger disambiguation.
- Add titles for common names.
- Add city or country when the company has many employees.
- Filter downstream rows where `confidence` is `high` or `score` is above your threshold.
- Review `candidates` for ambiguous names before automated outreach.

### Common workflows

#### Recruiting sourcing

Upload a list of candidate names and current companies.

Export `bestProfileUrl` to your applicant tracking system or sourcing spreadsheet.

#### Sales prospecting

Resolve contacts from CRM exports before building outreach sequences.

Use confidence scores to separate automatic matches from manual review.

#### Data enrichment

Add a LinkedIn URL column to Clay, Airtable, or Google Sheets workflows.

Use the Apify API to run this actor whenever a new batch is ready.

#### CRM cleanup

Find missing LinkedIn URLs for existing contacts.

Keep `searchQuery` and `reasons` for auditability.

### Integrations

- Google Sheets: export the dataset as CSV.
- Clay: run the actor through Apify integration or API calls.
- Zapier: trigger a run and send dataset rows into a CRM.
- Make: enrich rows in scheduled batches.
- Airtable: import URL and confidence fields.
- HubSpot or Salesforce: update contact records after manual approval.

### API usage with Node.js

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/linkedin-profile-url-finder').call({
  people: [{ fullName: 'Satya Nadella', company: 'Microsoft' }],
  maxCandidates: 5,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')
run = client.actor('automation-lab/linkedin-profile-url-finder').call(run_input={
    'people': [{'fullName': 'Satya Nadella', 'company': 'Microsoft'}],
    'maxCandidates': 5,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### API usage with cURL

```bash
curl "https://api.apify.com/v2/acts/automation-lab~linkedin-profile-url-finder/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"people":[{"fullName":"Satya Nadella","company":"Microsoft"}],"maxCandidates":5}'
```

### MCP usage

Use this actor with Apify MCP in Claude Desktop or Claude Code.

MCP URL:

```text
https://mcp.apify.com/?tools=automation-lab/linkedin-profile-url-finder
```

#### Claude Code setup

```bash
claude mcp add --transport http apify-linkedin-profile-url-finder https://mcp.apify.com/?tools=automation-lab/linkedin-profile-url-finder
```

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

Add this MCP JSON block in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify-linkedin-profile-url-finder": {
      "url": "https://mcp.apify.com/?tools=automation-lab/linkedin-profile-url-finder"
    }
  }
}
```

Example prompts:

- "Find LinkedIn profile URLs for these 50 people and return only high-confidence matches."
- "Enrich this recruiting list with profile URLs and explain ambiguous candidates."
- "Create a CSV-ready table with name, company, best LinkedIn URL, score, and reasons."

### Accuracy and confidence

This actor is a best-effort resolver, not an official identity verification service.

A high score means the public search result strongly matched the provided hints.

It does not guarantee employment, current role, or profile ownership.

For compliance-sensitive workflows, review results before use.

### Limitations

- Search engines may return different results by time and region; the actor tries at most two public search routes per person.
- Very common names can produce ambiguous candidates.
- Some LinkedIn profiles are hidden from public search results.
- The actor does not open private LinkedIn profile pages.
- The actor does not bypass LinkedIn login walls.

### FAQ

#### Why did a person return `not_found`?

Neither available public search route exposed a LinkedIn `/in/` result for the exact hints. The `reasons` field states which routes returned no candidates. If every route is blocked or fails, the row uses `status: "error"` with a diagnostic `errorMessage` instead of silently reporting a genuine no-match.

Try adding a company, removing overly specific title/location hints, or adding a domain.

#### Why is confidence low?

The candidate may match only a partial name or company clue.

Review `candidates` and `reasons` before accepting the URL.

#### Why do I see multiple candidates?

Common names and large companies often produce several plausible profiles.

Use the highest score first, then inspect alternatives when the decision matters.

### Legality and ethical use

This actor works with publicly visible search result snippets and URLs.

Use the data only for lawful purposes.

Respect privacy, platform terms, outreach rules, and applicable data protection laws.

Avoid using profile URLs for spam, harassment, discrimination, or sensitive profiling.

### Related scrapers and tools

- https://apify.com/automation-lab/google-search-scraper
- https://apify.com/automation-lab/website-contact-finder
- https://apify.com/automation-lab/domain-availability-checker
- https://apify.com/automation-lab/google-autocomplete-scraper

### Best practices for bulk runs

Start with a sample of 10 to 25 people.

Check confidence distribution.

Adjust hints.

Then run larger batches.

For thousands of records, split the input into smaller chunks so you can inspect and retry safely.

### Changelog

#### 0.1

Initial version with public search, LinkedIn `/in/` URL extraction, candidate scoring, confidence labels, and candidate evidence.

### Support

If results look wrong, save the input row, output row, and candidate list.

Those fields make it easier to reproduce and tune matching behavior.

# Actor input Schema

## `people` (type: `array`):

Rows to resolve. Full name is required; company, domain, title, and location improve confidence scoring.

## `maxCandidates` (type: `integer`):

How many LinkedIn /in/ candidates to keep for each person.

## `includeCandidates` (type: `boolean`):

Return all scored candidates, not only the best URL.

## `requestDelayMs` (type: `integer`):

Polite delay between public search requests. Increase for large batches.

## Actor input object example

```json
{
  "people": [
    {
      "fullName": "Satya Nadella",
      "company": "Microsoft",
      "domain": "microsoft.com",
      "title": "CEO",
      "location": "Redmond"
    },
    {
      "fullName": "Sundar Pichai",
      "company": "Google",
      "domain": "google.com",
      "title": "CEO",
      "location": "Mountain View"
    }
  ],
  "maxCandidates": 5,
  "includeCandidates": true,
  "requestDelayMs": 500
}
```

# Actor output Schema

## `overview` (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

```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 = {
    "people": [
        {
            "fullName": "Satya Nadella",
            "company": "Microsoft",
            "domain": "microsoft.com",
            "title": "CEO",
            "location": "Redmond"
        },
        {
            "fullName": "Sundar Pichai",
            "company": "Google",
            "domain": "google.com",
            "title": "CEO",
            "location": "Mountain View"
        }
    ],
    "maxCandidates": 5,
    "includeCandidates": true,
    "requestDelayMs": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/linkedin-profile-url-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 = {
    "people": [
        {
            "fullName": "Satya Nadella",
            "company": "Microsoft",
            "domain": "microsoft.com",
            "title": "CEO",
            "location": "Redmond",
        },
        {
            "fullName": "Sundar Pichai",
            "company": "Google",
            "domain": "google.com",
            "title": "CEO",
            "location": "Mountain View",
        },
    ],
    "maxCandidates": 5,
    "includeCandidates": True,
    "requestDelayMs": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/linkedin-profile-url-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 '{
  "people": [
    {
      "fullName": "Satya Nadella",
      "company": "Microsoft",
      "domain": "microsoft.com",
      "title": "CEO",
      "location": "Redmond"
    },
    {
      "fullName": "Sundar Pichai",
      "company": "Google",
      "domain": "google.com",
      "title": "CEO",
      "location": "Mountain View"
    }
  ],
  "maxCandidates": 5,
  "includeCandidates": true,
  "requestDelayMs": 500
}' |
apify call automation-lab/linkedin-profile-url-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/linkedin-profile-url-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/RmTWvesTLvIXUyjes/builds/9TnhExd3bb0AR2Q6n/openapi.json
