# Public Candidate Finder — LinkedIn Recruiter Alternative (`khadinakbar/linkedin-recruiter-alternative`) Actor

Find public candidate leads using role, location, employer, and professional-search filters. Export LinkedIn profile URLs, professional context, source evidence, and timestamps for recruiter review.

- **URL**: https://apify.com/khadinakbar/linkedin-recruiter-alternative.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Lead generation, MCP servers, Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 public candidate lead founds

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?

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

## Public Candidate Finder — LinkedIn Recruiter Alternative

Find public candidate leads using role, location, employer, and professional-search filters. Export LinkedIn profile URLs, professional context, source evidence, and timestamps for recruiter review. For recruiters, each dataset row represents one public candidate lead and the professional search context used to find it.

### Workflow: put the results to work

Translate the hiring brief into a role query and the relevant location or employer filters. Inspect each public profile lead and the applied search context, then move approved records into your recruiting process. Every result needs human review before a candidate decision.

### A recruiter workflow

An agency recruiter starts with `machine learning engineer`, adds London and several senior-title alternatives, and caps the run at 25 candidates. The Actor requests a stable provider session, deduplicates profiles, validates every complete public candidate record, and stores it in the dataset. Next, the recruiter reviews the visible role and location context, confirms relevance manually, and routes selected records into their approved recruiting workflow.

### Public candidate data

| Field | Meaning |
| --- | --- |
| `fullName` | Public professional name returned for the profile |
| `profileUrl` | Public LinkedIn profile URL |
| `currentTitle` / `currentCompany` | Current professional context when returned |
| `location` | Public professional location text when returned |
| `matchEvidence` | Visible or applied professional search-filter context |
| `source` / `collectedAt` | Provider provenance and collection time |
| `humanReviewRequired` | Always `true`; every record needs human review |

The data source is an owner-managed HarvestAPI public lead-search route. The Actor accepts no LinkedIn account, cookie, session, or contact credential from the caller. Public sourcing records are intended for authorised recruitment research and manual review; human-led workflows remain responsible for all employment decisions.

### Quick start input

```json
{
  "searchQuery": "machine learning engineer",
  "currentJobTitles": ["Senior Machine Learning Engineer", "Staff Machine Learning Engineer"],
  "locations": ["London"],
  "recentlyChangedJobs": false,
  "maxResults": 25
}
```

Use `currentCompanies` or `excludeCurrentCompanies` only with public LinkedIn company URLs. Add `postedOnLinkedin` when a recent public posting signal supports the sourcing workflow. The Actor stores applied filters with every record so a recruiter can understand the exact scope that produced the dataset.

### Example output

```json
{
  "recordType": "public_recruiting_candidate_lead",
  "candidateId": "public-provider-id",
  "fullName": "Ada Lovelace",
  "profileUrl": "https://www.linkedin.com/in/example-person",
  "currentTitle": "Senior Machine Learning Engineer",
  "currentCompany": "Example Ltd",
  "currentCompanyUrl": "https://www.linkedin.com/company/example",
  "location": "London, England",
  "openProfile": false,
  "premiumProfile": false,
  "matchEvidence": ["search_query_visible", "title_visible", "location_visible"],
  "searchQuery": "machine learning engineer",
  "appliedFilters": {
    "currentJobTitles": ["Senior Machine Learning Engineer"],
    "locations": ["London"],
    "currentCompanies": [],
    "recentlyChangedJobs": false,
    "postedOnLinkedin": false
  },
  "source": "harvest_api_public_linkedin_lead_search",
  "collectedAt": "2026-01-01T00:00:00.000Z",
  "humanReviewRequired": true,
  "useLimit": "Use only as public sourcing research. Do not use this record to make automated employment, eligibility, or suitability decisions."
}
```

### API and dataset readback

Start a bounded run from an authorised server-side client, then read the default dataset and the compact terminal record.

```bash
curl -X POST 'https://api.apify.com/v2/acts/khadinakbar~linkedin-recruiter-alternative/runs?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"searchQuery":"machine learning engineer","locations":["London"],"maxResults":25}'
```

Each run writes `OUTPUT` and `RUN_SUMMARY` alongside the candidate dataset. `OUTPUT` gives an actionable terminal outcome and charge counts; `RUN_SUMMARY` adds page, deduplication, provider, cost-cap, and warning context. Use dataset pagination for larger result sets or narrow the professional criteria for a smaller review set.

