LinkedIn Job Scraper API - Salary, Skills & Full Descriptions avatar

LinkedIn Job Scraper API - Salary, Skills & Full Descriptions

Pricing

from $1.00 / 1,000 results

Go to Apify Store
LinkedIn Job Scraper API - Salary, Skills & Full Descriptions

LinkedIn Job Scraper API - Salary, Skills & Full Descriptions

LinkedIn job scraper tool that searches by keyword and location and returns every posting with the full description, salary, skills, and applicant count. No login or cookies.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

Thodor

Thodor

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 days ago

Last modified

Share

A LinkedIn job scraper tool that searches by keyword and location, then opens every posting it finds. Search python developer in Amsterdam, Netherlands and load the jobs into a spreadsheet as CSV, Excel, or JSON, full description included. No login, no cookies, no LinkedIn account.

Most LinkedIn job scrapers return what the search results page shows: title, company, location, date. This one opens each job and returns what is inside it: the full description, remote flag, seniority, applicant count, and expiry date. Tracking specific employers instead of keywords? The LinkedIn Company Jobs Scraper takes a company and returns every opening it has.

๐Ÿ“‹ How to export LinkedIn jobs to a spreadsheet

  1. Type your search terms into Search keywords, one per line. Each term runs as its own search.
  2. Set Location the way you would type it on LinkedIn: Berlin, Germany, London, United Kingdom, United States. Empty means worldwide.
  3. Click Start.
  4. Open the Output tab and click Export for CSV, Excel, JSON, or HTML.

A 10-job run across two keywords takes about 20 seconds. Already built your search on LinkedIn? Paste the URL into Search URLs and the keywords and location are read from it.

๐ŸŽ So what do you get?

๐Ÿ’ผ Job title๐Ÿ“ Full job description๐Ÿ‘ฅ Amount of applicants
๐Ÿ  Remote flag๐ŸŽ–๏ธ Seniority level๐Ÿ“… Posted and expiry dates
๐Ÿข Employer firmographics, optional๐Ÿ’ถ Salary, when published๐Ÿ› ๏ธ Job function
โณ Employment type๐ŸŽ“ Required skills and education๐Ÿ“Š Months of experience required
๐Ÿ”— Original LinkedIn URL๐Ÿ†” Stable job and requisition IDs๐Ÿ”Ž Which search produced the row

โš–๏ธ Compared to search-page scrapers

Search-page scrapersThis actor
๐Ÿ“ DescriptionโŒ Snippet or noneโœ… Full, as HTML and plain text
๐Ÿ  Remote and seniorityโš ๏ธ From filters LinkedIn ignoresโœ… Read from each job's own page
๐Ÿ“… Expiry dateโŒ Not on the results pageโœ… valid_through on every row
๐Ÿ‘ฅ Applicant countโŒโœ… A competition signal per job
๐Ÿ”‘ Your LinkedIn accountโš ๏ธ Cookie scrapers put it at riskโœ… Never used, nothing to ban

๐ŸŽฏ Three things people run this for

How
๐Ÿ“ฐ A daily feed of new jobs in a marketDaily run on a Schedule with Posted within at Past 24 hours. A webhook drops new rows into Slack, Airtable, or your CRM
๐Ÿ“ˆ Hiring-intent lists for salesGroup the feed by company and you know who is staffing a team this month. Switch on Add company details for industry, headcount, and HQ on every row
๐Ÿ’ถ Salary and stack researchbase_salary when the employer publishes it; the rest of the time the range sits in description_text, ready to mine with an LLM

๐Ÿ“ฅ Input

{
"keywords": ["python developer", "data engineer"],
"location": "Amsterdam, Netherlands",
"postedWithin": "30d",
"maxJobsPerSearch": 25
}
  • keywords: one search per term. A job matched by two terms is returned once
  • location: as you would type it on LinkedIn. Empty means worldwide
  • postedWithin: default any, or 24h, 7d, 30d
  • jobType: default any, or fulltime, parttime, contract, temporary, internship, volunteer, other
  • maxJobsPerSearch: 0 = everything LinkedIn serves. The default 25 keeps a first run quick
  • scrapeDetails: default true, opens each job for the full record. Off = much faster, search-results fields only
  • enrichCompanies: default false. Attaches employer firmographics, one lookup per company per run, billed on top
  • searchUrls: paste LinkedIn job search URLs instead of typing keywords

