LinkedIn Jobs Scraper | Experience Filters & Company Data avatar

LinkedIn Jobs Scraper | Experience Filters & Company Data

Pricing

from $0.25 / 1,000 results

Go to Apify Store
LinkedIn Jobs Scraper | Experience Filters & Company Data

LinkedIn Jobs Scraper | Experience Filters & Company Data

Scrape LinkedIn job listings worldwide by keyword and place or from search URLs, no login. Experience-level and job-type filters that really work, company website, size, industry, followers and HQ address, parsed pay range, applicant count, Easy Apply, plus incremental alerts.

Pricing

from $0.25 / 1,000 results

Rating

0.0

(0)

Developer

Corvuslab

Corvuslab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

What does LinkedIn Jobs Scraper do?

LinkedIn Jobs Scraper extracts public job listings from linkedin.com/jobs in 137 countries. Its headline is experience-level and job-type filters that actually work: LinkedIn's public search quietly ignores both, so this Actor checks each posting's own seniority and employment type, and jobs that don't match are skipped and cost nothing. Pay, company size, industry, keyword and agency filters work the same way. Each job comes with up to 70 fields: full description, seniority, job type, applicants, Easy Apply or external, matched skills, a one-line AI summary, pay when the employer lists it, and an optional company profile (website, industry, size, followers, HQ address) at no extra cost.

Search by keyword and place, a whole country, a region group like DACH or the EU-27, or a company name, or paste LinkedIn search and job URLs. With no input at all you get the newest US jobs. Incremental mode returns and charges only new and changed jobs, with alerts to Telegram, Slack, Discord, WhatsApp or a webhook. Export to JSON, CSV or Excel, use the API, or feed an AI agent. No LinkedIn login or cookies needed from you.

New to Apify? Sign up free and use the included monthly platform credit to try this Actor. No credit card needed.

Why this scraper

  • 🎯 Filters you can trust: experience level and job type are checked on each posting, so "Entry level, Full-time" means exactly that.
  • 🏢 Company data included: website, size, industry, followers and HQ address at the same per-job price.
  • 💰 Pay you can filter on: employer-stated ranges parsed into numbers, currency and period, plus a yearly figure for comparing and filtering.
  • ♻️ Cheap to monitor: incremental mode skips unchanged jobs before their posting is read, and skipped jobs cost nothing.

What data can you extract from LinkedIn?

Every record carries up to 70 fields, grouped like this:

GroupWhat you get
Jobtitle, url, id, location, country, countryCode, postedDate, postedAgo, listingBadge (e.g. "Actively Hiring"), isClosed
Job criteria & skillsseniorityLevel, employmentType, industries, applyType (EASY_APPLY / EXTERNAL), skills (matched from the description), language (e.g. en, de), isAgency (posted by a staffing or recruiting firm)
Pay (when the employer lists it)salaryText, salaryMin, salaryMax, salaryCurrency (ISO code), salaryPeriod (YEAR, MONTH, HOUR…), salarySource, plus salaryYearlyMin / salaryYearlyMax
Demand & hiring teamapplicantsCount as a number, applicantsText, plus jobPosterName, jobPosterTitle and jobPosterProfileUrl when LinkedIn shows the hiring team
Description, summary & contactsdescription as plain text, descriptionHtml, descriptionMarkdown, aiSummary (one line for AI agents and ATS imports), plus extractedEmails, extractedPhones, extractedUrls and socialProfiles when the employer writes them into the posting
Companycompany, companyUrl, companySlug, companyLogo, and with company details on: companyId, companyWebsite, companyIndustry, companySize, companyEmployeesOnLinkedIn, companyFollowers, companyHeadquarters, companyStreetAddress, companyPostalCode, companyCountryCode, companyType, companySpecialties, companySlogan, companyDescription
MonitoringchangeType, firstSeenAt, lastSeenAt, previousSeenAt, expiredAt, isRepost, repostOfId, repostDetectedAt, contentHash, plus searchKeyword / searchLocation showing which search found the job