### AI-agent prompt card

> Find up to 25 public data-engineer profiles in Berlin for recruiter review. Return the public name, current title, current company, profile URL, location, source, and collection time. Keep every result marked for human review, report the terminal outcome, and read the dataset after the run.

An AI agent can use the declared input and output schema to prepare a bounded request, inspect the terminal outcome, and retrieve the dataset. The agent should preserve the source and collection-time fields, communicate the event cost and platform usage, respect pagination, and hand the record set to a human recruiter for review.

### Best results guidance

Start with a specific role and one market, then add title or public-company filters only when the initial dataset needs more focus. Keep result caps aligned with the number of records a recruiter can review, confirm the visible public context, and retain the source and collection time alongside downstream records. A fresh scheduled run can support an authorised recurring sourcing workflow once its output is reviewed and maintained by the operator.

### Builder's note

I designed this Actor around the narrow public sourcing step because that is where a structured, source-linked dataset provides value without copying a recruiting suite. The output intentionally keeps public professional context, collection provenance, and a human-review boundary together so downstream systems have less ambiguous data to work with.

### Responsible use

Use this workflow only for authorised, lawful professional sourcing and in line with applicable laws, privacy obligations, and site terms. Treat public profile data carefully, retain it only as long as needed for the defined recruiting purpose, and keep a qualified human responsible for every employment-related decision.

### How this workflow compares with LinkedIn Recruiter

| Decision area | This Actor | LinkedIn Recruiter | Practical routing |
| --- | --- | --- | --- |
| Scope and workflow | Bounded public candidate sourcing and structured export | Licensed recruiting suite with broader workflow features | Use this Actor for the initial public sourcing-export step; use Recruiter for the wider suite workflow |
| Billing and cost | Pay per event plus platform usage; see the Pricing tab for current rates. | Subscription and contract pricing vary by offering, region, and terms | Use the Actor price for a bounded run; evaluate Recruiter plans for ongoing suite access |
| Output usability and efficiency | A dataset row keeps profile URL, professional context, source, collection time, and review boundary together | Recruiter provides its own product workflows and exports | Choose the record shape that keeps the recruiter review process clear and auditable |
| Input access | Professional filters with no caller LinkedIn account credential | Licensed account-based recruiting tools | Select the access model that matches the approved recruiting workflow |
| Integration and automation | Declared Apify API and dataset output for programmatic readback | Recruiter supports selected ATS integrations and team features | Pair this Actor with an approved downstream system; use Recruiter where its ATS and team integration is central |

LinkedIn Recruiter is a trademark of its owner. This independent Actor is not affiliated with, associated with, or endorsed by LinkedIn. It offers a focused public sourcing workflow; LinkedIn Recruiter remains the appropriate product for teams whose workflow centres on its licensed recruiting suite.

### Pricing and run costs

This Actor uses **Pay per event plus Apify platform usage**. The [Pricing tab](https://apify.com/khadinakbar/linkedin-recruiter-alternative/pricing) lists the current event rates and billing terms.

| Event | Billing unit | When it applies |
|---|---|---|
| `apify-actor-start` | Actor Start | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). |
| `candidate-lead-found` | Public candidate lead found | One complete public professional candidate lead persisted with provenance and a human-review boundary. |

Run cost combines the charged events and Apify platform usage. Review the run charge limit and requested result count before starting.

### Connect an AI agent

