Back to Blog
Tutorial

LinkedIn Scraping API: Extract Profiles, Companies & Jobs (2026)

February 19, 2026
8 min read
S
By SociaVault Team
LinkedIn ScrapingLinkedIn APIData ExtractionB2B DataPythonJavaScriptLead Generation

LinkedIn Scraping API: Extract Profiles, Companies & Jobs

LinkedIn has the best B2B data on the internet. 1 billion professionals. 65 million companies. Decision-makers, job titles, company sizes, funding data—all in one place.

But LinkedIn's official API? Nearly useless for data extraction. They shut down most endpoints in 2015.

This guide shows you how to use a LinkedIn scraping API to get the data you actually need.

Why LinkedIn's Official API Falls Short

Here's what LinkedIn's API lets you do (and doesn't):

Can DoCan't Do
Post to your own profileSearch for people
Get your own connectionsGet company employees
Share updatesExtract profile details
Basic profile (with user permission)Bulk data extraction

For any serious B2B use case—lead generation, market research, competitor analysis—you need scraping.

What You Can Scrape from LinkedIn

Data TypeWhat You Get
ProfilesName, headline, location, current company, experience, education, skills
CompaniesName, industry, size, headquarters, description, employee count, funding
JobsTitle, company, location, description, requirements, posted date
PostsContent, likes, comments, shares, author info
Search ResultsPeople matching filters (title, company, location)

All publicly visible data—the same information anyone sees on linkedin.com without logging in.

LinkedIn Scraping API: How It Works

A scraping API handles all the complexity:

  • Proxy rotation and IP management
  • Browser fingerprinting
  • Rate limit handling
  • CAPTCHA solving
  • Data parsing and normalization

You just make HTTP requests and receive clean JSON data.

Extract a LinkedIn Profile

const API_KEY = 'your_sociavault_api_key';

async function getLinkedInProfile(profileUrl) {
  const response = await fetch(
    `https://api.sociavault.com/v1/scrape/linkedin/profile?url=${encodeURIComponent(profileUrl)}`,
    {
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      }
    }
  );
  
  return response.json();
}

// Usage
const profile = await getLinkedInProfile('https://www.linkedin.com/in/satyanadella/');

console.log(profile);
/* Response:
{
  "success": true,
  "data": {
    "name": "Satya Nadella",
    "headline": "Chairman and CEO at Microsoft",
    "location": "Redmond, Washington, United States",
    "connections": "500+",
    "about": "...",
    "experience": [
      {
        "title": "Chairman and CEO",
        "company": "Microsoft",
        "duration": "10+ years",
        "description": "..."
      }
    ],
    "education": [...],
    "skills": [...]
  }
}
*/

Python Example

import requests

API_KEY = 'your_sociavault_api_key'
BASE_URL = 'https://api.sociavault.com/v1/scrape/linkedin'

def get_linkedin_profile(profile_url):
    response = requests.get(
        f'{BASE_URL}/profile',
        params={'url': profile_url},
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    return response.json()

def get_company_info(company_url):
    response = requests.get(
        f'{BASE_URL}/company',
        params={'url': company_url},
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    return response.json()

# Usage
profile = get_linkedin_profile('https://www.linkedin.com/in/jeffweiner08/')
print(f"Name: {profile['data']['name']}")
print(f"Headline: {profile['data']['headline']}")

Extract Company Data

async function getLinkedInCompany(companyUrl) {
  const response = await fetch(
    `https://api.sociavault.com/v1/scrape/linkedin/company?url=${encodeURIComponent(companyUrl)}`,
    {
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      }
    }
  );
  
  return response.json();
}

// Get company information
const company = await getLinkedInCompany('https://www.linkedin.com/company/stripe/');

console.log(company);
/* Response:
{
  "success": true,
  "data": {
    "name": "Stripe",
    "industry": "Financial Services",
    "company_size": "5,001-10,000 employees",
    "headquarters": "San Francisco, California",
    "founded": "2010",
    "specialties": ["Payments", "APIs", "Developer Tools"],
    "website": "https://stripe.com",
    "about": "..."
  }
}
*/

Scrape Job Listings

async function getJobListings(companyUrl, limit = 20) {
  const response = await fetch(
    `https://api.sociavault.com/v1/scrape/linkedin/jobs?company_url=${encodeURIComponent(companyUrl)}&limit=${limit}`,
    {
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      }
    }
  );
  
  return response.json();
}