Key features

  • 🎯 Experience-level and job-type filters that actually work: LinkedIn's public search ignores both and returns every level and type. This Actor reads each posting's own seniority (Internship to Executive) and employment type (Full-time, Contract…) and keeps only the matches. Non-matching jobs are not charged.
  • 🏢 Company profiles in the same price: website, industry, size band, employees on LinkedIn, followers, HQ street address, postal and country code, type and specialties. No add-on event; each company is read once per run.
  • 💰 Pay as numbers, and a pay filter: CA$55,000.00/yr - CA$60,000.00/yr becomes min 55000, max 60000, CAD, YEAR, plus yearly equivalents for hourly, daily, weekly and monthly pay. Filter by a yearly minimum or maximum in 15 currencies.
  • 🌍 Countries and region groups: 137 countries, or one click for DACH, Nordics, Benelux, UK & Ireland, EU-27, GCC, MENA, ASEAN, Latin America or the Anglosphere. Each country is its own search with LinkedIn's full 1,000-job view.
  • 🏢 Companies by name: type "Google" or paste a company URL; it's matched to the right LinkedIn company and searched exactly.
  • 🚫 Skip staffing agencies: one switch drops staffing, recruiting and headhunting firms, by the employer's LinkedIn industry and name. Every record carries isAgency.
  • 🎚️ More filters, none charged when they drop a job: description must contain (e.g. "visa sponsorship"), exclude keywords, industry, company size, hiring team shown, title words, excluded companies, known job IDs. Plus LinkedIn's Easy Apply, under 10 applicants and a custom last N hours window.
  • 🧠 Skills, language and an AI summary: skills are matched against a curated skill list (most postings get at least one), language is the description's language, and aiSummary puts the whole job in one line.
  • ♻️ Incremental monitoring: schedule it and get only NEW / UPDATED / REAPPEARED / EXPIRED jobs. Unchanged jobs are never charged; re-posts can be flagged or skipped.
  • 🔔 Notifications: Telegram, Slack, Discord, WhatsApp or any webhook (n8n / Make / Zapier).

🚀 How to scrape LinkedIn jobs

  1. Enter one or more keywords (e.g. data analyst) and places like London, England, United Kingdom, or pick countries or a region group. Or paste a LinkedIn job-search URL.
  2. Pick your filters: experience level, job type, posted within, pay, company size, industry, description words, agencies.
  3. Set Max results and decide whether to add company details.
  4. (Optional) Turn on incremental mode and a notification channel, then Schedule it.
  5. Click Start and download the results as JSON, CSV or Excel, or pull them from the API.

No LinkedIn account, no login, no cookies: it runs out of the box.

Quick-start example input

{
"searchTerms": ["data analyst"],
"locations": ["London, England, United Kingdom"],
"experienceLevels": ["entryLevel", "associate"],
"employmentTypes": ["fullTime"],
"postedWithin": "pastWeek",
"includeCompanyDetails": true,
"maxResults": 100
}

This returns up to 100 full-time, entry-level or associate data analyst jobs posted in London in the past week. Each one really carries that seniority and job type, plus the full description, applicants and the hiring company's profile.


Input

Use the visual editor or pass JSON via the API. 58 inputs, grouped as in the editor.

FieldTypeWhat it does
searchTermsarrayJob titles or skills, as typed on LinkedIn; each keyword is its own search in every place. Empty = newest jobs.
locationsarrayCountries, regions or cities ("Berlin") or a LinkedIn geoId. Empty = United States.
countriesarray (select)137 countries, one search each.
regionPresetsarray (select)dach, nordics, benelux, ukIreland, eu27, gcc, mena, asean, latam, anglosphere; one search per member country.
distancestring (select)Radius around a city: 5 to 100 miles.
startUrlsarrayLinkedIn job-search URLs (filters kept) or job URLs; replaces the search form.
maxResultsintegerMaximum jobs across all searches (default 25, 0 = no limit).
maxResultsPerSearchintegerCap each keyword × place search (up to 1,000).

🎚️ Filters

