# LinkedIn Candidate Finder: Matched Skills, No Recruiter Seat (`themineworks/linkedin-candidate-finder`) Actor

Find LinkedIn profiles matching recruiter requirements: role, skills, location, experience, target companies. Returns name, headline, current title and company, profile URL, matched skills, and a match confidence note. No login, no cookies. Use as an MCP server in Claude, ChatGPT and AI agents.

- **URL**: https://apify.com/themineworks/linkedin-candidate-finder.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Lead generation, Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 candidate founds

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

## LinkedIn Candidate Finder: Recruiter Sourcing

### Overview

LinkedIn Candidate Finder turns your recruiter requirements into a ready-to-review candidate shortlist. Give it a role, the skills you need, a location and (optionally) target companies, and it returns names, headlines, current title and company, profile URLs, which of your required skills each candidate actually has, and a plain-English match confidence note. No LinkedIn login, no Recruiter seat, no cookies, no browser automation.

It reads public LinkedIn profiles that Google has already indexed, the same public-data technique proven across this portfolio's other LinkedIn actors, and returns structured recruiter-ready records for your ATS or sourcing sheet.

Reliability posture: empty or blocked searches are never charged. You only pay for a candidate record that was actually delivered.

✅ No login required | ✅ No cookies | ✅ Matched skills per candidate | ✅ MCP-ready for AI agents

### Features

Recruiter-shaped input. Role, required skills, location, experience band, target companies, not a generic keyword box.
Matched skills per candidate. See exactly which of your required skills show up on each profile.
Match confidence note. A short, honest explanation of how strong each match is, not just a bare score.
Target-company sourcing. Point it at specific companies to pull candidates from those teams first.
CRM/ATS-ready export. JSON, CSV, or Excel, or pull it straight into an AI agent via MCP.

### How it works

LinkedIn has no public candidate-search API, and Recruiter seats are expensive per-license subscriptions. LinkedIn Candidate Finder works only from public data: it builds `site:linkedin.com/in "role" "skill" "location"` search queries and reads the public LinkedIn profiles Google has already indexed. It never authenticates with LinkedIn, never uses cookies, and never touches LinkedIn's own servers.

For each profile found, it checks the indexed headline and snippet text against your required skills list and reports which ones actually appear, parses a best-effort current title and company from the headline, and produces a match confidence note explaining whether the role, skills, and location all line up. If a narrow search (role plus several skills plus a location) returns too few results, it automatically broadens the query, dropping skills or the location constraint, so you still get a usable shortlist instead of an empty run.

### 🧾 Input configuration

```json
{
  "roleTitle": "Senior Software Engineer",
  "skills": ["Python", "AWS"],
  "location": "San Francisco",
  "experienceYears": { "min": 5, "max": 10 },
  "targetCompanies": ["Stripe", "Notion"],
  "maxResults": 30,
  "proxy": { "useApifyProxy": true, "apifyProxyGroups": ["GOOGLE_SERP"] }
}
```

### 📤 Output format

Real record delivered by a live run against `roleTitle: "Senior Software Engineer", skills: ["Python", "AWS"], location: "San Francisco"` on 2026-07-15:

```json
{
  "name": "Adam Jenkins",
  "headline": "Senior Software Engineer | ex-Amazon",
  "current_title": "Senior Software Engineer",
  "current_company": "ex-Amazon",
  "profile_url": "https://www.linkedin.com/in/adamjenkins1",
  "matched_skills": [],
  "match_confidence": "medium (role matched, 0/2 skills matched, location not confirmed)",
  "scraped_at": "2026-07-15T01:15:42.690Z"
}
```

`matched_skills` is genuinely empty here: Google's indexed snippet for this profile didn't surface "Python" or "AWS" in text, so the actor correctly under-reports rather than guesses. `location` is included only when confirmed in the indexed text; it isn't present on this record.

Every candidate record contains these fields:

| Field | Description |
| --- | --- |
| 🙋 `name` | Full name of the candidate |
| 💬 `headline` | LinkedIn headline as indexed by Google |
| 💼 `current_title` | Current job title, best-effort parsed from the headline |
| 🏢 `current_company` | Current company, best-effort parsed from the headline |
| 📍 `location` | Candidate location, reported only when confirmed in the indexed text |
| 🔗 `profile_url` | Public LinkedIn profile URL |
| 🧩 `matched_skills` | Which of your required skills were found on the profile |
| 🎯 `match_confidence` | Note on match strength: high, medium, or low, with the reasoning |
| 🕒 `scraped_at` | ISO timestamp of when the record was captured |

### 💼 Common use cases

**Recruiter sourcing**
Build a first-pass candidate list for a role by title, must-have skills, and location before reaching out.
Fill a pipeline for a hard-to-fill role by broadening across nearby skills automatically.

**Target-company sourcing**
Point the search at named companies to find people already doing the job you're hiring for.
Build a passive-candidate list from specific competitors or partner companies.

**Skills-gap shortlisting**
Compare `matched_skills` across candidates to see who actually has the full stack you need versus a partial match.
Use `match_confidence` to triage a long list down to the ones worth a first call.

**Sourcing pipeline enrichment**
Feed the `profile_url` list into an outreach sequencer or ATS import.
Re-run periodically as new profiles get indexed for a hard-to-fill role.

### 🚀 Getting started

1. Open the actor and enter the role you're recruiting for (e.g. "Senior Software Engineer").
2. Add the required skills (e.g. "Python", "AWS") and a location. Leave either empty to search more broadly.
3. Optionally set an experience range and target companies to prioritise (up to 20 — each adds its own search).
4. Set max candidates (default 30) to control volume and cost, and keep the recommended `GOOGLE_SERP` proxy group.
5. Click Start, then download the dataset as JSON, CSV, or Excel, or pull it via API/MCP.

