LinkedIn Profile Scraper
Pricing
$30.00 / 1,000 profile analyzeds
LinkedIn Profile Scraper
Enrich LinkedIn profiles and companies in bulk — paste URLs or search by keyword/industry/location. Get structured data with name, headline, experience, education, follower count, company size, industry, and 70+ more fields.
Pricing
$30.00 / 1,000 profile analyzeds
Rating
0.0
(0)
Developer
Andrey Afanasenko
Actor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Enrich LinkedIn profiles and companies in bulk — paste URLs or search by keyword/industry/company. Get structured data with name, headline, experience, education, follower count, company size, industry, and 70+ more fields.
🎯 What it does
You feed the actor LinkedIn URLs (profiles or companies) OR a search criteria (keyword + optional industry, or "decision-makers at this company") — it returns clean, structured rows ready for a CRM, sheet, or downstream agent.
- 44 fields per profile —
full_name,headline,about, currentjob_title+company, fullexperiences[]/educations[],follower_count, verification flags, parsed location, current-employer enrichment (industry, employee count, year founded). - 26 fields per company —
company_name,description,tagline,industries[],specialties[],employee_count,employee_range,year_founded,website,logo_url,follower_count, full HQ address,locations[],affiliated_companies[]. - 4 operation modes — Lookup Profile by URL, Lookup Company by URL/Domain, Search Decision-Makers at given companies, Search Companies by keyword.
- 7 advanced filters — follower range, must-have email/phone, open-to-work, country, industry — applied across all modes.
📦 What you get — output sample
{"entity_type": "profile","input": "https://www.linkedin.com/in/satyanadella/","linkedin_url": "https://www.linkedin.com/in/satyanadella","full_name": "Satya Nadella","first_name": "Satya","last_name": "Nadella","headline": "Chairman and CEO at Microsoft","job_title": "Chairman and CEO","company": "Microsoft","company_industry": "Software Development","company_employee_count": 228000,"follower_count": 11489320,"city": "Redmond","country": "United States","is_premium": true,"is_verified": true,"experiences": [ { "title": "CEO", "company": "Microsoft", "starts_at": "2014-02-01" } ],"educations": [ { "school": "University of Chicago", "degree": "MBA" } ],"profile_image_url": "https://media.licdn.com/dms/image/.../satya-nadella.jpg"}
{"entity_type": "company","input": "microsoft.com","linkedin_url": "https://www.linkedin.com/company/microsoft","company_name": "Microsoft","tagline": "Empowering every person and organization on the planet to achieve more.","industries": ["Software Development"],"specialties": ["Software", "Cloud", "AI", "Productivity"],"employee_count": 228000,"employee_range": "10,001+","year_founded": 1975,"follower_count": 25190000,"domain": "microsoft.com","website": "https://news.microsoft.com","logo_url": "https://media.licdn.com/dms/image/.../microsoft-logo.png","hq_city": "Redmond","hq_country": "US"}
Missing optional fields come back as the string "N/A" — every always-emitted column appears in every row, so downstream tools (Sheets / Airtable / CSV) don't have to special-case missing values. See .actor/dataset_schema.json for the full per-column declaration.
⚡ Quick start
Minimal input that works on the free plan:
{"operationMode": "lookupByUrl","profileUrls": ["https://www.linkedin.com/in/satyanadella/"]}
Run, open Storage → Dataset, see one enriched row. Add more URLs to scale up.
🧭 How to use it
- Pick the mode that matches what you have: known LinkedIn URLs (Modes 1/2) vs criteria-based search (Modes 3/4).
- Fill the mode's fields — URL list, or keyword / company URL / job title.
- (Optional) tighten the output with Advanced filtering — minimum followers, must-have email, country/industry match — to drop irrelevant rows before they hit your CRM.
⭐ Choose your mode
🎯 Mode 1 — Lookup Profile by URL
You paste LinkedIn profile URLs, the actor returns one fully-enriched profile row per URL.
Input:
{"operationMode": "lookupByUrl","profileUrls": ["https://www.linkedin.com/in/satyanadella/","https://www.linkedin.com/in/jeffweiner08/"],"maxItemsMode1": 100}
Output: 1 row per URL, 44 fields per row.
Cost control (Mode 1): maxItemsMode1 caps how many profiles you'll pay for in this run. Free plan ceilings to 50 items regardless. Trial runs auto-cap at 10.
🏢 Mode 2 — Lookup Company by URL or Domain
Paste LinkedIn company URLs OR raw domains — each input becomes one company row. Domains are resolved against the company database; URLs are read directly.
Input:
{"operationMode": "companyLookup","companyInputs": ["https://www.linkedin.com/company/microsoft/","anthropic.com","stripe.com"],"maxItemsMode2": 50}
Output: 1 row per input, 26 fields per row.
Cost control (Mode 2): maxItemsMode2. Same free-plan / trial caps as Mode 1.
🔍 Mode 3 — Search Leads (Decision-Makers at given companies)
Give the actor target company URLs + an optional job-title filter. It pulls decision-makers / employees matching the title.
Input:
{"operationMode": "searchLead","searchLeadCompanyUrls": ["https://www.linkedin.com/company/microsoft/","https://www.linkedin.com/company/anthropic/"],"searchLeadJobTitle": "engineering manager","searchLeadCount": 25,"maxItemsMode3": 50}
Output: Slim profile rows for each match (full_name, headline, location, company, job_title, linkedin_url, profile_id). Run a Mode 1 follow-up pass on the returned URLs if you want full 44-field enrichment.
Cost control (Mode 3): maxItemsMode3 caps total leads returned across all source companies. searchLeadCount caps per-company.
🏭 Mode 4 — Search Companies (by keyword)
Free-text keyword search over the LinkedIn company graph, optionally narrowed to specific industries.
Input:
{"operationMode": "searchCompany","searchCompanyKeywords": "saas analytics","searchCompanyIndustries": ["software", "information technology"],"searchCompanyCount": 25,"maxItemsMode4": 50}
Output: Slim company rows for each match (company_name, tagline, domain, industries, employee_count, linkedin_url). Use Mode 2 follow-up for full 26-field enrichment.
Cost control (Mode 4): maxItemsMode4 caps total companies returned.
🛠 Input
| Section | Fields |
|---|---|
| Mode picker | operationMode (required) |
| Mode 1 | profileUrls, maxItemsMode1 |
| Mode 2 | companyInputs, maxItemsMode2 |
| Mode 3 | searchLeadCompanyUrls, searchLeadJobTitle, searchLeadCount, maxItemsMode3 |
| Mode 4 | searchCompanyKeywords, searchCompanyIndustries, searchCompanyCount, maxItemsMode4 |
| Advanced filtering | minFollowers, maxFollowers, mustHaveEmail, mustHavePhone, openToWorkOnly, countryFilter, industryFilter |
See .actor/input_schema.json for the authoritative declaration.
💰 Pricing
Pay-per-event. You're charged once per fetched record, regardless of mode.
| Event | Price | Trigger |
|---|---|---|
| Profile Analyzed | $0.030 | Each profile or company successfully retrieved from upstream and processed by the actor |
Examples:
- 100 profiles in Mode 1 → 100 × $0.030 = $3.00
- 5 companies in Mode 2 → 5 × $0.030 = $0.15
- Mode 3 with 4 target companies × 25 leads each = 100 leads → $3.00
- Mode 4 returning 25 company matches → 25 × $0.030 = $0.75
Filters and billing: Filters narrow your output, not your bill. The paid event fires when the upstream returns the row — even if your filter then drops it. Use cost-control caps (maxItemsModeN) to bound spend; use filters to narrow signal.
🆓 Free vs paid plan
| Free | Paid | |
|---|---|---|
| Items per run | 50 max | unlimited (capped only by your cost-control field) |
| Trial run cap | 10 (auto, when input matches the example) | n/a |
| All 4 modes | ✅ | ✅ |
| Advanced filters | ✅ | ✅ |
| Live status page | ✅ | ✅ |
🧪 Filter recipes
Drop these straight into the input editor.
Find SaaS founders in the US (Mode 4 → Mode 3 → Mode 1):
Step 1 — find SaaS companies:
{"operationMode": "searchCompany","searchCompanyKeywords": "saas","searchCompanyIndustries": ["software"],"countryFilter": "United States","searchCompanyCount": 50}
Step 2 — find founders at those companies (paste company URLs from Step 1):
{"operationMode": "searchLead","searchLeadCompanyUrls": ["...", "...", "..."],"searchLeadJobTitle": "founder","searchLeadCount": 25}
Engineering hiring at top tech companies (Mode 3 with email-only filter):
{"operationMode": "searchLead","searchLeadCompanyUrls": ["https://www.linkedin.com/company/microsoft/","https://www.linkedin.com/company/google/","https://www.linkedin.com/company/anthropic/"],"searchLeadJobTitle": "engineering manager","mustHaveEmail": true,"minFollowers": 500,"searchLeadCount": 50}
Bulk enrich your CRM list (Mode 1 with relevance filter):
{"operationMode": "lookupByUrl","profileUrls": ["...100 URLs..."],"minFollowers": 1000,"industryFilter": "software"}
📡 Live status & storage records
Every run writes structured JSON records to its key-value store, AND serves a live status page over HTTP while running.
| Key | Format | Content |
|---|---|---|
RUN_SUMMARY | JSON | End-of-run aggregate: stop reason, mode, processedCount, paidEventsFired, itemsScraped/Filtered, demoCapped, wallClockSec |
USER_MESSAGE | JSON | First-paid-run welcome / 3rd-run check-in (paid plan) |
FREE_LIMITS_APPLIED | JSON | Which free-plan caps fired (e.g. free_plan_50_items) |
SKIPPED_ITEMS | JSON | Inputs we couldn't process + reason |
status.html | HTML | Live progress page (auto-refreshes every 3s) |
While the run is active, the live page is reachable at the actor's container URL (Apify shows it under "Live view"). For programmatic monitoring:
# Poll JSON statuscurl https://<run-container-url>/api/status
Returns { isRunning, progress: {total, analyzed, saved, skippedByFilters, percentage}, cost: {spent, currency}, timing: {elapsedSeconds, startedAt}, settings: {mode, plan} }.
🤖 Programmatic / API use
# Trigger a run via Apify APIcurl -X POST "https://api.apify.com/v2/acts/afanasenko~linkedin-profile-api-scraper/runs?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"operationMode": "lookupByUrl","profileUrls": ["https://www.linkedin.com/in/satyanadella/"]}'
Fetch dataset items:
$curl "https://api.apify.com/v2/datasets/<datasetId>/items?token=$APIFY_TOKEN&clean=1&format=json"
Read RUN_SUMMARY:
$curl "https://api.apify.com/v2/key-value-stores/<storeId>/records/RUN_SUMMARY?token=$APIFY_TOKEN"
❓ FAQ
Are filters charged?
Filters narrow output, not bill. The paid event fires when a row is fetched; filtering it out doesn't refund. Use maxItemsModeN to cap spend.
Can I scrape private profiles? No. Only public LinkedIn data is available. Profiles set to private return "Profile not found" with no charge.
What's the difference between Mode 3 (slim) and Mode 1 (full)? Mode 3 returns slim rows (10 fields per match) from the search index — cheap way to discover relevant profiles. Feed those URLs back into Mode 1 for full 44-field enrichment.
Is data live? Yes. Each lookup hits LinkedIn's public profile in real time (no stale cache).
Why do I sometimes see a row where most fields are "N/A"? For Mode 3/4 search results, the slim row holds only the search-index fields. Re-run those URLs through Mode 1 / Mode 2 to fill the full schema.
How do I pause / resume a long run? Apify's Resurrect feature works — the actor doesn't keep internal state across resurrections, so each resurrection starts fresh from the input. Better pattern for big lists: split inputs into batches of 500-1000 per run.
🔗 Other LinkedIn / lead-gen scrapers (same author)
| You start with… | You want to find… | Use this actor |
|---|---|---|
| LinkedIn profile URLs | Bulk-enrich profiles + companies | This actor — Mode 1 / Mode 2 |
| Search criteria (keyword / company / job title) | Decision-makers + companies via search index | This actor — Mode 3 / Mode 4 |
| Instagram handles | Profile data + 5 discovery modes (followers, similar, keyword, location) | Instagram Profile Scraper |
| TikTok profile / hashtag | Profile data + posts | TikTok Profile Scraper |
| YouTube channel URL / handle | Channel + video metadata | YouTube Channel Scraper |
| US ZIP / address | Property listings + market data | Zillow Scraper |
🛟 Support & feedback
Found a bug? Have a feature request? Open an issue on the actor's Apify Store page Issues tab — that's the canonical channel and I get a notification on every new issue.
💡 Tips & Best Practices
Getting max results
- For Mode 3 (Search Leads): job-title filter is fuzzy —
engineermatchessoftware engineer,staff engineer,principal engineer. Use specific titles (VP of engineering) when you want narrow. - For Mode 4 (Search Companies): keywords are AND-style —
saas analyticsmatches companies that mention both. Try single keywords first to gauge volume. - For Mode 1: company-URL inputs auto-route through company lookup, so you can mix profile and company URLs in one run.
Cost optimization
- Use
maxItemsModeNaggressively when testing — 5-10 first to validate output, then scale up. - Mode 3 / Mode 4 are cheaper per discovery: 1 search call returns 25-100 slim rows for the same $0.030/row that Mode 1 / Mode 2 charge per fetch.
- Filters don't reduce billing but reduce noise — apply
industryFilter+countryFilterfor tighter targeting BEFORE pasting URLs into a Mode 1 follow-up pass.
Performance
- Large Mode 1 batches (500+) take 2-3 minutes; the actor processes profiles serially to respect upstream rate limits. Live status page shows progress.
- Mode 3 polling waits up to 60s for upstream search to complete — most queries return in 5-10s. If polling times out, reduce
searchLeadCount.
Data quality
- LinkedIn profiles update daily; running the same URL twice in a week may return slightly different
follower_count/headline. - "N/A" is intentional — always-emitted columns let you write
IF(field == "N/A", ...)instead of null-checking. - Search results (Mode 3 / Mode 4) are slim by design — feed URLs into Mode 1 / Mode 2 for full enrichment.
⚖️ Disclaimer
This actor scrapes only publicly available LinkedIn data. You are responsible for using the data in accordance with LinkedIn's Terms of Service, applicable privacy laws (GDPR, CCPA), and ethical-use guidelines. The actor does not scrape private profiles, paid LinkedIn features (Sales Navigator), or content behind login walls.