LinkedIn Jobs Scraper — Remote Jobs, No Login | $0.50/1k avatar

LinkedIn Jobs Scraper — Remote Jobs, No Login | $0.50/1k

Pricing

from $0.50 / 1,000 results

Go to Apify Store
LinkedIn Jobs Scraper — Remote Jobs, No Login | $0.50/1k

LinkedIn Jobs Scraper — Remote Jobs, No Login | $0.50/1k

Scrape LinkedIn job postings without an account: title, company, location, date posted, salary, seniority, employment type, industries, applicants and the full description. Keyword, location, company and date filters.

Pricing

from $0.50 / 1,000 results

Rating

0.0

(0)

Developer

Raffy

Raffy

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

3

Monthly active users

3 hours ago

Last modified

Share

What does LinkedIn Jobs Scraper do?

Get LinkedIn job postings as clean spreadsheet rows: job title, company, company page and logo, location, the date the job was posted, the pay range when the employer published one (parsed into salaryMin and salaryMax), seniority, employment type, job function, industries, applicant count, Easy Apply, and the full job description as plain text.

Type a keyword and a location - software engineer in United States, nurse in United Kingdom - or paste a LinkedIn job-search URL straight from your browser, and scrape LinkedIn jobs into JSON, CSV or Excel, or read them from the Apify API. It works as a practical LinkedIn jobs API for job boards, recruiters, analysts and AI agents: no LinkedIn account, no login, no cookies, nothing to install.