// Get open positions at a company
const jobs = await getJobListings('https://www.linkedin.com/company/openai/', 50);

jobs.data.forEach(job => {
  console.log({
    title: job.title,
    location: job.location,
    postedDate: job.posted_date,
    applicants: job.applicant_count
  });
});

Use Cases

1. B2B Lead Generation

Build targeted prospect lists:

async function buildProspectList(profiles) {
  const prospects = [];
  
  for (const profileUrl of profiles) {
    const result = await getLinkedInProfile(profileUrl);
    
    if (result.success) {
      const { data } = result;
      
      prospects.push({
        name: data.name,
        title: data.headline,
        company: data.experience?.[0]?.company,
        location: data.location,
        profileUrl: profileUrl,
        skills: data.skills?.slice(0, 5)
      });
    }
    
    // Rate limiting courtesy
    await new Promise(r => setTimeout(r, 500));
  }
  
  return prospects;
}

// Export to CSV
function exportToCSV(prospects) {
  const headers = ['name', 'title', 'company', 'location', 'profileUrl'];
  const rows = prospects.map(p => headers.map(h => `"${p[h] || ''}"`).join(','));
  
  return [headers.join(','), ...rows].join('\n');
}

Related: B2B Lead Generation with Social Media Data

2. Competitor Employee Analysis

Track hiring and team composition:

import requests

def analyze_competitor_team(company_url, target_departments):
    # Get company info
    company = get_company_info(company_url)
    
    # Get employees (from company page)
    employees = requests.get(
        f'{BASE_URL}/company/employees',
        params={'url': company_url, 'limit': 100},
        headers={'Authorization': f'Bearer {API_KEY}'}
    ).json()
    
    # Analyze by department
    department_counts = {}
    for emp in employees.get('data', []):
        for dept in target_departments:
            if dept.lower() in emp.get('headline', '').lower():
                department_counts[dept] = department_counts.get(dept, 0) + 1
    
    return {
        'company': company['data']['name'],
        'total_employees': company['data']['company_size'],
        'departments': department_counts
    }

# Analyze engineering team size
result = analyze_competitor_team(
    'https://www.linkedin.com/company/vercel/',
    ['Engineering', 'Product', 'Sales', 'Marketing']
)
print(result)

3. Market Research

Analyze industry trends:

async function analyzeIndustryHiring(companies) {
  const results = [];
  
  for (const companyUrl of companies) {
    const jobs = await getJobListings(companyUrl, 100);
    
    // Count job types
    const jobTypes = {};
    jobs.data.forEach(job => {
      const category = categorizeJob(job.title);
      jobTypes[category] = (jobTypes[category] || 0) + 1;
    });
    
    results.push({
      company: companyUrl.split('/company/')[1].replace('/', ''),
      totalOpenings: jobs.data.length,
      breakdown: jobTypes
    });
  }
  
  return results;
}

function categorizeJob(title) {
  const lower = title.toLowerCase();
  if (lower.includes('engineer') || lower.includes('developer')) return 'Engineering';
  if (lower.includes('sales') || lower.includes('account')) return 'Sales';
  if (lower.includes('marketing') || lower.includes('growth')) return 'Marketing';
  if (lower.includes('product')) return 'Product';
  if (lower.includes('design')) return 'Design';
  return 'Other';
}

// Compare fintech hiring
const fintechCompanies = [
  'https://www.linkedin.com/company/stripe/',
  'https://www.linkedin.com/company/plaid/',
  'https://www.linkedin.com/company/wise/'
];

analyzeIndustryHiring(fintechCompanies).then(console.table);

4. Enrich CRM Data

Add LinkedIn data to your contacts:

async function enrichCRMContacts(contacts) {
  const enriched = [];
  
  for (const contact of contacts) {
    // Find LinkedIn URL if not present
    let linkedInUrl = contact.linkedInUrl;
    
    if (!linkedInUrl && contact.name && contact.company) {
      // Search for profile
      const search = await searchLinkedIn(contact.name, contact.company);
      linkedInUrl = search.data?.[0]?.profile_url;
    }
    
    if (linkedInUrl) {
      const profile = await getLinkedInProfile(linkedInUrl);
      
      enriched.push({
        ...contact,
        linkedInUrl,
        currentTitle: profile.data?.headline,
        location: profile.data?.location,
        skills: profile.data?.skills?.slice(0, 5),
        experience: profile.data?.experience?.length,
        enrichedAt: new Date().toISOString()
      });
    } else {
      enriched.push({ ...contact, enriched: false });
    }
    
    await new Promise(r => setTimeout(r, 500));
  }
  
  return enriched;
}

Storing LinkedIn Data

SQLite Database

const Database = require('better-sqlite3');
const db = new Database('linkedin_data.db');

db.exec(`
  CREATE TABLE IF NOT EXISTS profiles (
    profile_url TEXT PRIMARY KEY,
    name TEXT,
    headline TEXT,
    location TEXT,
    company TEXT,
    connections TEXT,
    scraped_at TEXT
  );
  
  CREATE TABLE IF NOT EXISTS companies (
    company_url TEXT PRIMARY KEY,
    name TEXT,
    industry TEXT,
    company_size TEXT,
    headquarters TEXT,
    founded TEXT,
    scraped_at TEXT
  );
`);

function saveProfile(profileUrl, data) {
  const stmt = db.prepare(`
    INSERT OR REPLACE INTO profiles 
    VALUES (?, ?, ?, ?, ?, ?, datetime('now'))
  `);
  
  stmt.run(
    profileUrl,
    data.name,
    data.headline,
    data.location,
    data.experience?.[0]?.company || null,
    data.connections
  );
}

function saveCompany(companyUrl, data) {
  const stmt = db.prepare(`
    INSERT OR REPLACE INTO companies 
    VALUES (?, ?, ?, ?, ?, ?, datetime('now'))
  `);
  
  stmt.run(
    companyUrl,
    data.name,
    data.industry,
    data.company_size,
    data.headquarters,
    data.founded
  );
}

Scraping public LinkedIn data is legal when you:

  • ✅ Only access publicly visible information (no login required)
  • ✅ Don't bypass authentication or access controls
  • ✅ Respect rate limits
  • ✅ Don't use data for spam or harassment
  • ✅ Comply with GDPR/CCPA for personal data

The landmark hiQ Labs v. LinkedIn case (2022) established that scraping public LinkedIn profiles doesn't violate the Computer Fraud and Abuse Act.

Read more: LinkedIn Scraping Legal Guide

API vs DIY Scraping

DIY ScrapingAPI
Build proxy infrastructureProxies included
Handle browser fingerprintingHandled for you
Fix when LinkedIn changesAlways maintained
Risk account bansNo account needed
$300-500/month infrastructurePay per request

For anything beyond a few dozen profiles, an API is far more practical.

Getting Started

  1. Sign up at sociavault.com
  2. Get 50 free credits to test
  3. Copy your API key from the dashboard
  4. Start extracting LinkedIn data

Frequently Asked Questions

Yes, scraping publicly visible LinkedIn data is legal. The hiQ Labs case established this precedent. However, never scrape data behind login walls or violate privacy laws.

Does LinkedIn block scraping?

LinkedIn actively blocks scrapers. That's why using an API is recommended—it handles proxy rotation, browser fingerprinting, and anti-bot detection.

Can I get email addresses from LinkedIn?

Email addresses aren't publicly displayed on LinkedIn. You'd need the profile owner's permission or use an email finder service separately.

How accurate is scraped LinkedIn data?

Data accuracy depends on when users last updated their profiles. For best results, focus on verified information like current company and title.


Related guides:

Found this helpful?

Share it with others who might benefit

Ready to Try SociaVault?

Start extracting social media data with our powerful API. No credit card required.