๐Ÿ“ฐ A daily feed of new postings

Put this on a daily Schedule and each run returns only what appeared since the last one.

{"keywords": ["data engineer"], "location": "Amsterdam, Netherlands", "postedWithin": "24h", "maxJobsPerSearch": 0}

๐Ÿ—‚๏ธ Several roles in one market

{"keywords": ["python developer", "data engineer", "ml engineer"], "location": "Amsterdam, Netherlands", "maxJobsPerSearch": 0}

โšก A fast headcount sweep

When the question is "how many jobs match", not "what is in them", switching details off makes the run several times faster.

{"keywords": ["rust developer"], "location": "Germany", "scrapeDetails": false, "maxJobsPerSearch": 0}

๐Ÿ“ค Output

One flat row per job. Results stream into the dataset while the run is going, so partial exports work immediately.

LinkedIn Job Scraper API output showing job title, company, location, remote flag, posted date, applicant count, employment type and seniority for each scraped LinkedIn job

{
"search_keywords": "python developer",
"search_location": "Amsterdam, Netherlands",
"job_id": "4445431410",
"title": "Python Software Engineer",
"company": "IMC Trading",
"company_url": "https://www.linkedin.com/company/imc-trading",
"location": "Amsterdam, North Holland, Netherlands",
"is_remote": false,
"posted": "2026-07-26",
"date_posted": "2026-07-26T02:18:40.000Z",
"valid_through": "2026-08-26T02:18:40.000Z",
"employment_type": "FULL_TIME",
"seniority": "Mid-Senior level",
"job_function": "Engineering and Information Technology",
"industries": "Financial Services",
"applicants": 200,
"employer_job_id": "f862f028-49d1-4487-96d8-47b7e73fd508",
"education": { "@type": "EducationalOccupationalCredential", "credentialCategory": "bachelor degree" },
"description_html": "<p>...</p>",
"description_text": "...",
"view_url": "https://nl.linkedin.com/jobs/view/python-software-engineer-at-imc-trading-4445431410"
// HIDDEN: months_of_experience, applicants_raw, base_salary, skills,
// hiring_org, job_location, company_details, detail_error
}

โš ๏ธ Jobs are not returned newest first. LinkedIn orders them by its own relevance ranking and ignores any request to sort by date. Posted within is the way to bias a run toward recent postings; sort on date_posted for strict chronology.

Fields

FieldNotes
job_id, view_urlStable LinkedIn identifiers. Use job_id to deduplicate across runs and detect new postings
search_keywords, search_locationWhich of your searches produced this row, so multi-keyword runs stay traceable
title, company, location, postedThe basics, on every row even with details switched off
is_remotetrue when LinkedIn flags the posting as remote, read from the job's own page rather than the search results
date_posted, valid_throughExact timestamps from LinkedIn's structured data, including when the posting expires
applicantsCapped by LinkedIn at 200. A row showing 200 means "200 or more", and applicants_raw keeps the original wording
seniority, job_function, industries, employment_typeAlways in English, for every job in every country
months_of_experienceRequired experience as a number, so 24 means two years. Filter on it instead of parsing prose
employer_job_idThe employer's own requisition ID, separate from LinkedIn's job_id. Joins against a careers page or ATS
base_salaryPopulated when LinkedIn publishes structured pay, which is uncommon. Usually null
description_html, description_textFull posting body as HTML and as plain text. Feed either to an LLM to pull out tech stack, salary, or team structure
skills, education, hiring_org, job_locationPresent when LinkedIn publishes them, null when it does not
company_detailsEmployer firmographics, when Add company details is on. null otherwise
detail_errornull on success. Set when a detail page failed, so you can retry those rows

