LinkedIn Jobs Scraper — From $0.25/1k · No Cookies, No Login avatar

LinkedIn Jobs Scraper — From $0.25/1k · No Cookies, No Login

Pricing

from $0.25 / 1,000 job results

Go to Apify Store
LinkedIn Jobs Scraper — From $0.25/1k · No Cookies, No Login

LinkedIn Jobs Scraper — From $0.25/1k · No Cookies, No Login

LinkedIn Jobs scraper — no login or cookies. Search by keyword, URL, or job IDs with expiry monitoring. Free title/employer filters, 1K-cap bypass, recruiter contacts, optional company enrichment. Salary, description, apply URL per job. From $0.25/1k. JSON or CSV.

Pricing

from $0.25 / 1,000 job results

Rating

0.0

(0)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

2

Monthly active users

3 days ago

Last modified

Categories

Share

LinkedIn Jobs Scraper

The fastest way to turn LinkedIn Jobs into structured, spreadsheet-ready data — without a LinkedIn account, cookies, or login. Start from a search URL, a keyword + location, a single job URL, or a plain list of job IDs, and get clean job rows with title, company, salary, full description, apply URL, and recruiter contacts (best-effort) — as JSON or CSV.

From $0.25 per 1,000 jobs on higher plans ($0.69/1k on the free plan) — pay only for the jobs that land in your dataset. Filtered, duplicate, and previously-seen jobs cost nothing.

Why Use This Scraper?

  • No login, no cookies, no account risk — reads only LinkedIn's public Jobs surface
  • Cheapest per-job price in its class — $0.69/1k free plan → $0.25/1k Gold and above
  • Recruiter & hiring-team contacts (best-effort) — name, title, profile URL of the job poster
  • Bypass LinkedIn's ~1,000-results-per-search cap — split by city or experience level automatically
  • Job monitoring built in — paste job IDs, get back isExpired / verifiedAt / verificationStatus per listing
  • Free result filters — title include/exclude and employer blocklist run before billing
  • Cross-run deduponlyNewJobs remembers what it already sent you, ideal for daily schedules
  • Optional company firmographics — website, size, employees, HQ, industry, follower count

Overview

The LinkedIn Jobs Scraper is built for recruiters, lead-gen teams, job-market analysts, and job-board builders who need structured job-posting data from LinkedIn without maintaining a logged-in session.

The output is always job-shaped rows. Whether you start from a search URL, keyword filters, a single job URL, or a list of job IDs, every dataset item is one job posting with the same ~40-field schema — so your downstream pipeline never has to branch on input type.

Cookie-based LinkedIn scrapers require you to hand over a logged-in session (which gets accounts flagged) or buy session cookies from third parties. This actor reads the same public Jobs pages any anonymous browser can see, so no account is required and none is at risk. The trade-off is honest: a few fields LinkedIn reserves for logged-in viewers (some recruiter cards, some salary ranges) are best-effort.

Supported Inputs

URL types

URL typePatternWhat it returns
Search URLlinkedin.com/jobs/search?keywords=…&location=…Paginated job listings, filters read from the URL
Single-job URLlinkedin.com/jobs/view/4410745146/One enriched row per URL, no search phase
Slug job URLlinkedin.com/jobs/view/data-engineer-at-netflix-4350364210Same as above

Copy-pasteable startUrls

{
"startUrls": [
{ "url": "https://www.linkedin.com/jobs/search?keywords=Software%20Engineer&location=United%20States&geoId=103644278" },
{ "url": "https://www.linkedin.com/jobs/view/4410745146/" }
]
}

Job IDs mode — scrape or re-verify exact listings

Paste raw job IDs, view URLs, or any LinkedIn URL carrying currentJobId= into the jobIds field. Each entry goes straight to the job detail page. Re-run the same list on a schedule to monitor listings — every row includes isExpired, verifiedAt, and verificationStatus (active / closed / removed), so dead listings are flagged instead of silently missing.

{
"jobIds": ["4410745146", "https://www.linkedin.com/jobs/view/4406118990/"]
}

Keyword / filter mode

Leave URLs empty and let the actor build the search: keywords × locations × time range × workplace type × experience level × contract type × company names.

{
"keywords": ["Data Engineer"],
"location": "United States",
"timeRange": "r604800",
"remote": ["2"],
"experienceLevels": ["4", "5"]
}

Unsupported inputs

  • ❌ URLs behind the LinkedIn login wall (Sales Navigator, Recruiter seats, private postings)
  • ❌ LinkedIn profile / company-page URLs (see the dedicated actors in Explore More Scrapers)
  • ❌ Shortened or redirect URLs (lnkd.in/…)

Use Cases