It reads only LinkedIn's public job postings, the same pages LinkedIn shows to anyone who is not signed in. It never logs in and never touches member profiles. It does not read "meet the hiring team" cards or recruiter profiles. When a job description names a contact person, that person's name, email address and phone number are replaced with [name removed] / [email removed] / [phone removed] (deterministic rules for contact lines and contact blocks in English, German and French postings, such as "please contact

Filter like on LinkedIn itself - Easy Apply, Under 10 applicants, distance, remote / hybrid / on-site, minimum salary, experience level, job type, title words and excluded companies - and run it on a schedule with Only jobs new since the last run to get a daily feed of new postings only. Every row also carries ready-to-filter columns: workplaceType, yearsExperienceMin, visaSponsorship, skills and applyType.

$0.50 per 1,000 jobs plus $0.005 per run, platform compute and proxy included. A 1,000-job run with full descriptions costs about $0.51.

Use cases for this LinkedIn jobs scraper

  • Job board or aggregator. Schedule one search per keyword and city every morning with Date posted = Past 24 hours, and publish fresh postings with the full descriptionText, employmentType and seniority.
  • Recruitment agency. Find the companies hiring for the roles you place: filter on companyName, location and postedAt, and see how many people applied (applicantCount) before you call.
  • Sales prospecting. A company hiring five data engineers is buying data tools. Search by role and group the rows by companyName and companyUrl to build an account list with real hiring intent.
  • Labour-market and salary research. salaryMin, salaryMax, salaryCurrency and salaryPeriod are parsed from LinkedIn's pay range, so you can chart pay by role, country or industries.
  • Job seekers and career tools. Pull every entry-level posting for a skill from the past week into a spreadsheet and track what you applied to.
  • AI agents and automations. Call it with {"keywords": ["python developer"], "locations": ["Berlin"]} from an MCP client, n8n, Make or Zapier and get structured rows back.

What data can LinkedIn Jobs Scraper extract?

One row per job posting. A job found by several of your searches is returned once (de-duplicated by jobId). The Overview table shows title, companyName, location, postedAt, salaryText, employmentType, seniority, applicantCount, url, companyUrl, searchKeyword, status and error.

Job and company

FieldTypeDescription
jobIdstringLinkedIn's numeric job id, e.g. 4454133738.
urlstringPublic job page, https://www.linkedin.com/jobs/view/<jobId>/.
titlestringJob title as posted.
companyNamestringHiring company.
companyUrlstringThe company's LinkedIn page.
companyLogostringCompany logo image URL.
locationstringLocation as LinkedIn writes it: city, region, country or metro area.
workplaceTypestringRemote, Hybrid or On-site, read from the location (United States (Remote)), a title tag (Engineer (Remote)) or a fixed phrase in the description (this is a hybrid role, fully remote, on-site role). Absent when none of them says it; LinkedIn's public pages have no workplace-type field.
workplaceTypeSourcestringWhere workplaceType was read: location, title or description.

Date, pay and applicants

FieldTypeDescription
postedAtstringPosting date, ISO 8601 (LinkedIn gives the day, so the time is midnight UTC).
postedTextstringLinkedIn's relative time, e.g. 2 weeks ago.
salaryTextstringPay range exactly as shown, e.g. $117,000.00/yr - $234,000.00/yr. Only when the employer published one.
salaryMin / salaryMaxnumberThe range parsed to numbers.
salaryCurrencystringISO currency code: USD, EUR, GBP, CAD, INR, ...
salaryPeriodstringhour, day, week, month or year.
applicantsTextstringe.g. Over 200 applicants, Be among the first 25 applicants.
applicantCountintegerThe number in applicantsText (Over 200 = 200).
benefitsarrayLinkedIn's highlights on the search card, e.g. Actively Hiring.

Job details (with Fetch full job details on, the default)

FieldTypeDescription
descriptionTextstringFull description as plain text, paragraphs and bullet points on their own lines.
descriptionHtmlstringThe same as HTML, only with Also keep the description as HTML.
senioritystringe.g. Entry level, Mid-Senior level, Director.
employmentTypestringe.g. Full-time, Part-time, Contract.
jobFunctionstringe.g. Engineering and Information Technology.
industriesstringThe company's industries as LinkedIn lists them.
easyApplybooleantrue = LinkedIn Easy Apply, false = apply on the company's site.
applyTypestringThe same as text: easy_apply or external.
yearsExperienceMinintegerYears of experience from the first "N years ... experience" sentence of the description (3+ years of experience = 3). Absent when the description names none.
visaSponsorshipbooleanfalse when the description rules sponsorship out (unable to sponsor, without sponsorship), true when it offers it (visa sponsorship available); absent when it says neither.
skillsarraySkills from a fixed list of about 100 (languages, frameworks, cloud, data, business tools, healthcare certifications) named in the title or description, e.g. ["Python", "SQL", "AWS"].
isClosedbooleantrue when LinkedIn says the job no longer accepts applications.
applyUrlstringExternal apply link, only on the few postings where LinkedIn shows it without sign-in.
descriptionErrorstringWhy the details of this job could not be read; the row still has the search-card data.

Search and row status

FieldTypeDescription
searchKeywordstringKeyword of the search that found the job.
searchLocationstringLocation of that search.
statusstringok, not_found or error (below).
errorstringReason when status is not ok.
scrapedAtstringISO 8601 time the row was written.
statusMeaningBilled?
okA job posting.Yes
not_foundLinkedIn answered, but has nothing: a search with no jobs, a deleted posting, a company name LinkedIn does not know.No
errorLinkedIn could not be read after retries. error says why.No

A run whose only rows are not_found ends as Succeeded: "no jobs for this search" is an answer, not a failure.

How to scrape LinkedIn jobs

  1. Open the Actor and click Try for free.
  2. Type one or more Job titles or keywords and Locations - or paste LinkedIn job-search URLs into LinkedIn job-search URLs.
  3. Optional: pick filters (Date posted, Experience level, Job type) or restrict to companies by name or id.
  4. Set Maximum results (the default 20 shows you the output in seconds).
  5. Click Start, then open the Output tab or export the dataset as JSON, CSV, Excel, XML or HTML.

To automate it, use the API tab (Node.js, Python, curl) or add a Schedule.

Input

FieldTypeDefaultDescription
keywordsarray of strings-Job titles or keywords; each one is a separate search.
locationsarray of strings-Countries, regions or cities; each is searched separately. Empty = worldwide.
startUrlsarray of stringsone example searchLinkedIn job-search URLs (all filters kept), job URLs or job ids. The example is skipped as soon as you fill in keywords, locations or companies.
datePostedstringany1h, 24h, week, month or any.
experienceLevelarrayallinternship, entry, associate, mid-senior, director, executive. Checked on every job's page (see below).
jobTypearrayallfull-time, part-time, contract, temporary, internship, volunteer, other. Checked on every job's page.
workplaceTypearrayallremote, hybrid, on-site. Checked on every job (see below); jobs that state no workplace are left out.
easyApplybooleanfalseEasy Apply jobs only (applied by LinkedIn's search).
under10ApplicantsbooleanfalseJobs with fewer than 10 applicants only (applied by LinkedIn's search).
minSalaryinteger-Minimum yearly pay in the posting's currency (hourly x 2,080, monthly x 12). Jobs without a published pay range are left out. Checked on every job.
distanceinteger-Radius in miles around a city in locations (LinkedIn uses 5, 10, 25, 50, 100).
titleIncludes / titleExcludesarray of strings-Keep only titles with one of these words / skip titles with any of them. Whole words, case-insensitive.
excludeCompaniesarray of strings-Skip these companies (e.g. staffing agencies); whole words of the company name.
onlyNewSinceLastRunbooleanfalseFor schedules: skip every job an earlier run already delivered (see below).
seenJobsStoreNamestringlinkedin-jobs-seenThe named key-value store that remembers delivered jobs; one name per monitor.
companyNamesarray of strings-Only jobs at these companies, matched to their LinkedIn page by name.
companyIdsarray of strings-LinkedIn company ids (the f_C value in a search URL).
geoIdstring-LinkedIn's place id, for ambiguous place names.
fetchDescriptionbooleantrueFull job details (one extra request per job). false = search-card data only, much faster.
includeDescriptionHtmlbooleanfalseAlso return the description as HTML.
maxItemsinteger20Stop after this many jobs across all searches.
maxItemsPerSearchinteger-Cap per single search, so one broad search cannot use up maxItems.
proxyConfigurationobjectApify Proxy onDatacenter proxy (included). Residential proxies are not needed.

Filters apply to every search, pasted URLs included. keyword, location and query are accepted as aliases, which helps AI agents.

How the filters work. LinkedIn's logged-out search applies the date and company filters itself. It ignores experience level and job type (we measured identical results with and without them), so the Actor reads each job's own "Seniority level" and "Employment type" and saves only the jobs that match; the ones that do not match are never saved or billed. When you pick exactly one level or type, its words (e.g. entry level, part-time) are also added to your keyword search so that LinkedIn ranks matching jobs first; searchKeyword still shows your own keyword. That takes one job-page request per job checked, so filtered runs are slower. Easy Apply, Under 10 applicants and distance are applied by LinkedIn's search itself (measured October 2026), so they cost nothing extra. Workplace type and minimum salary are ignored by LinkedIn's logged-out search, so they are checked on each job like experience level: workplace type against the workplaceType column, salary against the top of the published pay range. With exactly one of remote / hybrid chosen, that word is added to your keyword search too.

Title and company filters (titleIncludes, titleExcludes, excludeCompanies) are decided on the search results before any job page is fetched; skipped jobs cost nothing and do not count toward Maximum results.

Only new jobs on a schedule. With onlyNewSinceLastRun, every job the run delivers is remembered in a named key-value store on your Apify account (seenJobsStoreName, default linkedin-jobs-seen), and later runs skip those jobs on the search results, before any request or charge. Schedule the same input daily and each run returns only new postings; a run that finds nothing new ends successfully with "No new matching jobs" and costs only the start fee. Use one store name per monitor.

Example input:

{
"keywords": ["data analyst", "data engineer"],
"locations": ["United States", "Canada"],
"datePosted": "week",
"experienceLevel": ["entry", "associate"],
"maxItems": 500,
"maxItemsPerSearch": 125
}

Output

A real row from a platform run (description shortened):

{
"url": "https://www.linkedin.com/jobs/view/4454133738/",
"status": "ok",
"jobId": "4454133738",
"title": "(USA) Senior, Software Engineer",
"companyName": "Walmart",
"companyUrl": "https://www.linkedin.com/company/walmart",
"companyLogo": "https://media.licdn.com/dms/image/v2/D560BAQHZkPdlecGssw/company-logo_100_100/company-logo_100_100/0/1736779000209/walmart_logo?e=2147483647&v=beta&t=tWcWIFSyHtICTzTLIPiYeKCp21XucI-HWijZdWwYR-A",
"location": "Sunnyvale, CA",
"postedAt": "2026-09-11T00:00:00.000Z",
"postedText": "2 weeks ago",
"benefits": ["Actively Hiring"],
"applicantsText": "101 applicants",
"applicantCount": 101,
"seniority": "Not Applicable",
"employmentType": "Full-time",
"jobFunction": "Engineering and Information Technology",
"industries": "Retail",
"salaryText": "$117,000.00/yr - $234,000.00/yr",
"salaryMin": 117000,
"salaryMax": 234000,
"salaryCurrency": "USD",
"salaryPeriod": "year",
"easyApply": false,
"descriptionText": "Position Summary...\n\nWhat you'll do...\n\nRole summary:\n\nAs a Senior Software Engineer, you will lead the delivery of scoped features and solutions by collaborating with cross-functional teams ...",
"searchKeyword": "software engineer",
"searchLocation": "United States",
"scrapedAt": "2026-09-27T23:34:53.593Z"
}

A search with no jobs, and a company name LinkedIn does not know, look like this (free):

{
"url": "https://www.linkedin.com/jobs-guest/jobs/api/seeMoreJobPostings/search?keywords=astronaut&location=Vatican+City&f_TPR=r3600&start=0",
"status": "not_found",
"error": "No results for this page",
"scrapedAt": "2026-09-28T00:10:04.221Z"
}

Speed and reliability (real runs)

The default memory is 512 MB since version 1.1.0 (cheaper small runs). The numbers below are from runs at 1,024 MB with the default datacenter proxy; at 512 MB the same 500-job run took 8 min 56 s instead of 4 min 21 s at the same cost, so give a big run 1,024 MB when you want it faster.

RunJobsTimeRequestsFailed
Default input (no arguments), 6 staging runs205-18 s220
3 US keyword searches, full details30079 s3450
12 searches in 12 countries (US, UK, DE, IN, CA, AU, FR, NL, BR, SG, ES, PL), full details1,1886 min 11 s1,3080 (99.9% on the first attempt)

With Fetch full job details off, a run needs one request per 10 jobs instead of one per job. LinkedIn throttles busy IP addresses; the Actor retries a throttled request from a fresh IP, so throttling costs seconds, not rows.

How much does it cost to scrape LinkedIn jobs?

Pay per event, platform compute and proxy included:

EventPrice
Actor start$0.005 per run
Result (status: ok job)$0.0005 per job ($0.50 per 1,000)

Examples: the default 20-job run costs $0.015; 1,000 jobs cost $0.505; 10,000 jobs $5.005. Rows with status not_found or error are never billed. Cap spending with Maximum results and the run's Max total charge; the Actor stops cleanly when either is reached.

Tips

  • More than 1,000 jobs for one query: LinkedIn serves at most 1,000 results per search. Split it: several locations (states or cities instead of a country), several related keywords, or Date posted = Past 24 hours on a daily schedule.
  • Put several keywords and locations into one run instead of many small runs; you pay the start fee once, and duplicates across searches are removed for you.
  • Use maxItemsPerSearch to spread maxItems evenly over your searches.
  • For exact companies use companyIds; companyNames takes LinkedIn's best match for the name (check companyName in the output).

Limitations

  • LinkedIn serves at most 1,000 jobs per search (see Tips).
  • LinkedIn does not return "no results" for a keyword it does not recognise; it shows related jobs instead. searchKeyword tells you which search found each row.
  • Pay ranges exist only where the employer published one (about one job in ten in our test runs, more in the US, UK and EU).
  • Most external apply links are behind LinkedIn's sign-in, so applyUrl is usually empty; easyApply tells you how to apply.
  • postedAt has day precision. Jobs requested by URL (not found through a search) have postedText only.
  • LinkedIn's logged-out search ignores its own workplace-type, salary, experience-level and job-type filters and its sort order (results come in LinkedIn's relevance order; use Date posted for the newest jobs). The Actor checks those filters on each job page instead, which costs one request per job checked.
  • workplaceType, yearsExperienceMin, visaSponsorship and skills come from fixed text rules, not from a LinkedIn field: a job whose description does not say it gets no value, and the workplace filter leaves such jobs out.
  • If a job-page filter (experience level, job type, workplace type, minimum salary) matches none of the jobs checked (up to 20 per requested result), the run ends without results and is marked failed.
  • Title and company filters apply to searches; jobs requested by URL or id are always returned.
  • Member data is out of scope: no recruiter profiles or hiring-team cards. Contact-person names, emails and phone numbers written in descriptions are replaced with [name removed] / [email removed] / [phone removed].

FAQ

Do I need a LinkedIn account, cookies or a proxy? No. The Actor reads LinkedIn's public job pages without logging in; the datacenter proxy it uses is included in the price.

Is it legal to scrape LinkedIn jobs? It collects only job postings that LinkedIn publishes to anonymous visitors, and no member data. You are responsible for how you use the data; read the notice below and LinkedIn's terms.

Why did I get fewer rows than Maximum results? Your searches had fewer jobs, jobs repeated across searches (each is returned once), or a per-search cap or the run's charge limit was reached. The run log says which.

Can an AI agent call it? Yes. With no input at all it returns 20 software engineer jobs in the United States in seconds. Agents can pass keywords/keyword, locations/location or query as plain strings, and every row says whether it is data (ok), an empty answer (not_found) or a failure (error).

How fresh is the data? Every run reads LinkedIn live; nothing is cached. Use Date posted = Past hour / 24 hours for a feed of new postings.

Does it get the company's website, size or employees? No, only what the job posting shows: company name, LinkedIn page and logo.

This Actor extracts only job postings that LinkedIn publishes publicly to visitors who are not signed in. It does not log in, does not work around access controls, and does not extract member data such as names, profile links, e-mail addresses or phone numbers. Job descriptions are written by employers and can still mention a contact person; personal data is protected by the GDPR in the European Union and by other laws worldwide, so do not use such data without a legitimate reason. You are responsible for complying with LinkedIn's terms of service and applicable law when you use the extracted data.

This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by LinkedIn Corporation. LinkedIn is a trademark of LinkedIn Corporation; all trademarks belong to their respective owners.