DEV Community

coreclaw
coreclaw

Posted on

LinkedIn Scraper API: How to Enrich B2B Leads Without Manual Research

LinkedIn Scraper API: How to Enrich B2B Leads Without Manual Research

A LinkedIn scraper API lets you turn public professional profiles and company pages into structured B2B lead data so your sales team can spend time selling instead of copy-pasting. If you are building outbound pipelines, recruiting workflows, or account-research tools, the right approach is not to run a browser automation script yourself; it is to send a structured request to a managed data API and receive normalized JSON you can push straight into a CRM, enrichment queue, or AI agent context.

This article shows what that workflow looks like, where the real operational limits are, and how to keep your data collection lawful and maintainable.

TL;DR

  • A LinkedIn scraper API returns structured public data — job titles, companies, locations, industries, company size, and public profile URLs — from professional pages.
  • The main alternative to a managed API is building headless-browser automation yourself, which means handling proxies, rate limits, session rotation, and layout changes.
  • A production workflow typically sends one request with search filters, polls for completion, then normalizes the JSON response for your CRM or enrichment tool.
  • Always collect only public data, respect LinkedIn's terms and robots directives, and comply with regional privacy rules.
  • For a ready-made B2B data pipeline, start with the CoreClaw product store and check the current CoreClaw pricing for pay-per-result options.

Why Manual LinkedIn Research Hits a Wall

Sales reps and founders know the drill: open a profile, read the headline, copy the name and title, switch tabs to find the company size, guess the industry, paste everything into a spreadsheet, and repeat. It is accurate in small doses, but it does not scale.

The real problems start when you need hundreds or thousands of prospects per week:

  • Fragmented data. A useful lead record combines profile fields, company attributes, and contact context that live on different pages.
  • Stale records. Roles change constantly. Manual exports become outdated before they are imported.
  • Operational drag. Every hour spent researching is an hour not spent on calls, demos, or follow-ups.
  • Infrastructure tax. If you try to automate this yourself, you immediately inherit proxy rotation, session management, CAPTCHA handling, and parser maintenance.

The search intent behind "LinkedIn scraper API" is not "how do I click faster." It is "how do I get reliable structured data without operating the scraping stack."

What Is a LinkedIn Scraper API?

A LinkedIn scraper API is a hosted service that accepts search parameters — such as job title, company, location, or industry — and returns structured records extracted from public LinkedIn pages. It is distinct from the official LinkedIn API, which requires partnership approval and is restricted to approved use cases. A scraper API focuses on publicly visible profile and company information that can be collected without authenticated access to private member data.

The output is usually JSON or JSONL and includes fields like:

  • profile_url — the public URL of the profile or company page
  • name — full name or company name
  • headline — current role or company tagline
  • current_company — employer or organization
  • location — geographic region
  • industry — sector classification
  • company_size — employee range, when visible
  • job_title — current position
  • description — public summary or about text

A managed API handles the rendering, parsing, and normalization for you. The trade-off is cost per result versus the engineering time and risk of running the infrastructure yourself.

A Production-Ready Python Workflow

The example below sends a request to a CoreClaw-compatible endpoint, polls for the result, and writes the structured records to a local JSON file. It uses environment variables for the endpoint and token so you never hardcode credentials or invent a URL.

import json
import os
import time

import requests

# Read configuration from the environment. Never commit real credentials.
API_TOKEN = os.environ["CORECLAW_API_TOKEN"]
ENDPOINT = os.environ["CORECLAW_LINKEDIN_ENDPOINT"]
POLL_INTERVAL = int(os.environ.get("CORECLAW_POLL_SECONDS", "10"))

# Search criteria: public professional profiles matching a role and region.
PAYLOAD = {
    "source": "linkedin",
    "filters": {
        "keywords": "sales director",
        "location": "United States",
        "industry": "Software Development",
    },
    "output_format": "json",
}


def submit_job(endpoint: str, token: str, payload: dict) -> str:
    response = requests.post(
        endpoint,
        headers={
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
        },
        json=payload,
        timeout=60,
    )
    response.raise_for_status()
    job_id = response.json().get("job_id")
    if not job_id:
        raise RuntimeError("No job_id returned by the endpoint.")
    return job_id


def fetch_results(endpoint: str, token: str, job_id: str) -> list[dict]:
    status_url = f"{endpoint.rstrip('/')}/{job_id}"
    while True:
        response = requests.get(
            status_url,
            headers={"Authorization": f"Bearer {token}"},
            timeout=60,
        )
        response.raise_for_status()
        data = response.json()
        status = data.get("status")
        if status == "completed":
            return data.get("results", [])
        if status in {"failed", "error"}:
            raise RuntimeError(f"Job failed: {data.get('message', 'unknown error')}")
        time.sleep(POLL_INTERVAL)


def save_records(records: list[dict], path: str) -> None:
    with open(path, "w", encoding="utf-8") as f:
        json.dump(records, f, indent=2, ensure_ascii=False)


def main() -> None:
    print("Submitting LinkedIn data job...")
    job_id = submit_job(ENDPOINT, API_TOKEN, PAYLOAD)
    print(f"Job submitted: {job_id}. Polling for completion...")

    records = fetch_results(ENDPOINT, API_TOKEN, job_id)
    print(f"Retrieved {len(records)} records.")

    save_records(records, "linkedin_leads.json")
    print("Saved to linkedin_leads.json")