### FAQ

**How does it find candidates without a Recruiter seat?**
It only reads public LinkedIn profiles that Google has already indexed, using `site:linkedin.com/in "role" "skill" "location"` search queries through the `GOOGLE_SERP` proxy. It never logs in, never uses cookies, and never touches LinkedIn's own servers directly.

**How reliable is the matched\_skills field?**
It checks each required skill against the profile's indexed headline and snippet text (case-insensitive). A skill only appears in `matched_skills` if it's actually present in that indexed text, so it will under-report skills LinkedIn hasn't surfaced in its Google-facing summary rather than over-claim a match.

**What does experienceYears actually filter on?**
Google's public index has no structured years-of-experience field, so this is a soft signal: outside a min of 8+ or a max of 3 or under, it adds a "senior" or "junior" keyword to the search rather than filtering results numerically.

**How much does it cost?**
Pay per event: $0.003 per candidate found. You're charged only for candidates actually delivered, never for empty or blocked searches.

**Can I use it inside an AI agent?**
Yes. It's exposed as an MCP tool. See below.

### Use in Claude, ChatGPT & any MCP agent

```
https://mcp.apify.com/?tools=themineworks/linkedin-candidate-finder
```

Or call it programmatically with the Apify client:

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('themineworks/linkedin-candidate-finder').call({
  roleTitle: 'Senior Software Engineer',
  skills: ['Python', 'AWS'],
  location: 'San Francisco',
  maxResults: 30,
});

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

### 🛠️ Related LinkedIn actors

Found the candidates. Now enrich and reach out with the full LinkedIn wedge:

- **[LinkedIn Profile Scraper](https://apify.com/themineworks/linkedin-profile-scraper)**: pull the full profile (experience, education, skills) for any candidate URL.
- **[LinkedIn Company Scraper](https://apify.com/themineworks/linkedin-company-details)**: firmographics (industry, size, HQ, founded, website) from a company page URL.
- **[LinkedIn Employees Scraper](https://apify.com/themineworks/linkedin-employees)**: list every public employee at a target company.
- **[LinkedIn Jobs Scraper](https://apify.com/themineworks/linkedin-jobs-scraper)**: see what roles a target company is actively hiring for.
- **[LinkedIn Post Scraper](https://apify.com/themineworks/linkedin-post-search)**: public LinkedIn posts and their authors by keyword, for social listening and lead discovery.
- **[B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder)**: get business emails and phone numbers alongside LinkedIn profiles.

Typical flow: candidate-finder builds the shortlist, linkedin-profile-scraper pulls full work history for the shortlisted names, b2b-leads-finder adds a contact email before outreach.

Found a bug or have a feature request? Open an issue on the actor's Apify Console page or reach out through the Apify profile.

# Actor input Schema

## `roleTitle` (type: `string`):

The role you are recruiting for, e.g. 'Senior Software Engineer', 'Product Manager', 'Data Scientist'.

## `skills` (type: `array`):

Skills the candidate must have, e.g. 'Python', 'AWS', 'React'. Each matched skill is reported per candidate in matched\_skills.

## `location` (type: `string`):

City, region, or country to search in, e.g. 'San Francisco', 'London', 'Bengaluru'.

## `experienceYears` (type: `object`):

Optional years-of-experience range, e.g. {"min": 5, "max": 10}. This is a soft signal (adds a seniority keyword like 'senior' or 'junior' to the search), not a hard filter: Google's public index has no structured experience field to filter on exactly.

## `targetCompanies` (type: `array`):

Optional list of companies to prioritise, e.g. 'Stripe', 'Notion'. Adds focused role + company searches ahead of the broader search. Capped at 20 — each adds its own query, and misses on wrong/niche company names cost real fetches even when nothing is billable. Need more? Run again with a fresh list.

## `maxResults` (type: `integer`):

Maximum number of candidates to return across all queries.

## `proxy` (type: `object`):

The GOOGLE\_SERP proxy group is strongly recommended for LinkedIn profile discovery via Google.

## Actor input object example

```json
{
  "roleTitle": "Senior Software Engineer",
  "skills": [
    "Python",
    "AWS"
  ],
  "location": "San Francisco",
  "experienceYears": {
    "min": 3,
    "max": 8
  },
  "targetCompanies": [],
  "maxResults": 5,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}
```

# Actor output Schema

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

```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 = {
    "roleTitle": "Senior Software Engineer",
    "skills": [
        "Python",
        "AWS"
    ],
    "location": "San Francisco",
    "experienceYears": {
        "min": 3,
        "max": 8
    },
    "targetCompanies": [],
    "maxResults": 5,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "GOOGLE_SERP"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/linkedin-candidate-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 = {
    "roleTitle": "Senior Software Engineer",
    "skills": [
        "Python",
        "AWS",
    ],
    "location": "San Francisco",
    "experienceYears": {
        "min": 3,
        "max": 8,
    },
    "targetCompanies": [],
    "maxResults": 5,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["GOOGLE_SERP"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/linkedin-candidate-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 '{
  "roleTitle": "Senior Software Engineer",
  "skills": [
    "Python",
    "AWS"
  ],
  "location": "San Francisco",
  "experienceYears": {
    "min": 3,
    "max": 8
  },
  "targetCompanies": [],
  "maxResults": 5,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}' |
apify call themineworks/linkedin-candidate-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,themineworks/linkedin-candidate-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/CXDTgdW3W9z1eKRvK/builds/bsIXUjN3ipElBnCo9/openapi.json
