# Candidate Cross-Platform Resolver (`recruitops_hq/candidate-cross-reference`) Actor

Cross-references 12 platforms — GitHub, GitLab, Kaggle, Devpost, Stack Overflow, dev.to, npm, and a candidate's own site — into confidence-scored matches backed by real evidence. LinkedIn and X are never scraped, only corroborated.

- **URL**: https://apify.com/recruitops\_hq/candidate-cross-reference.md
- **Developed by:** [RecruitOps Support](https://apify.com/recruitops_hq) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $250.00 / 1,000 lead resolveds

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

## Candidate Cross-Platform Resolver

Verify a candidate's real footprint before you reach out — not another
"here's a maybe, go check it yourself" name-search tool. Give it any subset
of **full name, company, LinkedIn URL, GitHub username, personal site, or
X/Twitter handle**, and it cross-references **12 platforms** into
confidence-scored matches, each backed by a stated reason, not a guess.

**What you get, per lead:**

- **A confidence-scored match per platform** — a numeric score (0.3-0.95)
  and tier (`declared` / `site-crosslink` / `correlated` / `weak`) for every
  hit, so you know how much to trust it before you act on it.
- **The actual evidence, in plain English** — e.g. *"GitHub's own
  social\_accounts field links this LinkedIn URL — the candidate declared it
  themselves"* — so you can judge the match yourself, not trust a black box.
- **Zero LinkedIn/X scraping, ever** — those only surface when independently
  corroborated by an official API or the candidate's own site, keeping you
  clear of the ToS risk that comes with scraping either platform directly.

**Sample output** (real shape, one entry per lead):

```json
{
  "inputLead": { "githubUsername": "addyosmani" },
  "matches": [
    {
      "platform": "github",
      "url": "https://github.com/addyosmani",
      "handle": "addyosmani",
      "confidenceScore": 0.95,
      "confidenceTier": "declared",
      "evidence": ["GitHub username supplied directly in the lead"]
    },
    {
      "platform": "linkedin",
      "url": "https://linkedin.com/in/addyosmani",
      "handle": null,
      "confidenceScore": 0.95,
      "confidenceTier": "declared",
      "evidence": [
        "GitHub's own social_accounts field links this linkedin URL — the candidate declared it themselves"
      ]
    }
  ],
  "overallConfidence": 0.95,
  "checkedAt": "2026-09-21T10:00:00.000Z"
}
```

- **B2B/recruiting-only.** No consumer platforms (Instagram, TikTok,
  Facebook). **LinkedIn and X are never scraped** — they only appear as
  input anchors you already have, or as corroboration when GitHub's own API
  or the candidate's personal site independently confirms the same link.
- **No web scraping of the platforms that matter most for identity** — GitHub
  is an official, authenticated-optional REST API; the only HTML fetched is
  the candidate's own personal site, for finding self-published links.
- **Stateless.** Each run resolves the leads you send it — no recurring
  monitor, no dedupe state. Full behaviour is in [`SPEC.md`](./SPEC.md).
- Part of the **RecruitOps** suite alongside
  [`ats-hiring-signal`](https://github.com/recruitops-hq/ats-hiring-signal) —
  use that one to find which target companies are hiring, then this one to
  verify a candidate before you pitch them.

***

### 1. Quick start (Apify Console)

1. Open the Actor, paste this into **Input**, and click **Start**:

   ```json
   {
     "leads": [
       { "githubUsername": "addyosmani" },
       { "fullName": "Jane Doe", "company": "Acme Corp" }
     ]
   }
   ```

2. Results appear in the run's **Dataset**: one row per lead, each with a
   `matches[]` list — platform, URL, a **confidence tier** (`declared` /
   `site-crosslink` / `correlated` / `weak`), a numeric score, and an
   `evidence[]` array explaining *why* each match was made.

3. **Strongly recommended:** supply a free `githubToken` (a GitHub personal
   access token, no scopes needed) — GitHub's unauthenticated rate limit is
   60 requests/hour (10/min for name search), which more than a handful of
   leads per run will exhaust. A token raises this to 5,000/hour.

### 2. Which fields to give it, depending on what you start with

Each lead needs at least one of these three anchor patterns — pick based on
what you already have:

| You have | Give it | What happens |
|---|---|---|
| Their GitHub username | `githubUsername` | Most direct — fetches the profile and its declared links straight away. |
| Their LinkedIn profile | `fullName` + `company` **+** `linkedinUrl` | Searches GitHub by name (narrowed by company), then checks whether the GitHub profile it finds independently confirms the same LinkedIn URL. If it does, that's a real `declared` match — two sources agreeing, not just your say-so. |
| Only a name | `fullName` + `company` | Same GitHub search, but nothing to corroborate a LinkedIn/X link against — expect `correlated`/`weak` tier results, not `declared`. |

**A bare `linkedinUrl` with nothing else does very little.** Since LinkedIn is
never scraped (see below), the Actor has no name to search GitHub with — it
just echoes your URL back at `weak` confidence, unconfirmed. Always pair a
LinkedIn URL with the name (and ideally company) from that same profile.

### 3. What a confidence tier means

| Tier | Meaning | Score |
|---|---|---|
| `declared` | The platform's own API says the candidate linked this account themselves | 0.95 |
| `site-crosslink` | Found by reading the candidate's own personal site/blog | 0.85 |
| `correlated` | Same handle exists elsewhere, with some corroborating signal | 0.6 |
| `weak` | Name-only or unconfirmed input, no independent corroboration | 0.3 |

A "weak" match is a lead to verify, not a confirmed identity — say so plainly
to your own users if you build on top of this.

### 4. Why this exists

Cheap commodity "find social profiles by name" tools (as low as $2/1,000
results) tell you *that* they found something and ask you to verify it
yourself manually. Enterprise sourcing platforms (SeekOut, hireEZ) charge
$150-500+/seat/month, sales-led, for roughly this job. This sits in between:
self-serve, pay-per-lookup, and — unlike the cheap tools — every match ships
with the actual evidence, not just a guess. See [`SPEC.md`](./SPEC.md) §1 for
the full reasoning and pricing.

### 5. Local development

```bash
npm ci
npm run check   # typecheck + lint + unit tests (all pure, no network)
npm run dev     # runs against the real GitHub API using local input
npm run build   # compiles to dist/
```

### 6. License

Proprietary — see [`LICENSE`](./LICENSE). © 2026 BuildersArk LLC.

# Changelog

This Actor's version history is a separate document: https://apify.com/recruitops\_hq/candidate-cross-reference/changelog.md

# Actor input Schema

## `leads` (type: `array`):

Candidates to resolve. Each entry needs at least a githubUsername, a linkedinUrl, or both fullName and company. Optional fields: fullName, company, linkedinUrl, githubUsername, personalSite, twitterHandle.

## `probePlatforms` (type: `array`):

Which secondary checks to run. Narrowing this reduces cost and GitHub API calls.

## `minConfidence` (type: `number`):

Drop matches scoring below this (0-1). Default 0 returns everything, tier-labelled, so you can decide.

## `githubToken` (type: `string`):

A free GitHub PAT (no scopes needed) raises the API rate limit from 60/hour to 5,000/hour. Strongly recommended for more than a handful of leads per run.

## `maxLeads` (type: `integer`):

Safety cap on how many leads a single run will process. 1-500.

## Actor input object example

```json
{
  "leads": [
    {
      "fullName": "Addy Osmani",
      "company": "Google",
      "githubUsername": "addyosmani"
    }
  ],
  "probePlatforms": [
    "github",
    "personalSite",
    "stackoverflow",
    "devto",
    "npm",
    "gitlab",
    "kaggle",
    "devpost"
  ],
  "minConfidence": 0,
  "maxLeads": 200
}
```

# 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 = {
    "leads": [
        {
            "fullName": "Addy Osmani",
            "company": "Google",
            "githubUsername": "addyosmani"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("recruitops_hq/candidate-cross-reference").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 = { "leads": [{
            "fullName": "Addy Osmani",
            "company": "Google",
            "githubUsername": "addyosmani",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("recruitops_hq/candidate-cross-reference").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 '{
  "leads": [
    {
      "fullName": "Addy Osmani",
      "company": "Google",
      "githubUsername": "addyosmani"
    }
  ]
}' |
apify call recruitops_hq/candidate-cross-reference --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,recruitops_hq/candidate-cross-reference"
        }
    }
}
```

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/gHYfUIkLwJDzVJ2yG/builds/AGmEYNiSbKWkPK3IU/openapi.json