โš™๏ธ Use it as a LinkedIn jobs API

Every run is an HTTP endpoint: POST the same JSON as the form and the jobs come back in the response body.

Python

import requests
resp = requests.post(
"https://api.apify.com/v2/acts/thodor~linkedin-job-scraper-api/run-sync-get-dataset-items",
params={"token": "YOUR_APIFY_TOKEN"},
json={"keywords": ["python developer"], "location": "Amsterdam, Netherlands", "maxJobsPerSearch": 50},
)
for job in resp.json():
print(job["title"], job["company"], job["location"])

Node.js

import axios from "axios";
const { data } = await axios.post(
"https://api.apify.com/v2/acts/thodor~linkedin-job-scraper-api/run-sync-get-dataset-items",
{ keywords: ["python developer"], location: "Amsterdam, Netherlands", maxJobsPerSearch: 50 },
{ params: { token: process.env.APIFY_TOKEN } }
);
console.log(data.length, data[0].title, data[0].company);

curl

curl -X POST "https://api.apify.com/v2/acts/thodor~linkedin-job-scraper-api/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords":["python developer"],"location":"Amsterdam, Netherlands","maxJobsPerSearch":50}'

Swap run-sync-get-dataset-items for runs to fire async and collect results by webhook; broad searches can outlive the 5-minute sync window. The apify-client SDK works too, in Python and JavaScript, and the n8n, Make, Zapier, Google Sheets, and Slack integrations take the same input.

๐Ÿ’ก Tip: no need to write the JSON by hand. Fill in the form on the Input tab, switch the editor from Form to JSON, and copy the result into your code.

๐Ÿ’ฐ How much does it cost to scrape LinkedIn jobs?

Billing is per job returned, at the per-1,000 rate on the price card on this page. Searches, result pages, and jobs that fail to load are free, so maxJobsPerSearch doubles as a hard cost cap.

Add company details is the one thing billed on top, because it fetches a company page that produces no row of its own. It bills once per company per run however many of that company's jobs you get, so 40 jobs across 12 employers bills 40 jobs plus 12 companies. A lookup that fails is not billed.

โ“ FAQ

Do I need a LinkedIn account or cookies? No.

Can I scrape LinkedIn jobs for free? Yes. Registering on Apify comes with $5 of free platform credit every month, no credit card needed, which covers a few thousand jobs here.

Is there an official LinkedIn jobs API? LinkedIn's Talent APIs are open to approved partners only. This actor is the practical alternative: POST keywords and a location, get JSON back, no partnership application.

Why is there no remote or seniority filter? LinkedIn's public search accepts both parameters and then ignores them, so a toggle here would do nothing. Put remote in the keyword to bias the search, then filter on the is_remote and seniority columns, which are read from each job's own page and accurate.

Why did my search return fewer jobs than LinkedIn shows? LinkedIn caps any public job search at 1,000 results. Split the search by location or by posting window and each search gets its own 1,000; a job found twice is still returned once.

I filtered by job type and got other types anyway? When too few postings match, LinkedIn relaxes the filter and returns adjacent types rather than an empty page. employment_type on each row is always the truth.

Does it include the recruiter or an external apply URL? No. Both are shown to logged-in members only, so they are left out rather than guessed at. view_url always gets you to the posting itself.

What happens when LinkedIn blocks a request? The actor retries through a US proxy on a fresh IP, up to 5 times. If 15 requests fail back to back, the run stops with an explanation instead of grinding on, and everything scraped so far stays in the dataset.

Is this legal? It collects only publicly visible job postings, published deliberately so people can find and apply to them. No private data, no logins. You are responsible for how you use the output, and GDPR applies if you store personal data an employer wrote into a description.

๐Ÿ›Ÿ Support

Something not working, or a field missing? Message me in the Issues tab and I'll look into it quickly. I'm a solo dev, so don't hesitate.

Watching specific companies rather than keywords? The LinkedIn Company Jobs Scraper takes a company and returns every opening it has, with no search ceiling.

  • Thodor