{
  "data": {
    "id": "t9U82GVzUpIow2oR2",
    "actId": "QNyRsYZSPWVlNZke2",
    "userId": "qNHv1aNFJdi7qCpWe",
    "startedAt": "2026-10-12T05:48:58.036Z",
    "finishedAt": "2026-10-12T05:49:07.424Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "API"
    },
    "stats": {
      "durationMillis": 9296,
      "runTimeSecs": 9.296,
      "computeUnits": 0.01032888888888889,
      "imageSizeBytes": 575610880
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "tag": "latest",
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Email to LinkedIn Profile Scraper\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"description\": \"Look up public LinkedIn profiles from one or more email addresses. Paste work emails and get one row per address with matchStatus, profile URL, name, headline, company, and location when a public match is found. Unmatched addresses return a free CLEAR row. No LinkedIn cookies or login required.\",\n  \"properties\": {\n    \"emails\": {\n      \"title\": \"Email addresses\",\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"Email addresses to resolve to public LinkedIn profiles. Accepts work or personal emails such as satya.nadella@microsoft.com. Up to 100 addresses per run. Role mailboxes like info@ or support@ are recorded as CLEAR and are not billed. NOT LinkedIn profile URLs — use a profile scraper when you already have the /in/ URL.\",\n      \"prefill\": [\n        \"satya.nadella@microsoft.com\"\n      ],\n      \"editor\": \"stringList\",\n      \"maxItems\": 100\n    },\n    \"maxItems\": {\n      \"title\": \"Max found profiles\",\n      \"type\": \"integer\",\n      \"minimum\": 1,\n      \"maximum\": 100,\n      \"description\": \"Maximum number of matched LinkedIn profiles to save and bill this run. Default 50. CLEAR / not-found rows do not count toward this cap and are never billed. Prefill is 1 so Apify quality tests finish quickly; raise it for production batches.\",\n      \"default\": 50,\n      \"prefill\": 1\n    },\n    \"minConfidence\": {\n      \"title\": \"Minimum match confidence\",\n      \"type\": \"integer\",\n      \"minimum\": 50,\n      \"maximum\": 95,\n      \"description\": \"Minimum 0-100 confidence required to accept a LinkedIn profile as a match. Default 70. Lower values return more matches with a higher false-positive risk; higher values keep only name-and-company locks. This is not a LinkedIn login threshold.\",\n      \"default\": 70,\n      \"prefill\": 70\n    },\n    \"enrichProfiles\": {\n      \"title\": \"Enrich matched profiles\",\n      \"type\": \"boolean\",\n      \"description\": \"When enabled, each found LinkedIn profile is fetched to add current company, company URL, location, follower count, and an about preview. Enrichment costs an additional $0.02 per successfully enriched profile on top of the $0.025 found-profile charge. Leave disabled when you only need the profile URL and SERP headline.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"maxConcurrency\": {\n      \"title\": \"Max concurrency\",\n      \"type\": \"integer\",\n      \"minimum\": 1,\n      \"maximum\": 5,\n      \"description\": \"How many email lookups to run in parallel. Default 2 balances speed against provider rate limits. Raise to 5 for large batches; lower to 1 if you see provider rate-limit errors in the run log.\",\n      \"default\": 2,\n      \"prefill\": 2\n    }\n  },\n  \"required\": [\n    \"emails\"\n  ]\n}",
    "readme": "## What is Email to LinkedIn Profile Scraper?\n\nTurn one or more email addresses into public LinkedIn profiles. Paste a work email such as `satya.nadella@microsoft.com` and get one dataset row with `matchStatus`, profile URL, name, headline, company, and location when a public match exists. Unmatched or role-mailbox addresses return a free CLEAR row so you can tell a completed empty lookup from a provider outage. No LinkedIn login or cookies.\n\nDesigned for B2B sales, recruiting, and CRM teams who already have emails and need the matching public LinkedIn URL before outreach. This is the reverse of [LinkedIn Profile Email Scraper](https://apify.com/khadinakbar/linkedin-profile-email-scraper), which starts from a profile URL and looks for an email.\n\n## What you get\n\n| Output | What it answers |\n|---|---|\n| `email` + `matchStatus` | **Which address** was processed and whether a public profile was found |\n| `profileUrl` + `publicIdentifier` | **Where** the person is on LinkedIn |\n| `fullName`, `headline`, `currentCompany`, `location` | **Who they are** at work from public search and optional enrichment |\n| `confidence`, `matchStrategy`, `provider` | **Why this match** was accepted, and which public-data provider supplied it |\n| `clearReason` on CLEAR rows | **Why there is no billable match** — no public hit, role mailbox, or ambiguous result |\n| `OUTPUT` / `RUN_SUMMARY` outcomes | **Provenance** — complete, empty, invalid input, or upstream outage |\n\n## Who it is for (and why it matters)\n\n- **Sales development reps** — attach a LinkedIn URL to inbound or list-bought work emails before a first touch.\n- **Recruiters** — turn a candidate email list into public profiles so you can review headline, company, and location without a LinkedIn seat.\n- **RevOps / CRM owners** — backfill contact records with a canonical `/in/` URL and skip role inboxes like `info@` without paying for them.\n- **AI agents** — one tool call with `emails` returns structured found or CLEAR rows, so the agent can enrich, skip, or route without guessing.\n\n## When to use this Actor\n\n- You have work emails (`first.last@company.com`) and need public LinkedIn profile URLs.\n- You want unmatched addresses recorded as CLEAR so the dataset stays honest.\n- You need optional public-profile enrichment (company URL, followers, about) after a match.\n- When you already have LinkedIn `/in/` URLs, start with [LinkedIn Profile Details Scraper](https://apify.com/khadinakbar/linkedin-profile-details-scraper) for the public about and experience view.\n- When the starting point is a title, company, or location instead of an email, use [LinkedIn Profile Search Scraper](https://apify.com/khadinakbar/linkedin-profile-search-scraper).\n\n## Best fit for this Actor\n\n- Strongest starting condition: a work email whose local-part is a person's name and whose domain is the employer.\n- Useful output: one row per email, billed only when `matchStatus` is `found`.\n- When you need emails validated first, pass the list through [Email Address Validator](https://apify.com/khadinakbar/email-address-validator), then feed the surviving addresses here.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `emails` | array (required) | 1 example email | Up to 100 email addresses per run |\n| `maxItems` | integer | 50 | Cap on **found** profiles saved and billed (CLEAR rows stay outside this cap) |\n| `minConfidence` | integer | 70 | Minimum 0–100 score required to accept a match |\n| `enrichProfiles` | boolean | false | Add company URL, location, followers, about ($0.02/row extra) |\n| `providerOrder` | enum | The default provider order | Public-data provider priority; fallback fires automatically |\n| `maxConcurrency` | integer | 2 | Emails processed in parallel (1–5) |\n\n### Quick start input\n\n```json\n{\n    \"emails\": [\"satya.nadella@microsoft.com\"],\n    \"maxItems\": 1,\n    \"enrichProfiles\": false\n}\n```\n\nThat input selects a single well-known work email so the run stays inside the five-minute quality window and still returns a real found row.\n\n### Example input — bulk work emails, enrichment on\n\n```json\n{\n    \"emails\": [\n        \"satya.nadella@microsoft.com\",\n        \"sundarpichai@google.com\"\n    ],\n    \"maxItems\": 50,\n    \"minConfidence\": 70,\n    \"enrichProfiles\": true\n}\n```\n\nDuplicate emails are deduplicated automatically. Role mailboxes such as `info@company.com` are written as CLEAR and never billed.\n\n## What data you receive\n\nOne dataset item is one email lookup. Found rows carry the LinkedIn identity; CLEAR rows document that the lookup finished with no billable match.\n\n```json\n{\n    \"email\": \"satya.nadella@microsoft.com\",\n    \"matchStatus\": \"found\",\n    \"confidence\": 88,\n    \"profileUrl\": \"https://www.linkedin.com/in/satyanadella\",\n    \"publicIdentifier\": \"satyanadella\",\n    \"fullName\": \"Satya Nadella\",\n    \"headline\": \"Chairman and CEO at Microsoft\",\n    \"currentCompany\": \"Microsoft\",\n    \"matchStrategy\": \"name-company-site\",\n    \"enriched\": false,\n    \"scrapedAt\": \"2026-08-17T00:00:00.000Z\"\n}\n```\n\nCLEAR example:\n\n```json\n{\n    \"email\": \"info@microsoft.com\",\n    \"matchStatus\": \"clear\",\n    \"clearReason\": \"role_mailbox\",\n    \"enriched\": false,\n    \"scrapedAt\": \"2026-08-17T00:00:00.000Z\"\n}\n```\n\nEvery terminal run also writes `OUTPUT` and `RUN_SUMMARY` with a named `outcome`, per-email results, provider diagnostics, and billing counters.\n\n## Workflow story: from a CRM email column to outreach-ready LinkedIn URLs\n\nA RevOps lead exports 40 work emails from a webinar registration list. She pastes them into this Actor with `enrichProfiles: true` and `maxItems` at 40. The run derives a name and company from each `first.last@company.com` address, searches public Google results restricted to LinkedIn profiles, and keeps only matches that clear the confidence bar. Twenty-eight rows come back `found` with profile URLs and current company; nine are CLEAR (`no_public_match` or `role_mailbox`); three stay unmatched because the local-part is a nickname with no public footprint. She then filters `matchStatus=found`, hands the `profileUrl` values to her sequencer, and skips paying for the CLEAR rows. Event cost is 28 × $0.025 plus enrichment on the rows that actually received public profile fields.\n\n## Use through the API\n\n```bash\ncurl -X POST \"https://api.apify.com/v2/acts/khadinakbar~email-to-linkedin-profile-scraper/runs?token=$APIFY_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"emails\": [\"satya.nadella@microsoft.com\"],\n    \"maxItems\": 1,\n    \"enrichProfiles\": false\n  }'\n```\n\nResults land in the run's default dataset: `https://api.apify.com/v2/datasets/{datasetId}/items?clean=true`. Paginate large batches with `offset`/`limit`. The same Actor is exposed through Apify MCP as `apify--email-to-linkedin-profile-scraper`.\n\n## Use with AI agents through Apify MCP\n\n> Given these work email addresses, find each person's public LinkedIn profile URL, name, headline, and company. Return CLEAR for addresses with no public match. Keep only dataset `profileUrl` values. Cap the run at 25 found profiles.\n\nInspect the terminal `outcome`, read the dataset, keep `profileUrl` as the source identifier, and treat `clearReason` as a completed empty lookup for that address. Connect through [Apify MCP](https://mcp.apify.com).\n\n```json\n{\n    \"emails\": [\"satya.nadella@microsoft.com\"],\n    \"maxItems\": 25,\n    \"minConfidence\": 70,\n    \"enrichProfiles\": true,\n    \"maxConcurrency\": 2\n}\n```\n\nThen read results with `get-actor-output`, keep `matchStatus=found` rows for outreach, and pass remaining emails to a validator or a different data source.\n\n## Pricing\n\nThis Actor uses Pay per event with Apify platform usage included. Open the live Pricing tab for current event details, and use Apify's run cost controls to keep the workflow aligned with your budget.\n\n| Event | Price | Charged when |\n|---|---|---|\n| Actor start | $0.00005 | Once per run (scaled by memory) |\n| `profile-found` | $0.025 | One found LinkedIn profile saved |\n| `profile-enriched` | $0.02 | Additional, only when enrichment succeeded |\n\nCLEAR rows, invalid input, and unmatched emails are not billed as `profile-found`.\n\n| Run | Found rows | Enrichment | Event cost (approx.) |\n|---|---|---|---|\n| 1 work email, match | 1 | off | ~$0.025 |\n| 1 work email, match | 1 | on | ~$0.045 |\n| 40 emails, 28 found | 28 | off | ~$0.70 |\n| 40 emails, 28 found | 28 | on | ~$1.26 |\n\nYour run log prints the exact cost cap before any charge fires. Apify platform usage is included in the event price — the live [Pricing tab](https://apify.com/khadinakbar/email-to-linkedin-profile-scraper/pricing) is the current source of truth.\n\n## Best results\n\n- Prefer `first.last@company.com` work emails; they produce name + company search queries.\n- Run [Email Address Validator](https://apify.com/khadinakbar/email-address-validator) first when the list is messy, then look up the surviving addresses here.\n- Keep `minConfidence` at 70 unless you have a reason to accept weaker name-only matches.\n- Turn on `enrichProfiles` when you need location, followers, or a company page URL for routing.\n- After you have profile URLs, pass them to [LinkedIn Profile Details Scraper](https://apify.com/khadinakbar/linkedin-profile-details-scraper) for the public about / experience view, or to [LinkedIn Profile Email Scraper](https://apify.com/khadinakbar/linkedin-profile-email-scraper) only when you started from a profile and need the reverse direction.\n\n## Builder's note\n\nI built this after probing the primary and fallback data providers live: neither vendor exposes an email-to-LinkedIn endpoint, and quoted `\"email\" site:linkedin.com/in` searches are usually empty because people rarely publish their inbox on a public profile. The working public path is Google Search over LinkedIn `/in/` results, using the name and company encoded in a work email, then scoring the hits so `satya.nadella@microsoft.com` keeps the Microsoft CEO and drops the identically named support specialist. That is why this Actor bills found profiles, writes honest CLEAR rows, and keeps ambiguous results out of the found set.\n\n## Responsible use\n\nUse this Actor on emails you are authorized to process for legitimate sales, recruiting, research, or verification. It reads **public web search results and public LinkedIn profile pages only**. It does not log into LinkedIn, does not use your cookies, and is not a private people-graph or data-broker dump. Follow GDPR, CCPA, CAN-SPAM, LinkedIn's terms, and any local law that applies to your outreach. Honor opt-out and do-not-contact requests.\n\nThis tool is provided for lawful public-data collection. You are responsible for how you use the output.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "email-to-linkedin-profile-scraper",
      "title": "Email to LinkedIn Profile Scraper",
      "description": "Look up public LinkedIn profiles from email addresses: name, headline, profile URL, company, and location. Provider-backed via ScrapeCreators and SociaVault Google Search with optional public-profile enrichment. Cookieless, no LinkedIn login. MCP-ready.",
      "seoTitle": "Email to LinkedIn Profile Lookup Scraper",
      "seoDescription": "Find public LinkedIn profiles from work emails: name, headline, URL, company, location. Cookieless bulk lookup, MCP-ready. $0.025 per found profile.",
      "categories": [
        "LEAD_GENERATION",
        "SOCIAL_MEDIA",
        "MCP_SERVERS"
      ],
      "version": "0.1",
      "buildTag": "latest",
      "meta": {
        "templateId": "js-empty",
        "generatedBy": "Claude Code with Claude Opus 4.7"
      },
      "input": {
        "title": "Email to LinkedIn Profile Scraper",
        "type": "object",
        "schemaVersion": 1,
        "description": "Look up public LinkedIn profiles from one or more email addresses. Paste work emails and get one row per address with matchStatus, profile URL, name, headline, company, and location when a public match is found. Unmatched addresses return a free CLEAR row. No LinkedIn cookies or login required.",
        "properties": {
          "emails": {
            "title": "Email addresses",
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Email addresses to resolve to public LinkedIn profiles. Accepts work or personal emails such as satya.nadella@microsoft.com. Up to 100 addresses per run. Role mailboxes like info@ or support@ are recorded as CLEAR and are not billed. NOT LinkedIn profile URLs — use a profile scraper when you already have the /in/ URL.",
            "prefill": [
              "satya.nadella@microsoft.com"
            ],
            "editor": "stringList",
            "maxItems": 100
          },
          "maxItems": {
            "title": "Max found profiles",
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Maximum number of matched LinkedIn profiles to save and bill this run. Default 50. CLEAR / not-found rows do not count toward this cap and are never billed. Prefill is 1 so Apify quality tests finish quickly; raise it for production batches.",
            "default": 50,
            "prefill": 1
          },
          "minConfidence": {
            "title": "Minimum match confidence",
            "type": "integer",
            "minimum": 50,
            "maximum": 95,
            "description": "Minimum 0-100 confidence required to accept a LinkedIn profile as a match. Default 70. Lower values return more matches with a higher false-positive risk; higher values keep only name-and-company locks. This is not a LinkedIn login threshold.",
            "default": 70,
            "prefill": 70
          },
          "enrichProfiles": {
            "title": "Enrich matched profiles",
            "type": "boolean",
            "description": "When enabled, each found LinkedIn profile is fetched to add current company, company URL, location, follower count, and an about preview. Enrichment costs an additional $0.02 per successfully enriched profile on top of the $0.025 found-profile charge. Leave disabled when you only need the profile URL and SERP headline.",
            "default": false,
            "prefill": false
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "description": "How many email lookups to run in parallel. Default 2 balances speed against provider rate limits. Raise to 5 for large batches; lower to 1 if you see provider rate-limit errors in the run log.",
            "default": 2,
            "prefill": 2
          }
        },
        "required": [
          "emails"
        ]
      },
      "chargedEvents": "./pay_per_event.json",
      "readme": "## What is Email to LinkedIn Profile Scraper?\n\nTurn one or more email addresses into public LinkedIn profiles. Paste a work email such as `satya.nadella@microsoft.com` and get one dataset row with `matchStatus`, profile URL, name, headline, company, and location when a public match exists. Unmatched or role-mailbox addresses return a free CLEAR row so you can tell a completed empty lookup from a provider outage. No LinkedIn login or cookies.\n\nDesigned for B2B sales, recruiting, and CRM teams who already have emails and need the matching public LinkedIn URL before outreach. This is the reverse of [LinkedIn Profile Email Scraper](https://apify.com/khadinakbar/linkedin-profile-email-scraper), which starts from a profile URL and looks for an email.\n\n## What you get\n\n| Output | What it answers |\n|---|---|\n| `email` + `matchStatus` | **Which address** was processed and whether a public profile was found |\n| `profileUrl` + `publicIdentifier` | **Where** the person is on LinkedIn |\n| `fullName`, `headline`, `currentCompany`, `location` | **Who they are** at work from public search and optional enrichment |\n| `confidence`, `matchStrategy`, `provider` | **Why this match** was accepted, and which public-data provider supplied it |\n| `clearReason` on CLEAR rows | **Why there is no billable match** — no public hit, role mailbox, or ambiguous result |\n| `OUTPUT` / `RUN_SUMMARY` outcomes | **Provenance** — complete, empty, invalid input, or upstream outage |\n\n## Who it is for (and why it matters)\n\n- **Sales development reps** — attach a LinkedIn URL to inbound or list-bought work emails before a first touch.\n- **Recruiters** — turn a candidate email list into public profiles so you can review headline, company, and location without a LinkedIn seat.\n- **RevOps / CRM owners** — backfill contact records with a canonical `/in/` URL and skip role inboxes like `info@` without paying for them.\n- **AI agents** — one tool call with `emails` returns structured found or CLEAR rows, so the agent can enrich, skip, or route without guessing.\n\n## When to use this Actor\n\n- You have work emails (`first.last@company.com`) and need public LinkedIn profile URLs.\n- You want unmatched addresses recorded as CLEAR so the dataset stays honest.\n- You need optional public-profile enrichment (company URL, followers, about) after a match.\n- When you already have LinkedIn `/in/` URLs, start with [LinkedIn Profile Details Scraper](https://apify.com/khadinakbar/linkedin-profile-details-scraper) for the public about and experience view.\n- When the starting point is a title, company, or location instead of an email, use [LinkedIn Profile Search Scraper](https://apify.com/khadinakbar/linkedin-profile-search-scraper).\n\n## Best fit for this Actor\n\n- Strongest starting condition: a work email whose local-part is a person's name and whose domain is the employer.\n- Useful output: one row per email, billed only when `matchStatus` is `found`.\n- When you need emails validated first, pass the list through [Email Address Validator](https://apify.com/khadinakbar/email-address-validator), then feed the surviving addresses here.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `emails` | array (required) | 1 example email | Up to 100 email addresses per run |\n| `maxItems` | integer | 50 | Cap on **found** profiles saved and billed (CLEAR rows stay outside this cap) |\n| `minConfidence` | integer | 70 | Minimum 0–100 score required to accept a match |\n| `enrichProfiles` | boolean | false | Add company URL, location, followers, about ($0.02/row extra) |\n| `providerOrder` | enum | The default provider order | Public-data provider priority; fallback fires automatically |\n| `maxConcurrency` | integer | 2 | Emails processed in parallel (1–5) |\n\n### Quick start input\n\n```json\n{\n    \"emails\": [\"satya.nadella@microsoft.com\"],\n    \"maxItems\": 1,\n    \"enrichProfiles\": false\n}\n```\n\nThat input selects a single well-known work email so the run stays inside the five-minute quality window and still returns a real found row.\n\n### Example input — bulk work emails, enrichment on\n\n```json\n{\n    \"emails\": [\n        \"satya.nadella@microsoft.com\",\n        \"sundarpichai@google.com\"\n    ],\n    \"maxItems\": 50,\n    \"minConfidence\": 70,\n    \"enrichProfiles\": true\n}\n```\n\nDuplicate emails are deduplicated automatically. Role mailboxes such as `info@company.com` are written as CLEAR and never billed.\n\n## What data you receive\n\nOne dataset item is one email lookup. Found rows carry the LinkedIn identity; CLEAR rows document that the lookup finished with no billable match.\n\n```json\n{\n    \"email\": \"satya.nadella@microsoft.com\",\n    \"matchStatus\": \"found\",\n    \"confidence\": 88,\n    \"profileUrl\": \"https://www.linkedin.com/in/satyanadella\",\n    \"publicIdentifier\": \"satyanadella\",\n    \"fullName\": \"Satya Nadella\",\n    \"headline\": \"Chairman and CEO at Microsoft\",\n    \"currentCompany\": \"Microsoft\",\n    \"matchStrategy\": \"name-company-site\",\n    \"enriched\": false,\n    \"scrapedAt\": \"2026-08-17T00:00:00.000Z\"\n}\n```\n\nCLEAR example:\n\n```json\n{\n    \"email\": \"info@microsoft.com\",\n    \"matchStatus\": \"clear\",\n    \"clearReason\": \"role_mailbox\",\n    \"enriched\": false,\n    \"scrapedAt\": \"2026-08-17T00:00:00.000Z\"\n}\n```\n\nEvery terminal run also writes `OUTPUT` and `RUN_SUMMARY` with a named `outcome`, per-email results, provider diagnostics, and billing counters.\n\n## Workflow story: from a CRM email column to outreach-ready LinkedIn URLs\n\nA RevOps lead exports 40 work emails from a webinar registration list. She pastes them into this Actor with `enrichProfiles: true` and `maxItems` at 40. The run derives a name and company from each `first.last@company.com` address, searches public Google results restricted to LinkedIn profiles, and keeps only matches that clear the confidence bar. Twenty-eight rows come back `found` with profile URLs and current company; nine are CLEAR (`no_public_match` or `role_mailbox`); three stay unmatched because the local-part is a nickname with no public footprint. She then filters `matchStatus=found`, hands the `profileUrl` values to her sequencer, and skips paying for the CLEAR rows. Event cost is 28 × $0.025 plus enrichment on the rows that actually received public profile fields.\n\n## Use through the API\n\n```bash\ncurl -X POST \"https://api.apify.com/v2/acts/khadinakbar~email-to-linkedin-profile-scraper/runs?token=$APIFY_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"emails\": [\"satya.nadella@microsoft.com\"],\n    \"maxItems\": 1,\n    \"enrichProfiles\": false\n  }'\n```\n\nResults land in the run's default dataset: `https://api.apify.com/v2/datasets/{datasetId}/items?clean=true`. Paginate large batches with `offset`/`limit`. The same Actor is exposed through Apify MCP as `apify--email-to-linkedin-profile-scraper`.\n\n## Use with AI agents through Apify MCP\n\n> Given these work email addresses, find each person's public LinkedIn profile URL, name, headline, and company. Return CLEAR for addresses with no public match. Keep only dataset `profileUrl` values. Cap the run at 25 found profiles.\n\nInspect the terminal `outcome`, read the dataset, keep `profileUrl` as the source identifier, and treat `clearReason` as a completed empty lookup for that address. Connect through [Apify MCP](https://mcp.apify.com).\n\n```json\n{\n    \"emails\": [\"satya.nadella@microsoft.com\"],\n    \"maxItems\": 25,\n    \"minConfidence\": 70,\n    \"enrichProfiles\": true,\n    \"maxConcurrency\": 2\n}\n```\n\nThen read results with `get-actor-output`, keep `matchStatus=found` rows for outreach, and pass remaining emails to a validator or a different data source.\n\n## Pricing\n\nThis Actor uses Pay per event with Apify platform usage included. Open the live Pricing tab for current event details, and use Apify's run cost controls to keep the workflow aligned with your budget.\n\n| Event | Price | Charged when |\n|---|---|---|\n| Actor start | $0.00005 | Once per run (scaled by memory) |\n| `profile-found` | $0.025 | One found LinkedIn profile saved |\n| `profile-enriched` | $0.02 | Additional, only when enrichment succeeded |\n\nCLEAR rows, invalid input, and unmatched emails are not billed as `profile-found`.\n\n| Run | Found rows | Enrichment | Event cost (approx.) |\n|---|---|---|---|\n| 1 work email, match | 1 | off | ~$0.025 |\n| 1 work email, match | 1 | on | ~$0.045 |\n| 40 emails, 28 found | 28 | off | ~$0.70 |\n| 40 emails, 28 found | 28 | on | ~$1.26 |\n\nYour run log prints the exact cost cap before any charge fires. Apify platform usage is included in the event price — the live [Pricing tab](https://apify.com/khadinakbar/email-to-linkedin-profile-scraper/pricing) is the current source of truth.\n\n## Best results\n\n- Prefer `first.last@company.com` work emails; they produce name + company search queries.\n- Run [Email Address Validator](https://apify.com/khadinakbar/email-address-validator) first when the list is messy, then look up the surviving addresses here.\n- Keep `minConfidence` at 70 unless you have a reason to accept weaker name-only matches.\n- Turn on `enrichProfiles` when you need location, followers, or a company page URL for routing.\n- After you have profile URLs, pass them to [LinkedIn Profile Details Scraper](https://apify.com/khadinakbar/linkedin-profile-details-scraper) for the public about / experience view, or to [LinkedIn Profile Email Scraper](https://apify.com/khadinakbar/linkedin-profile-email-scraper) only when you started from a profile and need the reverse direction.\n\n## Builder's note\n\nI built this after probing the primary and fallback data providers live: neither vendor exposes an email-to-LinkedIn endpoint, and quoted `\"email\" site:linkedin.com/in` searches are usually empty because people rarely publish their inbox on a public profile. The working public path is Google Search over LinkedIn `/in/` results, using the name and company encoded in a work email, then scoring the hits so `satya.nadella@microsoft.com` keeps the Microsoft CEO and drops the identically named support specialist. That is why this Actor bills found profiles, writes honest CLEAR rows, and keeps ambiguous results out of the found set.\n\n## Responsible use\n\nUse this Actor on emails you are authorized to process for legitimate sales, recruiting, research, or verification. It reads **public web search results and public LinkedIn profile pages only**. It does not log into LinkedIn, does not use your cookies, and is not a private people-graph or data-broker dump. Follow GDPR, CCPA, CAN-SPAM, LinkedIn's terms, and any local law that applies to your outreach. Honor opt-out and do-not-contact requests.\n\nThis tool is provided for lawful public-data collection. You are responsible for how you use the output.\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "fields": {
            "$schema": "http://json-schema.org/draft-07/schema#",
            "type": "object",
            "properties": {
              "email": {
                "type": "string",
                "title": "Email",
                "description": "Normalized email address that was looked up.",
                "example": "satya.nadella@microsoft.com"
              },
              "matchStatus": {
                "type": "string",
                "title": "Match Status",
                "description": "found when a public LinkedIn profile was matched; clear when the lookup completed with no billable match.",
                "enum": [
                  "found",
                  "clear"
                ]
              },
              "clearReason": {
                "type": "string",
                "title": "Clear Reason",
                "description": "Why a valid email produced no billable match.",
                "enum": [
                  "no_public_match",
                  "role_mailbox",
                  "below_confidence",
                  "ambiguous_match"
                ]
              },
              "confidence": {
                "type": [
                  "integer",
                  "null"
                ],
                "title": "Confidence",
                "description": "0-100 match confidence for found rows."
              },
              "profileUrl": {
                "type": "string",
                "title": "LinkedIn Profile URL",
                "description": "Canonical public LinkedIn profile URL for a found match.",
                "example": "https://www.linkedin.com/in/satyanadella"
              },
              "publicIdentifier": {
                "type": "string",
                "title": "Public Identifier",
                "description": "LinkedIn /in/ slug for the matched profile.",
                "example": "satyanadella"
              },
              "fullName": {
                "type": "string",
                "title": "Full Name",
                "description": "Public name from the LinkedIn search result or email local-part."
              },
              "firstName": {
                "type": "string",
                "title": "First Name",
                "description": "Parsed first name."
              },
              "lastName": {
                "type": "string",
                "title": "Last Name",
                "description": "Parsed last name."
              },
              "headline": {
                "type": "string",
                "title": "Headline",
                "description": "Public headline from the LinkedIn search result."
              },
              "currentCompany": {
                "type": "string",
                "title": "Current Company",
                "description": "Company parsed from the search headline, snippet, or enriched profile."
              },
              "currentCompanyUrl": {
                "type": "string",
                "title": "Current Company URL",
                "description": "LinkedIn company page URL from profile enrichment."
              },
              "location": {
                "type": "string",
                "title": "Location",
                "description": "Location from the search snippet or enriched public profile."
              },
              "snippet": {
                "type": "string",
                "title": "Search Snippet",
                "description": "Google snippet used to score the match."
              },
              "searchQuery": {
                "type": "string",
                "title": "Search Query",
                "description": "Google query that produced the accepted match or the last attempted query for a CLEAR row."
              },
              "matchStrategy": {
                "type": "string",
                "title": "Match Strategy",
                "description": "Which lookup strategy produced the row, such as name-company-site or quoted-email-site."
              },
              "enriched": {
                "type": "boolean",
                "title": "Enriched",
                "description": "Whether the found row was enriched with public profile data."
              },
              "followerCount": {
                "type": [
                  "integer",
                  "null"
                ],
                "title": "Follower Count",
                "description": "Follower count from the public profile (enriched rows only)."
              },
              "aboutPreview": {
                "type": "string",
                "title": "About Preview",
                "description": "First 280 characters of the public about section (enriched rows only)."
              },
              "provider": {
                "type": "string",
                "title": "Data Provider",
                "description": "Provider that supplied the Google Search or skip decision.",
                "enum": [
                  "scrapecreators",
                  "sociavault"
                ]
              },
              "enrichmentProvider": {
                "type": "string",
                "title": "Enrichment Provider",
                "description": "Provider that supplied the public profile enrichment.",
                "enum": [
                  "scrapecreators",
                  "sociavault"
                ]
              },
              "scrapedAt": {
                "type": "string",
                "title": "Scraped At",
                "description": "ISO timestamp when the row was saved.",
                "format": "date-time"
              }
            },
            "required": [
              "email",
              "matchStatus",
              "enriched",
              "scrapedAt"
            ]
          },
          "views": {
            "overview": {
              "title": "Email to LinkedIn matches",
              "transformation": {
                "fields": [
                  "email",
                  "matchStatus",
                  "fullName",
                  "profileUrl",
                  "headline",
                  "currentCompany",
                  "location",
                  "confidence",
                  "enriched",
                  "provider",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "profileUrl": {
                    "label": "Profile URL",
                    "format": "link"
                  },
                  "confidence": {
                    "label": "Confidence",
                    "format": "number"
                  },
                  "scrapedAt": {
                    "label": "Scraped At",
                    "format": "date"
                  }
                }
              }
            },
            "foundProfiles": {
              "title": "Found LinkedIn profiles",
              "transformation": {
                "fields": [
                  "email",
                  "fullName",
                  "profileUrl",
                  "headline",
                  "currentCompany",
                  "currentCompanyUrl",
                  "location",
                  "followerCount",
                  "confidence",
                  "provider",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "profileUrl": {
                    "label": "Profile URL",
                    "format": "link"
                  },
                  "currentCompanyUrl": {
                    "label": "Company URL",
                    "format": "link"
                  },
                  "followerCount": {
                    "label": "Followers",
                    "format": "number"
                  },
                  "scrapedAt": {
                    "label": "Scraped At",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "keyValueStore": {
          "actorKeyValueStoreSchemaVersion": 1,
          "title": "Email to LinkedIn Profile Scraper KV Store",
          "collections": {
            "OUTPUT": {
              "title": "Run summary",
              "description": "Compact machine contract: outcome, itemsPushed, profilesFound, clearRows, chargedEventCounts, and warnings.",
              "keyPrefix": "OUTPUT"
            },
            "RUN_SUMMARY": {
              "title": "Run summary alias",
              "description": "Detailed diagnostics including per-email results, provider status codes, billing counters, and stop reason.",
              "keyPrefix": "RUN_SUMMARY"
            }
          }
        }
      },
      "output": {
        "title": "Email to LinkedIn Profile Scraper Output",
        "actorOutputSchemaVersion": 1,
        "description": "Returns one row per email in the default dataset, plus a machine-readable run summary in the default key-value store.",
        "properties": {
          "results": {
            "type": "string",
            "title": "Email to LinkedIn rows",
            "description": "Dataset items containing email, matchStatus, LinkedIn profile URL, name, headline, company, location, and optional enrichment.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          },
          "summary": {
            "type": "string",
            "title": "Run summary",
            "description": "Run summary including outcome, profilesFound, clearRows, provider diagnostics, and billing counters.",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/OUTPUT"
          },
          "runSummary": {
            "type": "string",
            "title": "RUN_SUMMARY alias",
            "description": "Machine-readable RUN_SUMMARY record mirroring OUTPUT for integrations that read RUN_SUMMARY directly.",
            "template": "{{links.apiDefaultKeyValueStoreUrl}}/records/RUN_SUMMARY"
          }
        }
      },
      "environmentVariables": {
        "SCRAPECREATORS_API_KEY": "@SCRAPECREATORS_API_KEY",
        "SOCIAVAULT_API_KEY": "@SOCIAVAULT_API_KEY",
        "SOCIALVAULT_API_KEY": "@SOCIALVAULT_API_KEY"
      },
      "defaultRunOptions": {
        "memoryMbytes": 512,
        "timeoutSecs": 1800
      },
      "dockerfile": "../Dockerfile"
    },
    "buildNumber": "0.1.5",
    "imageDigest": "c9378af7a0245c35201178669ad384e7bc3a9e520dbc0b2104d441d7e6d05f45",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "0.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.01032888888888889
    }
  }
}