AudienceUse case
Recruiters & sourcing teamsPull hiring-manager contacts from open roles and reach out before the inbox floods
B2B lead-gen / HR-tech vendorsCompanies actively hiring for X are in-market for your product — build the list daily
Job boards & aggregatorsBackfill listings at $0.25–0.69/1k with cross-run dedup so you only ingest new postings
Market & salary analystsTrack demand by title, region, seniority, and published salary bands
Sales intelligence teamsA competitor's job posts reveal their stack, roadmap, and the decision-makers to pitch
AgenciesDeliver client-ready hiring datasets on a schedule without writing scrapers

How It Works

How It Works

  1. Input — paste search URLs, job URLs, job IDs, or set keyword + location filters
  2. Route — search inputs paginate the public Jobs listing; job IDs and view URLs skip straight to the detail page
  3. Filter (free) — title include/exclude and employer blocklist drop unwanted jobs before they're collected or billed
  4. Collect & enrich — every kept job gets the full ~40-field row; optional company firmographics per unique employer
  5. Output — JSON or CSV dataset, plus a RUN_SUMMARY record explaining exactly how the run ended

Input Configuration

Input fields

FieldTypeRequiredNotes
startUrlsarray<{url}>one input modeMix of search URLs and single-job view URLs
jobIdsarray<string>one input modeRaw IDs, view URLs, or currentJobId= URLs — direct to detail page
keywordsarray<string>one input modeUsed when no URLs are given
location / locationsstring / arrayoptionalBroad location, or several locations searched in one run
geoId, placeIdsstring, arrayoptionalLinkedIn geo precision (geoId, f_PP city-level filters)
timeRangeenumoptionalany time, last 24h (r86400), week (r604800), month (r2592000)
remote / jobTypesarray enumoptionalOn-site 1 / Remote 2 / Hybrid 3
experienceLevelsarray enumoptional1 intern → 6 director
contractTypearray enumoptionalF/P/C/T/I/V/O
companyNamesarray<string>optionalOnly include these employers (query-injected + name-matched)
titleMustIncludearray<string>optionalKeep only titles containing at least one term — free, pre-billing
titleExcludearray<string>optionalDrop titles containing any term — free, pre-billing
excludeCompaniesarray<string>optionalDrop these employers — free, pre-billing
scrapeCompanyDetailsbooleanoptionalCompany firmographics; billed per unique company
onlyNewJobsbooleanoptionalCross-run dedup — only jobs not returned in previous runs
autoSplitbooleanoptionalBypass ~1K cap by splitting the search across experience levels
splitByLocation + splitCountryboolean + enumoptionalBypass ~1K cap by fanning out across a country's major cities
maxItemsintegeroptionalHard cap on charged dataset rows
minDelay/maxDelay, minConcurrency/maxConcurrency, maxRequestRetriesintegeroptionalCrawl pacing
proxyobjectoptionalResidential recommended

Common scenarios

1. Daily new-jobs monitor (schedule this)

{
"keywords": ["DevOps Engineer"],
"location": "Germany",
"timeRange": "r86400",
"onlyNewJobs": true,
"titleExclude": ["senior", "principal"],
"maxItems": 200
}

2. Re-verify a list of tracked listings

{
"jobIds": ["4410745146", "4406118990", "4350364210"]
}

3. Break the 1,000-result cap for a whole country

{
"keywords": ["Nurse"],
"splitByLocation": true,
"splitCountry": "GB",
"maxItems": 5000
}

Output Overview

Each dataset item is one job posting containing:

  • Core fieldsid, title, company, location, postedAt, jobUrl, full description (+ descriptionHtml)
  • Compensation & criteria — parsed salary (minAmount / maxAmount / currency / period), seniorityLevel, employmentType, jobFunction, industries, benefits
  • ApplicationapplyUrl (external careers site when exposed), easyApply, numberOfApplicants / applicantsCount
  • PeoplehiringTeam[] and flat jobPosterName / jobPosterTitle / jobPosterProfileUrl (best-effort; empty means LinkedIn hid it from anonymous viewers)
  • CompanycompanyLinkedinUrl always; with scrapeCompanyDetails also website, industry, size, employee count, HQ, logo, follower count
  • VerificationisExpired, verifiedAt, verificationStatus (active / closed / removed) on every row
  • ProvenancescrapedFrom (search-results / job-view-url / job-id-input), sourceUrl

Every run also writes a RUN_SUMMARY record to the key-value store: requested vs saved counts, pages parsed, jobs dropped per filter, expired jobs found, and a stopReason — so "why did I get 400 instead of 1000?" is answered by the run itself.

Output Samples

Search start (trimmed real row)