Use the [Apify MCP configurator](https://mcp.apify.com) to choose an available client connection. Inspect this Actor’s current input schema and required credentials before running it.

# Actor input Schema

## `searchQuery` (type: `string`):

Use this for the role, skill, or professional phrase to source, for example machine learning engineer. It uses HarvestAPI's public LinkedIn lead search and supports LinkedIn-style search operators. The default finds a broad professional role and the value is capped at 240 characters. This is not a request to decide whether anyone is qualified or suitable for employment.

## `currentJobTitles` (type: `array`):

Use this to require one or more current professional job-title phrases, for example Senior Machine Learning Engineer. Provide up to ten alternatives and the Actor sends them as an upstream title filter. Leave it empty to rely on the main search query. This is not a skills assessment or a suitability score.

## `locations` (type: `array`):

Use this to filter candidates by public location text, for example London or Berlin. Provide up to ten city, region, or country alternatives; exact upstream matching may vary. Leave it empty for no location restriction. This is not a proxy country setting or an address lookup.

## `currentCompanies` (type: `array`):

Use this for public LinkedIn company URLs whose current employees are in scope, for example https://www.linkedin.com/company/example/. Provide up to ten canonical company URLs. Leave it empty for no employer restriction. This is not an authenticated Recruiter project, an employee export, or a request for private company data.

## `excludeCurrentCompanies` (type: `array`):

Use this to exclude public LinkedIn company URLs from the search, for example https://www.linkedin.com/company/example/. Provide up to ten canonical company URLs. Leave it empty when no exclusion is needed. This is not a protected-class filter or a way to infer an individual's employment eligibility.

## `excludeJobTitles` (type: `array`):

Use this to exclude public professional job-title phrases, for example Intern. Provide up to ten alternatives and the Actor sends them as an upstream exclusion filter. Leave it empty for no title exclusion. This is not a personal attribute filter or an automated screening criterion.

## `recentlyChangedJobs` (type: `boolean`):

Turn this on to request the provider's public recently-changed-jobs filter, documented as the last 90 days. It defaults to false because this is a narrower sourcing signal. The upstream provider determines availability and the Actor records applied filters in every result. This is not a prediction of responsiveness or an employment recommendation.

## `postedOnLinkedin` (type: `boolean`):

Turn this on to request the provider's public recent-posting filter, documented as the last 30 days. It defaults to false and should be used only when that public activity signal is relevant to sourcing. The Actor does not fetch or evaluate post content. This is not an engagement score or a suitability measure.

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

Set the hard cap on unique, complete public candidate records to persist. The default is 25 and the maximum is 100, fetched in pages of up to 25 with one stable provider session per run. Each persisted record is charged $0.05, so a 25-result cap has at most $1.25 in event charges plus platform usage. This is not a promise that every requested result exists or matches all criteria.

## Actor input object example

```json
{
  "searchQuery": "machine learning engineer",
  "currentJobTitles": [
    "Senior Machine Learning Engineer"
  ],
  "locations": [
    "London"
  ],
  "currentCompanies": [],
  "excludeCurrentCompanies": [],
  "excludeJobTitles": [],
  "recentlyChangedJobs": false,
  "postedOnLinkedin": false,
  "maxResults": 25
}
```

# Actor output Schema

## `candidateLeads` (type: `string`):

One validated public professional sourcing record per candidate, including provenance and human-review safeguards.

## `compactOutput` (type: `string`):

Stable terminal outcome, row counts, warnings, and PPE event counts.

## `runSummary` (type: `string`):

Detailed provider attempts, cost-cap status, run identifiers, and terminal diagnostics.

# 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 = {
    "searchQuery": "machine learning engineer",
    "currentJobTitles": [
        "Senior Machine Learning Engineer"
    ],
    "locations": [
        "London"
    ],
    "currentCompanies": [],
    "excludeCurrentCompanies": [],
    "excludeJobTitles": [],
    "recentlyChangedJobs": false,
    "postedOnLinkedin": false,
    "maxResults": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/linkedin-recruiter-alternative").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 = {
    "searchQuery": "machine learning engineer",
    "currentJobTitles": ["Senior Machine Learning Engineer"],
    "locations": ["London"],
    "currentCompanies": [],
    "excludeCurrentCompanies": [],
    "excludeJobTitles": [],
    "recentlyChangedJobs": False,
    "postedOnLinkedin": False,
    "maxResults": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/linkedin-recruiter-alternative").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 '{
  "searchQuery": "machine learning engineer",
  "currentJobTitles": [
    "Senior Machine Learning Engineer"
  ],
  "locations": [
    "London"
  ],
  "currentCompanies": [],
  "excludeCurrentCompanies": [],
  "excludeJobTitles": [],
  "recentlyChangedJobs": false,
  "postedOnLinkedin": false,
  "maxResults": 25
}' |
apify call khadinakbar/linkedin-recruiter-alternative --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/linkedin-recruiter-alternative"
        }
    }
}
```

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/2AJMXGgk4HQb4ZAgT/builds/9HcPdCstfTt8GtpGX/openapi.json