FieldTypeWhat it does
postedWithinenumAny time, past24Hours, pastWeek or pastMonth.
postedWithinHoursintegerCustom window in hours (1–720), e.g. 1 or 6 for frequent schedules. Overrides postedWithin.
experienceLevelsarray (enum)internship, entryLevel, associate, midSenior, director, executive, notApplicable, checked on each posting.
employmentTypesarray (enum)fullTime, partTime, contract, temporary, internship, volunteer, other, checked on each posting.
easyApplyOnlybooleanOnly jobs you can apply to directly on LinkedIn.
under10ApplicantsbooleanOnly jobs fewer than 10 people have applied to so far.
companiesarrayOnly jobs at these companies, by name ("Google") or LinkedIn company URL.
companyIdsarrayThe same by LinkedIn company ID (the number after f_C= in a company's job-search URL, e.g. 1441).
titleIncludes / titleExcludesarrayTitle must / must not contain these words.
excludeCompaniesarrayDrop jobs from companies whose name contains any of these.
excludeAgenciesbooleanDrop jobs from staffing, recruitment and headhunting firms.
excludeKeywordsarrayDrop jobs whose title or description mentions any of these, e.g. "commission only".
descriptionIncludesarrayKeep only jobs whose description mentions one of these, e.g. "visa sponsorship".
industryIncludesarrayKeep only jobs whose LinkedIn industry contains one of these, e.g. "Software Development".
requireSalarybooleanKeep only jobs where the employer lists pay.
salaryMin / salaryMaxintegerYearly pay bounds (hourly × 2080, daily × 260, weekly × 52, monthly × 12).
salaryCurrencyenumCurrency of the bounds: USD (default), EUR, GBP, CAD, AUD, INR, CHF and 8 more.
includeUnknownSalarybooleanAlso keep jobs without comparable pay.
requireJobPosterbooleanKeep only jobs that show the hiring team.
companySizeMin / companySizeMaxintegerCompany size band bounds, e.g. 51 to 200 (reads company details automatically).
skipJobIdsarrayJob IDs or URLs you already have.

Every filter from experienceLevels down is checked by the Actor itself, and a job it drops is never charged.

📦 Output

FieldTypeWhat it does
includeDetailsbooleanRead the full posting (default on). Off = a faster, card-only run.
includeCompanyDetailsbooleanAdd the hiring company's profile.
descriptionFormatenumall, text, html or markdown.
descriptionMaxLengthintegerCut descriptions to this many characters (0 = full length).
compactbooleanCore fields only, for AI agents and MCP clients.
excludeEmptyFieldsbooleanDrop null, empty-string and empty-list fields.

♻️ Incremental monitoring

FieldTypeWhat it does
incrementalModebooleanTag jobs NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED; unchanged ones aren't charged.
stateKeystringStable name for the tracked search (auto-derived from your settings if blank).
emitUnchangedbooleanAlso return jobs that haven't changed.
emitExpiredbooleanReturn jobs that were listed last run but are gone now.
skipRepostsbooleanLeave out jobs re-posted under a new ID.

🔔 Notifications

Channels are off unless filled in. Credentials are encrypted, masked and never logged.

FieldTypeWhat it does
telegramToken + telegramChatIdstringTelegram bot token (from @BotFather) + chat or channel ID.
slackWebhookUrl / discordWebhookUrlstringIncoming webhook URL.
whatsappAccessToken + whatsappPhoneNumberId + whatsappTostring / arrayWhatsApp Cloud API token, your business phone-number ID and recipient numbers.
webhookUrl + webhookHeadersstring / objectPOST every matched job (up to 1,000 per run) as JSON.
notificationLimitintegerJobs listed per chat message (1–20, default 5).
notifyOnlyChangesbooleanIn incremental mode, alert only on new, updated and reappeared jobs.

⚙️ Advanced

FieldTypeWhat it does
proxyConfigurationobjectConnection settings. Keep the default for reliable runs.
detailConcurrencyintegerHow many postings to read at the same time (1–16, default 10).
ignoreUrlFailuresbooleanSkip unreadable start URLs instead of failing.
maxRequestRetriesintegerRetries for a failed request (0–10, default 6).

More example inputs

Paste a LinkedIn search URL (its filters are kept) and a single job URL:

{
"startUrls": [
{ "url": "https://www.linkedin.com/jobs/search?keywords=product%20manager&location=Germany&f_TPR=r86400" },
{ "url": "https://www.linkedin.com/jobs/view/4480525670" }
],
"includeCompanyDetails": true
}

Watch two searches in two cities every few hours, skip agencies and get a Telegram alert for each new job:

{
"searchTerms": ["python developer", "backend engineer"],
"locations": ["Berlin", "Munich"],
"postedWithinHours": 6,
"excludeAgencies": true,
"incrementalMode": true,
"notifyOnlyChanges": true,
"telegramToken": "<your bot token>",
"telegramChatId": "@yourchannel",
"maxResults": 0
}

Data engineering jobs across the Nordics that state at least 60,000 a year in euros, at companies of 51+ people:

{
"searchTerms": ["data engineer"],
"regionPresets": ["nordics"],
"salaryMin": 60000,
"salaryCurrency": "EUR",
"companySizeMin": 51,
"maxResultsPerSearch": 200
}

Senior roles at named companies that still have few applicants:

{
"companies": ["Google", "https://www.linkedin.com/company/microsoft"],
"countries": ["US", "GB"],
"titleIncludes": ["senior", "staff"],
"under10Applicants": true
}

Output

Each dataset item is one LinkedIn job. A real record (descriptions shortened here):

{
"id": "4480525670",
"url": "https://www.linkedin.com/jobs/view/4480525670",
"title": "Junior Accountant",
"company": "Peak Associates Limited",
"companyUrl": "https://ca.linkedin.com/company/peak-associates-limited",
"location": "North York, Ontario, Canada",
"country": "Canada",
"countryCode": "CA",
"postedDate": "2026-10-16",
"postedAgo": "6 days ago",
"listingBadge": "Actively Hiring",
"salaryText": "CA$55,000.00/yr - CA$60,000.00/yr",
"salaryMin": 55000.0,
"salaryMax": 60000.0,
"salaryCurrency": "CAD",
"salaryPeriod": "YEAR",
"salarySource": "EMPLOYER",
"salaryYearlyMin": 55000.0,
"salaryYearlyMax": 60000.0,
"applicantsCount": 200,
"applicantsText": "Over 200 applicants",
"seniorityLevel": "Associate",
"employmentType": "Full-time",
"industries": "Staffing and Recruiting",
"applyType": "EASY_APPLY",
"isAgency": true,
"isClosed": false,
"skills": ["Excel", "Accounting", "GAAP", "Accounts Payable", "Accounts Receivable", "CPA", "Time Management"],
"language": "en",
"aiSummary": "Junior Accountant at Peak Associates Limited (North York, Ontario, Canada) · Full-time · Associate · pay CA$55,000.00/yr - CA$60,000.00/yr · Easy Apply · Over 200 applicants · posted 2026-10-16 · industry: Staffing and Recruiting · skills: Excel, Accounting, GAAP, Accounts Payable, Accounts Receivable, CPA, Time Management",
"description": "Our client is seeking a Junior Accountant reporting to the Director of Accounting to join their team in Toronto. …",
"companyWebsite": "http://www.peakassociates.com",
"companyIndustry": "Staffing and Recruiting",
"companySize": "11-50 employees",
"companyEmployeesOnLinkedIn": 10,
"companyFollowers": 58622,
"companyHeadquarters": "Toronto, ON",
"companyStreetAddress": "2345 Yonge Street, Suite 505",
"companyPostalCode": "M4P 2E5",
"companyCountryCode": "CA",
"companyType": "Privately Held",
"companySpecialties": ["Recruitment", "Temporary Staffing Services", "Talent Acquisition", "Executive Search"],
"source": "linkedin.com",
"searchKeyword": "accountant",
"searchLocation": "Toronto",
"scrapedAt": "2026-10-23T12:34:26.021163+00:00",
"detailFetched": true
}

Descriptions also come as descriptionHtml and descriptionMarkdown. This posting comes from a recruitment firm, so it has isAgency: true, and Exclude staffing & recruiting agencies would have dropped it at no cost. In incremental mode each record carries a changeType (NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED) with firstSeenAt / lastSeenAt, and EXPIRED jobs get expiredAt. A job read by its URL after it stopped taking applications comes back with isClosed: true.

Data fields

Card fields are always there; Fetch the full job posting adds description, criteria, skills, language, AI summary, agency flag, applicants, apply type, pay and hiring team; Add company details adds the company profile including companyId.

Every field is present in standard mode (missing values are null); compact mode returns the core fields only, for lean AI/MCP payloads; excludeEmptyFields drops empties entirely. The Output tab ships two ready-made views: Overview (one row per job) and Companies (website, industry, size, HQ per open role).


♻️ How to monitor LinkedIn jobs with incremental mode

Schedule the Actor and turn on incremental mode: each run compares against the last and returns only NEW / UPDATED / REAPPEARED / EXPIRED jobs. Unchanged jobs are recognised from the search results before their posting is read, so you skip both the work and the cost.

First run (baseline)Next run (nothing changed)
Jobs found in the searchallall
Postings readallnone
Jobs returned & chargedallnone

Your cost after the baseline scales with how much the search changes, not with how much you watch:

Daily churnof 1,000 trackedbillable jobsyou save
5 %1,0005095 %
15 %1,00015085 %
30 %1,00030070 %

Re-posts under a new ID are flagged with isRepost / repostOfId, or left out with Skip re-posted jobs. EXPIRED needs a run that reads the whole search: Max results 0, and each search under 1,000 jobs.

Setting up scheduled monitoring

  1. Configure your search and filters; a last N hours window matching your schedule keeps runs small.
  2. Turn on Incremental mode.
  3. Run it once to seed the baseline.
  4. Open the Schedules tab and set a recurring run (e.g. every hour or every morning).
  5. Add a notification channel with Alert only on changes on.

🔔 How to set up LinkedIn job alerts

Fill in only the channels you want:

ChannelWhat to configure
✈️ TelegramtelegramToken (from @BotFather) + telegramChatId
💬 SlackslackWebhookUrl (Incoming Webhook URL)
🎮 DiscorddiscordWebhookUrl (channel webhook URL)
🟢 WhatsAppwhatsappAccessToken + whatsappPhoneNumberId (WhatsApp Cloud API) + whatsappTo numbers
🪝 WebhookwebhookUrl receives every matched job as structured JSON, ideal for n8n / Make / Zapier

Each message lists the title, company, place, pay and link for up to notificationLimit jobs. A broken channel can't stop the scrape or the others. WhatsApp follows Meta's 24-hour rule: a free-form message only reaches a number that has written to your business number in the last 24 hours, so have each recipient message it first. Pair incremental mode with Alert only on changes to hear only about genuinely new jobs.


💡 What can you do with LinkedIn data?

Get job alerts that match your level

Set your level, Full-time and a 1-hour window, schedule it hourly and get a ping for every fresh posting. Add fewer than 10 applicants to apply early.

Recruiting and sales lead generation

Every company posting a job is hiring. Get its website, size, industry and HQ with each job, filter by size, and drop agencies for a clean list of direct employers.

Salary benchmarking

Collect employer-stated pay ranges with currency and period, and compare roles, levels and countries on the yearly figures. Turn on Only jobs with a stated pay range to skip the rest at no cost.

Labour-market and competitor research

Track how many roles a competitor opens, where, at which levels and with which skills, week by week. Region groups cover a whole market in one run.

Feed AI agents and LLM pipelines

aiSummary gives an agent or ATS the whole job in one line, and skills is ready for CV matching. Compact mode and excludeEmptyFields keep token costs low.


💰 How much does it cost to scrape LinkedIn?

This Actor uses Apify's pay-per-event model: a tiny fee when a run starts, plus one fee for each job you receive. See the Pricing tab for the live numbers.

The full posting and the company profile are part of that one price: there is no separate charge for company data. Three things cut your bill further:

  • Filters that skip before charging: jobs that fail the experience-level, job-type, pay, company-size, industry, keyword, agency or title filters are dropped and never charged.
  • Incremental mode: after the baseline you pay only for what changed (the table above).

🔌 Integrations & export

Export to JSON, CSV, Excel or an HTML table, or pull from the REST API and the JavaScript / Python clients. Runs on a schedule, connects to Google Sheets, Slack, Make, Zapier and n8n, and works as an MCP tool for AI agents. Compact mode keeps token usage small.

Also covering jobs and employers: our XING Jobs Scraper (DACH), Glassdoor Job Scraper and Greenhouse, Lever & Ashby Jobs Scraper.


🔗 Using the API

Run this Actor from your own code. Example with the Apify Python client:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_API_TOKEN>")
run_input = {
"searchTerms": ["data engineer"],
"locations": ["Canada"],
"experienceLevels": ["midSenior"],
"postedWithin": "pastWeek",
"includeCompanyDetails": True,
"maxResults": 50,
}
run = client.actor("corvuslab/linkedin-jobs-scraper").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["title"], item["company"], item["salaryText"])