{
"id": "4350364210",
"title": "Data Engineer (L5)",
"company": "Netflix",
"companyLinkedinUrl": "https://www.linkedin.com/company/netflix",
"location": "United States",
"seniorityLevel": "Not Applicable",
"employmentType": "Full-time",
"industries": ["Entertainment Providers"],
"postedAt": "2026-07-02",
"postedTimeAgo": "5 days ago",
"numberOfApplicants": "Over 200 applicants",
"applicantsCount": 200,
"easyApply": false,
"description": "At Netflix, our mission is to entertain the world. Together, we are writing the next episode…",
"isExpired": false,
"verifiedAt": "2026-07-08T03:58:41.120Z",
"verificationStatus": "active",
"jobUrl": "https://www.linkedin.com/jobs/view/data-engineer-l5-at-netflix-4350364210",
"scrapedFrom": "search-results"
/* …plus salary, applyUrl, hiringTeam, jobPoster*, company* fields… */
}

Job-ID start — removed listing (monitoring)

{
"id": "3000000001",
"title": null,
"company": null,
"jobUrl": "https://www.linkedin.com/jobs/view/3000000001/",
"isExpired": true,
"verifiedAt": "2026-07-08T03:57:33.319Z",
"verificationStatus": "removed",
"scrapedFrom": "job-id-input"
}

Key Output Fields

Job core

  • id, title, company, location, postedAt, postedTimeAgo, jobUrl, sourceUrl

Description & criteria

  • description, descriptionHtml, criteria[], seniorityLevel, employmentType, jobFunction, industries[], benefits[], workplaceType

Compensation & application

  • salary.raw, salary.minAmount, salary.maxAmount, salary.currency, salary.period
  • applyUrl, easyApply, numberOfApplicants, applicantsCount

Recruiter / hiring team (best-effort)

  • hiringTeam[].name, hiringTeam[].title, hiringTeam[].linkedinUrl, hiringTeam[].photo
  • jobPosterName, jobPosterTitle, jobPosterProfileUrl, jobPosterPhoto

Company (flat fields filled by scrapeCompanyDetails)

  • companyLinkedinUrl, companyLinkedinSlug, companyWebsite, companyIndustry, companySize, companyEmployeesCount, companyHeadquarters, companyFollowerCount, companyLogo, companyDetails

Verification & provenance

  • isExpired, verifiedAt, verificationStatus, scrapedFrom

FAQ

Do I need a LinkedIn account or cookies?

No. The actor reads only the public Jobs surface that any anonymous browser can access. No login, no cookies, no account at risk.

Why did I get fewer jobs than maxItems?

Check the RUN_SUMMARY record in the run's key-value store — it reports pages parsed, candidates seen, how many jobs each filter dropped, and the stopReason. The most common causes: the search genuinely has fewer results, LinkedIn's ~1,000-per-search ceiling (enable autoSplit or splitByLocation), or your title/company filters doing their job.

Are the title and company filters really free?

Yes. titleMustInclude, titleExclude, and excludeCompanies run before a job is collected, so filtered jobs are never charged and never consume detail-page requests.

Are recruiter contacts always available?

No — best-effort. LinkedIn shows the hiring-team card to anonymous viewers on some jobs and hides it on others. hiringTeam: [] means LinkedIn hid it, not that the parser failed. Same honesty applies to salary and applyUrl: they're populated when the employer published them.

How do I monitor jobs for expiry?

Put the job IDs (or view URLs) in jobIds and run on a schedule. Live listings return full rows with verificationStatus: "active"; closed listings are flagged "closed"; listings deleted from LinkedIn come back as sparse rows with "removed" and isExpired: true.

LinkedIn caps every guest search at ~1,000 results. Enable splitByLocation (fans the search out across a country's major cities) or autoSplit (splits across the six experience levels). Results are deduplicated automatically.

What does onlyNewJobs do?

It remembers the job IDs from your previous runs and skips them, so a scheduled run only returns postings it has never sent you before.

Can I scrape private or logged-in-only postings?

No. Anything behind the LinkedIn login wall (Sales Navigator, Recruiter, private postings) is out of scope.

Support

Found a bug or have a feature request? Open an issue on the actor's Issues tab or email me at muhameddidovic@gmail.com.

Additional Services

Need a custom export shape, an extra field, or a managed daily feed delivered to your database? I do tailored work — drop me a line at muhameddidovic@gmail.com.

Explore More Scrapers

If you found this useful, you might also like:

Full list at apify.com/memo23.


⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by LinkedIn Corporation or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available LinkedIn Jobs pages — no authenticated endpoints, paid features, or content behind the linkedin.com login wall. Users are responsible for ensuring their use complies with LinkedIn's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.


SEO Keywords

linkedin jobs scraper, scrape linkedin jobs, linkedin job scraper, linkedin jobs API, linkedin job postings scraper, Apify linkedin jobs, job listings scraper, job board scraper, hiring data scraper, recruiter contact scraper, job monitoring tool, job posting verification, linkedin jobs without login, no-cookie linkedin scraper, job market analysis data, salary benchmark data, recruitment lead generation, hiring manager contacts, employment data extraction, HR tech data, talent sourcing data