LinkedIn Jobs Scraper — Search, Company Jobs & Job Details
Pricing
from $2.64 / 1,000 search jobs
LinkedIn Jobs Scraper — Search, Company Jobs & Job Details
Scrape LinkedIn job postings with the exact posting date, employer logo and LinkedIn URL, apply links, seniority, job function, industries, applicant count and structured salary. Search by keyword, list every open job at up to 10 companies, or batch full details for up to 20 job ids.
Pricing
from $2.64 / 1,000 search jobs
Rating
0.0
(0)
Developer
SIÁN OÜ
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
LinkedIn Jobs Scraper — Jobs, Salaries & Exact Posting Dates 🚀
🎉 Every job carries its exact posting date — not "2 weeks ago"
Built for recruiters, job boards and anyone whose analysis breaks on a relative date
🔎 What is the LinkedIn Jobs Scraper — and when should you use it?
The LinkedIn Jobs Scraper turns public LinkedIn job postings, with the exact date each one went up into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.
Use it when you need: LinkedIn job postings as rows: title, employer and the employer's LinkedIn company page, location, the exact posting date rather than a relative label, and the full description with working apply links. Each row also carries seniority level, job function, industries, applicant count, hiring badges, and a structured salary range wherever LinkedIn publishes one. Every job names its employer's numeric LinkedIn company id too, so jumping from one interesting posting to that company's whole open-role list is a single follow-up run.
Use something else when: the roles are not on LinkedIn, or one job board is not enough. Use Jobs Search API for Indeed, Glassdoor and other boards aggregated into this same row shape. Use Active Job Postings Scraper for roles read straight from 90,000+ employer applicant-tracking systems instead of a job board. Use Glassdoor Scraper for employer reviews, salary reports and interview notes rather than open roles. This actor covers LinkedIn's public, logged-out jobs surface. It cannot return anything that lives behind a LinkedIn login: there is no job-poster profile, no recruiter contact, no applicant insight and no employer applicant-tracking link. LinkedIn also caps any single result set at 1,000 jobs for everyone, so a broader pull has to be split by city or by narrower keywords.
🤖 Use with AI agents
Already connected to the Apify MCP server? Just ask for this Actor by name: sian.agency/linkedin-jobs-scraper
Your agent can pay for its own runs. This Actor is eligible for agentic payments, so an agent can discover it, run it and settle the bill over x402 (USDC on Base) or Skyfire — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.
Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:
I want LinkedIn job postings, salaries and exact posting dates using the Apify Actor `sian.agency/linkedin-jobs-scraper`.Use it when I need: LinkedIn job postings as rows: title, employer and the employer's LinkedIn company page, location, the exact posting date rather than a relative label, and the full description with working apply links. Each row also carries seniority level, job function, industries, applicant count, hiring badges, and a structured salary range wherever LinkedIn publishes one. Every job names its employer's numeric LinkedIn company id too, so jumping from one interesting posting to that company's whole open-role list is a single follow-up run.Don't use it when: the roles are not on LinkedIn, or one job board is not enough — use jsearch-jobs-scraper or active-job-postings-scraper or glassdoor-data-scraper instead.How to call it: pick one `operation` per run. `search` finds jobs by keyword: give it `query`, optionally a free-text `location` such as "Berlin, Germany", and `maxResults`. `companyJobs` returns every open role at up to 10 companies at once, named in `companyIds` as numeric ids or in `companies` as vanity slugs and company page URLs. `jobDetails` re-fetches up to 20 already-known jobs per call from `jobIds`; it is billed per job id, so it is for refreshing a shortlist rather than bulk collection. `datePosted` narrows to the last day, three days, week or month and is applied by LinkedIn itself, so it costs nothing extra. `employmentTypes` and `seniorityLevels` are applied after fetching instead, because LinkedIn ignores its own versions when logged out; they return fewer rows and cost more to run. `radiusKm` needs `geoId`, since LinkedIn ignores a radius on a free-text location. `includeDetails` is on by default and fills the description, salary, seniority, function and industries; turning it off is about 3x faster and leaves those empty. A search page returns 10 fully-detailed jobs for the price of one request, so collecting descriptions and salaries through `search` costs far less per job than looping `jobDetails`..Start with this input:{"operation": "search","query": "software engineer","location": "United States","datePosted": "week","maxResults": 50}Ask me which role or keyword they want, which location, and whether they need the full description and salary or only the faster card-level fields, then run the Actor and summarise the results as a table.
Things you can ask your agent for:
- Find senior backend roles posted in Berlin this week and show which ones publish a salary range.
- List every open job at Microsoft, Stripe and Datadog, grouped by job function and seniority.
- Re-check these job ids and tell me which postings have closed since last month.
Machine-readable API, MCP config and OpenAPI definition for this Actor are published at apify.com/sian.agency/linkedin-jobs-scraper.md.
📋 Overview
LinkedIn publishes a date. Most scrapers hand you a shrug. This Actor returns LinkedIn job postings as structured rows, with the real calendar date on every search result, so freshness is something you can compute instead of estimate.
Why professionals choose us:
- ✅ Exact posting dates: every search row carries the real date and a midnight-UTC timestamp, plus LinkedIn's own label if you still want it
- ⚡ Three jobs in one Actor: keyword search, every open role at up to 10 companies, and batch detail for up to 20 job ids
- 🎯 47 fields per job: description, salary range, seniority, job function, industries, applicant count, hiring badges, employer logo and company page
- 💰 Charged per job, never per attempt: a search that matches nothing and a closed posting both cost you nothing
- 💎 Drop-in compatible: the row shape matches our Jobs Search API, so adding LinkedIn to an existing pipeline needs no re-mapping
- 🔓 No login, ever: reads LinkedIn's public pages, so there is no account of yours to restrict and no credential to hand over
✨ Features
- 🔍 Keyword search: job title, skill or free text, anywhere in the world
- 🏢 Company job lists: up to 10 companies per run, by numeric id, vanity slug or plain company URL
- 📋 Batch job details: refresh up to 20 known job ids in one call, for keeping a saved shortlist current
- 🗓️ Real dates: exact posting date, UTC timestamp, and LinkedIn's relative label side by side
- 💰 Structured salary: minimum, maximum, period and currency as separate numeric fields
- 📈 Seniority and function: LinkedIn's own vocabulary, not a guessed years-of-experience number
- 👥 Applicant counts: find roles that are open but not yet crowded
- 🌍 Global coverage: free-text locations worldwide, or a LinkedIn geo id with a radius in kilometres
- 🎚️ Freshness filter: last 24 hours, 3 days, week or month, applied by LinkedIn itself
- 📄 Run report: every run writes an HTML summary with your rows, your costs and a fix for anything that failed
🎬 Quick Start
Pick an operation, give it a keyword or a company, and run. Results land in your dataset as JSON, CSV or Excel. A free run returns up to 25 jobs so you can see the shape before you spend anything.
curl -X POST "https://api.apify.com/v2/acts/sian.agency~linkedin-jobs-scraper/runs?token=YOUR_TOKEN" \-H 'Content-Type: application/json' \-d '{"operation": "search", "query": "software engineer", "location": "United States"}'
🚀 Getting Started (3 Simple Steps)
Step 1: Choose an operation
Search Jobs for keyword discovery, Company Jobs to list everything open at named companies, or Job Details to refresh job ids you already hold.
Step 2: Fill in the one field that operation needs
A keyword for search, a company id or slug for company jobs, a list of job ids for details. Everything else has a working default.
Step 3: Run it and open your dataset
Export to JSON, CSV or Excel, or read it straight from the API.
That's it. In under a minute, you'll have:
- Structured job rows with employers, locations and exact posting dates
- Salary ranges wherever LinkedIn published one
- Working apply links and employer LinkedIn pages
📥 Input Configuration
| Field | Type | Required | Description |
|---|---|---|---|
operation | string | Yes | search, companyJobs or jobDetails |
query | string | For search | Job title, skill or free text |
location | string | No | Free-text location, e.g. "Berlin, Germany" |
geoId | string | No | LinkedIn numeric geo id, needed for a radius |
radiusKm | integer | No | Radius in kilometres around the geo id |
datePosted | string | No | all, today, 3days, week, month |
employmentTypes | array | No | Full-time, part-time, contract, internship |
seniorityLevels | array | No | LinkedIn's seniority vocabulary |
remoteOnly | boolean | No | Only postings with an explicit remote marker |
companyIds | array | For companyJobs | Up to 10 LinkedIn company ids |
companies | array | For companyJobs | Up to 10 company slugs or page URLs |
jobIds | array | For jobDetails | Up to 20 job ids per call |
includeDetails | boolean | No | Fetch each job's detail page (default true) |
sortBy | string | No | relevance or date |
maxResults | integer | No | Upper bound on jobs returned (max 1000) |
country | string | No | Two-letter country code, default us |
Search example:
{"operation": "search","query": "data engineer","location": "Berlin, Germany","datePosted": "week","maxResults": 100}
Company jobs example:
{"operation": "companyJobs","companies": ["microsoft", "stripe"],"datePosted": "month"}
Job details example:
{"operation": "jobDetails","jobIds": ["bGlua2VkaW46NDQ1MzY3MDk3Mw"]}
📤 Output
Every job is written to the dataset with 47 fields. The most-used ones:
| Field | Type | Description |
|---|---|---|
jobTitle | string | The posting's title |
employerName | string | Company name |
employerLogo | string | Company logo image |
employerLinkedinUrl | string | The employer's LinkedIn company page |
linkedinCompanyId | string | Numeric company id, feeds straight into Company Jobs |
location | string | LinkedIn's location string, verbatim |
postedAtDate | string | The exact posting date |
postedAtTimestamp | integer | Midnight UTC of the posting date |
salaryString | string | Salary as LinkedIn prints it |
minSalary / maxSalary | number | Structured salary range |
salaryPeriod | string | YEAR, MONTH, HOUR |
seniorityLevel | string | LinkedIn's seniority label |
jobFunction | string | e.g. "Engineering and Information Technology" |
industries | array | Employer industries |
applicantsCount | integer | How many people have applied |
applyLink | string | Public LinkedIn posting URL |
jobDescription | string | Full posting text, typically 5,000–10,000 characters |
Example row (trimmed):
{"jobId": "bGlua2VkaW46NDQ1MzY3MDk3Mw","jobTitle": "Software Engineer III (Java/AWS)","employerName": "JPMorganChase","employerLinkedinUrl": "https://www.linkedin.com/company/jpmorganchase","linkedinCompanyId": "1068","location": "New York, NY","postedAtDate": "2026-09-03","postedAtTimestamp": 1788393600,"salaryString": "$137,750.00/yr - $185,000.00/yr","minSalary": 137750,"maxSalary": 185000,"salaryPeriod": "YEAR","seniorityLevel": "Not Applicable","jobFunction": "Engineering and Information Technology","industries": ["Financial Services"],"applicantsCount": 194,"applyLink": "https://www.linkedin.com/jobs/view/software-engineer-iii-java-aws-at-jpmorganchase-4453670973"}
💼 Use Cases & Examples
1. Recruiting Pipeline and Talent Sourcing
Recruiters and agencies tracking which roles are open, and how contested they are.
Input: a job title and a location, on a daily schedule Output: open postings with exact dates, seniority and applicant counts Use: pitch candidates at roles that are fresh and not yet crowded, using posting age and applicant count together.
2. Competitor Hiring Intelligence
Strategy and product teams watching where a rival is investing.
Input: up to 10 competitor companies in one Company Jobs run Output: every open role at each, with function, seniority and location Use: spot a team scaling, a new office opening, or a hiring freeze starting, weeks before it is announced.
3. Compensation Benchmarking
Comp analysts and founders setting bands they can defend.
Input: a job function and market, collected weekly Output: structured minimum, maximum, period and currency per posting Use: build a real salary time series, because exact dates make weekly cohorts trustworthy.
4. Job Board and Aggregator Content
Operators filling a niche board without a content team.
Input: a keyword set with datePosted set to today
Output: fresh postings with employer logo, company URL and apply link
Use: import only genuinely new roles each day instead of re-importing the same backlog.
5. Labor Market and Hiring Trend Analytics
Researchers and data teams measuring demand over time.
Input: broad queries across industries and seniority levels Output: posting volume tagged by function, industry and seniority Use: build monthly hiring indices that hold up, which relative labels such as "2 weeks ago" cannot support.
6. Lead Generation from Hiring Signals
Sales teams selling tools to a specific role.
Input: the job title your product serves Output: employers hiring for it, with LinkedIn company page and id Use: a company hiring a data engineer is a company buying data tooling, so reach out while the req is open.
7. Refreshing a Saved Job Shortlist
Anyone maintaining a curated list of roles.
Input: up to 20 stored job ids per call Output: current detail for each, with closed postings simply absent Use: detect filled roles: a missing id is a closed req. Billed per job id, so use it to refresh a shortlist rather than to collect in bulk.
🔗 Integration Examples
JavaScript/Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('sian.agency/linkedin-jobs-scraper').call({operation: 'search',query: 'software engineer',location: 'United States',datePosted: 'week',});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items[0]);
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('sian.agency/linkedin-jobs-scraper').call(run_input={'operation': 'search','query': 'software engineer','location': 'United States','datePosted': 'week',})for item in client.dataset(run['defaultDatasetId']).iterate_items():print(item)
cURL
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~linkedin-jobs-scraper/runs?token=YOUR_TOKEN' \-H 'Content-Type: application/json' \-d '{"operation": "search", "query": "software engineer", "location": "United States"}'
Automation Workflows (N8N / Zapier / Make)
- Trigger: a daily schedule
- HTTP Request: run the Actor with
datePosted: "today" - Process: filter the rows on seniority or salary
- Action: append to a sheet, post to Slack, or create CRM records
📊 Performance & Pricing
FREE Tier (Try It Now)
- 25 jobs per run, every field, same quality
- No credit card required
- Enough to see the row shape and check the fields you need
PAID Tier (Production Ready)
- Unlimited jobs per run, up to LinkedIn's own 1,000-per-search ceiling
- Pay per job written to your dataset. A search that matches nothing costs nothing
💰 You are charged for jobs, not attempts. Failed inputs, closed postings and empty searches are all free.
❓ Frequently Asked Questions
Q: Do I need a LinkedIn account, cookies or a session? A: No. This Actor reads LinkedIn's public, logged-out job pages. There is no account to connect and nothing of yours at risk.
Q: Is the posting date the real date, or LinkedIn's "2 weeks ago"? A: The real date. Every search row carries the calendar date and a midnight-UTC timestamp, and LinkedIn's own label is kept alongside it. On Job Details the date is derived from the relative label and can be a few days out, so Search Jobs is the authoritative source for exact dates.
Q: How many jobs can one search return? A: Up to 1,000. LinkedIn serves 10 per page and caps any single result set at 100 pages, for everyone. Split by city or narrower keywords to go further.
Q: Why did "Remote jobs only" return almost nothing? A: LinkedIn's public payload has no workplace-type field, so the remote flag is matched from wording in the title or location. It under-returns on purpose: a row marked remote really is remote, but many remote jobs are never marked.
Q: Can I get every open job at a specific company? A: Yes, that is the Company Jobs operation. Give it up to 10 companies as ids, slugs such as "microsoft", or company page URLs.
Q: Why are description, salary and seniority empty on some runs? A: Those live on a job's detail page, not on a search card. They fill whenever "Fetch full job details" is on, which is the default. Turning it off makes a run roughly 3x faster and leaves them empty.
Q: Does this return the employer's own application link? A: No. The apply link is the public LinkedIn posting URL. The employer's own system sits behind LinkedIn's login wall and is not in the public payload.
Q: What export formats are available? A: JSON, CSV and Excel, straight from the Apify dataset, or over the API.
Q: Which operation is cheapest per job? A: Search Jobs and Company Jobs, by a wide margin. A single search page returns 10 fully-detailed jobs for one unit of cost, while Job Details is billed per job id. Collect with Search Jobs; use Job Details only to refresh ids you already hold.
🐛 Troubleshooting
A search returned zero jobs
- Widen
datePosted:todayis a narrow window - Drop
employmentTypesandseniorityLevels: LinkedIn ignores its own versions of these, so they are applied afterwards and cut results hard - Try the location as free text ("Berlin, Germany") rather than a geo id
Company Jobs returned nothing
- A numeric company id that does not exist returns the same empty result as a real company with no open roles
- Pass the slug instead (
microsoft), which fails loudly and names itself
"Radius needs a LinkedIn Geo ID"
- LinkedIn ignores a radius when the location is free text, so the pair is rejected rather than silently dropped
- Copy the
geoId=value from a linkedin.com/jobs search URL, or remove the radius
One of the companies in my list broke the whole run
- One unknown slug fails the request. Remove it, or use numeric ids, which cannot fail to resolve
⚖️ Is it legal to scrape data?
Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.
However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.
You can also read Apify's blog post on the legality of web scraping.
LinkedIn is a trademark of LinkedIn Corporation, a Microsoft subsidiary. This Actor is not affiliated with, endorsed by, or sponsored by LinkedIn.
🤝 Support
Join our active support community
- For issues or questions, open an issue in the actor's repository
- Check SIÁN Agency Store for more automation tools
- 📧 apify@sian-agency.online
Built by SIÁN Agency | More Tools