It also works with the JavaScript/TypeScript client, the Apify CLI and the REST API.


❓ FAQ

Do I need a LinkedIn account, login or cookies? No. It reads LinkedIn's public job listings, the ones anyone can open without signing in.

Why do the experience-level and job-type filters work differently here? LinkedIn's public search ignores both, so the Actor reads each posting and keeps only those whose own seniority and employment type match. Jobs that don't match are not charged. These filters always read the full posting, even with Fetch the full job posting off. Filters that keep only a sliver of jobs stop the run early; the log suggests a keyword instead.

How many jobs can I get from one search? LinkedIn shows at most 1,000 jobs per search. Go further with more places (cities, or a region group) or more keywords: each keyword × place is its own search with its own 1,000-job view, de-duplicated.

Why is the pay range empty on most jobs? LinkedIn shows pay only when the employer states it, a minority of postings that varies by country. Otherwise the pay fields are null; pay is never guessed. So a pay filter returns fewer jobs: jobs without stated pay, or in another currency, are left out unless you turn on Keep jobs without comparable pay.

Do I get the external apply link? No. LinkedIn doesn't show the employer's own application link to signed-out visitors. Every posting carries applyType instead: EASY_APPLY (apply on LinkedIn) or EXTERNAL (apply on the employer's site).

Can I filter remote or hybrid jobs? Not reliably. Public postings don't say whether a role is remote, hybrid or on-site, and "Remote" as a place doesn't filter for it. Title must contain remote keeps jobs whose title says so.

Why is the hiring team empty on most jobs? jobPosterName, jobPosterTitle and jobPosterProfileUrl are filled only when LinkedIn shows a "Meet the hiring team" box, which is a small share of jobs. Only jobs that show the hiring team keeps just those.

How do I scrape all jobs from one company? Type its name or paste its LinkedIn company URL into Companies, or use its numeric ID in Company IDs. Leave keywords empty for all its roles in your places. The log shows which company each name matched; if none can be matched, the run searches nothing, so you're never charged for unrelated jobs.

How are skills found? By matching the title and description against a curated list of skills and tools (Excel, Python, GAAP, Kubernetes…). A skill appears only when the posting names it.


This Actor collects only publicly available job listings: the postings and company pages LinkedIn shows to anyone signed out. It does not scrape member profiles; the only personal data is what a posting displays, such as a hiring-team contact's name and title. You're responsible for how you use the data, especially personal information, and for complying with LinkedIn's terms and applicable law (including the GDPR/LGPD). Not affiliated with, endorsed by or sponsored by LinkedIn Corporation.


Keywords: linkedin jobs scraper · linkedin job scraper · linkedin scraper · linkedin jobs api · scrape linkedin jobs · linkedin job postings · linkedin job listings export · linkedin jobs without login · linkedin company data · linkedin salary data · linkedin jobs by country · job market research · recruitment lead generation · job monitoring · linkedin job alerts · export to CSV · export to Excel · no-code scraper · MCP tool for AI agents