if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

Before running it, set your variables:

export CORECLAW_API_TOKEN="your_token_here"
export CORECLAW_LINKEDIN_ENDPOINT="https://console.coreclaw.com/api/v1/jobs"
export CORECLAW_POLL_SECONDS="10"
python linkedin_leads.py
Enter fullscreen mode Exit fullscreen mode

The exact endpoint path depends on your CoreClaw account and the worker you are running. Copy the current endpoint from your CoreClaw console or worker settings rather than guessing a URL.

Representative Output

A single returned record might look like this:

{
  "profile_url": "https://www.linkedin.com/in/example-profile",
  "name": "Alex Morgan",
  "headline": "VP of Sales at SaaSFlow",
  "current_company": "SaaSFlow",
  "job_title": "VP of Sales",
  "location": "San Francisco, CA",
  "industry": "Software Development",
  "company_size": "51-200 employees",
  "public_identifier": "example-profile"
}
Enter fullscreen mode Exit fullscreen mode

A complete job result is a list of such records. You can pipe the output directly into an enrichment tool, a CRM import, or an AI agent context.

Lead-record checklist

Before importing any records into your sales stack, verify each field:

  • [ ] The profile URL is publicly accessible without logging in.
  • [ ] The record contains only business-relevant attributes.
  • [ ] No private contact details, connection lists, or message content are included.
  • [ ] The data will be refreshed on a schedule that matches your sales cycle.
  • [ ] Your use case complies with LinkedIn's terms and applicable privacy law.

Build vs. Buy: Where the Cost Hides

Approach Best for Setup burden Maintenance burden Scaling risk
Manual research One-off deals, tiny lists None Very high Not scalable
Self-built scraper Engineering teams with scraping expertise Medium High: proxies, parsers, rate limits Moderate
Managed LinkedIn scraper API Sales ops, founders, RevOps, AI-agent builders Low Low: provider handles infrastructure Low

The managed API is usually the cheaper option once you account for engineering time, proxy spend, and the cost of rebuilding parsers after site changes. For teams that want a no-code starting point, the CoreClaw product store lists ready-made workers you can run without writing infrastructure code.

Business Use Cases

  • Outbound sales. Build account lists by industry, company size, and seniority, then pass structured records to your SDR tool.
  • Recruitment intelligence. Map talent pools by role, location, and employer without manually browsing profiles.
  • Account research. Enrich CRM company records with public employee counts, industries, and leadership profiles.
  • Partner discovery. Identify companies and decision-makers in a target ecosystem for channel or integration partnerships.
  • AI-agent context. Feed public business profiles into an agent that drafts personalized outreach or account summaries.

In every case, the value is not the raw HTML; it is the structured, refreshed, import-ready record.

Limitations and Compliance

A scraper API is not a workaround for access controls or private data. Keep the following constraints in mind:

  • Public data only. Do not attempt to collect private messages, connection graphs, email addresses hidden behind login walls, or any data marked as private by the platform.
  • Terms and robots. Respect LinkedIn's Terms of Service and robots directives. A managed provider should operate within the same boundaries.
  • Privacy law. Depending on your jurisdiction, collecting and storing professional data may trigger GDPR, CCPA, or other privacy rules. Have a lawful basis and a retention policy.
  • Rate and freshness. Public profile data changes daily. Results are a snapshot, not a guarantee of current employment.
  • Regional variation. Public page layouts and available fields differ by geography and account type, which can affect field coverage.

For a deeper look at public web data compliance, see the CoreClaw public web data compliance guide (Chinese-language public-web-data reference).

FAQ

Is there an official LinkedIn API for lead generation?
LinkedIn offers partner programs and restricted APIs, but general lead-generation access requires approval and is limited to approved use cases. A scraper API focuses on publicly visible data without authenticated member access.

What data fields are typically returned?
Public profile fields such as name, headline, current company, job title, location, industry, company size, and public profile URL. Private contact information and connection networks are out of scope.

How often should the workflow run?
For active pipelines, refresh target lists weekly or bi-weekly. For account research, monthly refreshes are usually enough. Match the cadence to your sales cycle and refresh only what you actually use.

Can I connect this to a CRM or n8n?
Yes. The JSON output is designed to be mapped into CRM imports, Google Sheets, Airtable, or automation platforms. Use the provider's documented integration or a simple webhook.

What happens when LinkedIn changes its layout?
A managed provider updates the parser. If you self-host, you own the fix. That difference is often the main reason teams switch to a hosted API.

How do I verify an endpoint before production use?
Start with a small test query, confirm the returned fields match your schema, and check that every record is from a public page. Only scale after validating output quality and legal compliance.

What should I look for in pricing?
Look for transparent per-result pricing rather than bundled proxy credits. Check the current CoreClaw pricing page to compare pay-per-result options.

Where to Go Next

If you are building B2B lead workflows, the next step is to choose a data source and a delivery target, then run a small test job before scaling.

Start with one role-and-region query, validate the output, and build your enrichment pipeline from there.

Top comments (0)