LinkedIn Jobs Scraper
Pricing
from $0.30 / 1,000 job scrapeds
LinkedIn Jobs Scraper
Scrape LinkedIn jobs by keyword, location, company or search/job URL. Get salary, description, seniority, employment type and applicants. Job type, experience and remote filters that really work, up to ~1,000 jobs per search. No login. $0.50 per 1,000 jobs.
Pricing
from $0.30 / 1,000 job scrapeds
Rating
4.7
(3)
Developer
Automation Lab
Maintained by CommunityActor stats
6
Bookmarked
1.1K
Total users
240
Monthly active users
a day ago
Last modified
Categories
Features
Share
Scrape LinkedIn job listings by keyword, location, company, and filters, or from LinkedIn job search and job URLs. Extract salary, company info, full descriptions, applicant counts, and more. No login or cookies required. Up to about 1,000 jobs per search.
Use it for hiring-intent lead generation, recruiting intelligence, salary benchmarking, and job market research. Search LinkedIn jobs by keyword, company, or location, then export structured job data to your CRM, spreadsheet, or enrichment pipeline.
What does LinkedIn Jobs Scraper do?
LinkedIn Jobs Scraper extracts job posting data from LinkedIn using the public guest API. It searches for jobs by keyword and location, then extracts detailed information including salary ranges, company profiles, job descriptions, seniority levels, and applicant counts. No LinkedIn account or cookies needed.
Who is it for?
It is built for teams that need fresh hiring signals fast:
- Sales and lead generation teams — find companies actively hiring for roles related to your product, then prioritize outreach using real-time hiring intent
- Recruiters and talent teams — monitor competitor hiring, compensation ranges, and role requirements across markets
- Marketing and research teams — analyze job trends, remote-vs-onsite demand, and language from live job descriptions
- Developers and data teams — pipe LinkedIn jobs into ETL workflows, dashboards, or AI agents through the Apify API
Why use LinkedIn Jobs Scraper?
- No login or cookies required — uses LinkedIn's public guest jobs endpoints
- Full job detail extraction — salary, description, seniority, employment type, industries, and applicant count
- Useful for prospecting — identify fast-growing companies by hiring volume, role mix, and geography
- Flexible input workflows — run one query, many queries in many locations, LinkedIn job search URLs, single job URLs, or any combination
- Filters that really filter — LinkedIn ignores job type, experience level and workplace type for logged-out visitors; this scraper checks every job against them and keeps paging until it has your count
- Company, Easy Apply and freshness filters — company IDs, Easy Apply only, and jobs from the past hour, day, week or month
- Deterministic deduplication — duplicate searches and job IDs are removed across the entire run
- Fast and lightweight — pure HTTP architecture, 256 MB memory, no browser overhead
- Easy export — download results as JSON, CSV, or Excel, or connect to Zapier, Make, and custom APIs
What data can you extract?
| Field | Description |
|---|---|
| Job title | Full position title |
| Company | Company name, LinkedIn URL, and logo |
| Location | Job location (city, state, country) |
| Salary | Salary range when available |
| Workplace type | Remote, On-site, or Hybrid, when the title, location or description says so (LinkedIn hides its badge from logged-out visitors) |
| Description | Full job description (HTML and plain text) |
| Seniority level | Entry, Mid-Senior, Director, Executive, etc. |
| Employment type | Full-time, Part-time, Contract, etc. |
| Job function | Engineering, Marketing, Sales, etc., when LinkedIn shows it (most guest pages no longer do) |
| Industries | Industry sectors |
| Applicants count | Number of applicants (as integer) |
| Posted age | Human-readable LinkedIn label, such as 2 weeks ago (postedAt) |
| Posting date | Machine-readable ISO 8601 date when LinkedIn provides one (postedAtDate) |
| Apply URL | The LinkedIn page you apply from (LinkedIn shows external apply links only to signed-in users) |
| Benefits | Listed benefits, when LinkedIn shows them (rare on guest pages) |
| Job URL | Direct LinkedIn job posting link |
Why scrape LinkedIn jobs?
- Job market research -- Analyze hiring trends, in-demand skills, and salary benchmarks across industries and locations
- Recruitment intelligence -- Monitor competitor hiring activity and identify talent market dynamics
- Salary benchmarking -- Compare compensation packages across companies, roles, and regions
- Lead generation -- Identify companies that are actively hiring (growing companies = potential customers)
- Academic research -- Study labor market patterns, job description language, and employment trends
- Career planning -- Track job availability and requirements for specific roles
How to scrape LinkedIn jobs
- Go to the LinkedIn Jobs Scraper page on Apify Store.
- Click Try for free to open the actor configuration.
- Enter one search query, add multiple search queries, paste LinkedIn job search or job start URLs, or combine these input methods. Unusable start URLs are skipped and named in the run's status; when no usable query or URL remains, the run fails at once and nothing is charged.
- For query inputs, enter a location (e.g., "New York", "London") and optionally more locations; each query runs in each location. Start URLs keep the filters encoded in each URL.
- Optionally filter by job type, experience level, workplace type, date posted, Easy Apply, or company IDs.
- Set the maximum number of jobs you want (up to 1,000).
- Click Start and wait for your data.
- Download results as JSON, CSV, or Excel, or connect via the Apify API.
Input example
{"searchQueries": ["software engineer", "data engineer"],"startUrls": [{ "url": "https://www.linkedin.com/jobs/search/?keywords=platform%20engineer&location=United%20States&f_WT=2" }],"location": "United States","locations": ["Canada"],"maxJobs": 50,"jobType": "C","datePosted": "r604800","scrapeJobDetails": true}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| searchQuery | string | optional | Backwards-compatible single job title, keyword, or company name |
| searchQueries | string[] | [] | Additional queries to run in the same job |
| startUrls | object[] | [] | LinkedIn /jobs/search, /jobs/search-results or guest search API URLs, and single /jobs/view/... job URLs; use { "url": "..." } entries |
| location | string | "" | Location for query inputs; start URLs use their encoded location |
| locations | string[] | [] | More locations; every query runs in each one |
| companyIds | string[] | [] | Numeric LinkedIn company IDs (the f_C value in a LinkedIn jobs URL); works without a query too |
| easyApply | boolean | false | Only jobs with LinkedIn Easy Apply |
| maxJobs | integer | 50 | Max unique listings across all searches (up to 1,000) |
| jobType | string | "all" | F=Full-time, P=Part-time, C=Contract, T=Temporary, I=Internship (checked on each job) |
| experienceLevel | string | "all" | 1=Internship, 2=Entry, 3=Associate, 4=Mid-Senior, 5=Director, 6=Executive (checked on each job) |
| workplaceType | string | "all" | 1=On-site, 2=Remote, 3=Hybrid (read from the posting text) |
| datePosted | string | "all" | r3600=Past hour, r86400=Past 24h, r604800=Past week, r2592000=Past month |
| sortBy | string | "R" | R=Most relevant, DD=Most recent |
| scrapeJobDetails | boolean | true | Fetch full details (description, salary, criteria) |
Output example
{"id": "4370317193","title": "Software Engineer (New Grads) - San Francisco","url": "https://www.linkedin.com/jobs/view/software-engineer-new-grads-san-francisco-at-giga-4370317193","companyName": "Giga","companyLinkedinUrl": "https://www.linkedin.com/company/gigaml","companyLogo": "https://media.licdn.com/dms/image/v2/...","location": "San Francisco, CA","postedAt": "2 weeks ago","postedAtDate": "2026-03-03","salary": "$160,000.00/yr - $250,000.00/yr","applicantsCount": 200,"workplaceType": null,"descriptionHtml": "<strong>About Giga</strong>...","descriptionText": "About Giga...","seniorityLevel": "Not Applicable","employmentType": "Full-time","jobFunction": "Engineering and Information Technology","industries": "Software Development","applyUrl": "https://www.linkedin.com/jobs/view/...","benefits": null,"scrapedAt": "2026-03-17T17:38:24.331Z"}
Filters and search options
LinkedIn stopped applying the job type, experience level and workplace type filters for logged-out visitors: its public search returns the same jobs with or without them. This scraper reads each job's page and keeps only the jobs that match, then keeps paging until it has your Max Jobs or LinkedIn runs out (about 1,000 jobs per search). For a single uncommon job type (such as Contract) or Remote/Hybrid, it also adds that word to your keywords so matching jobs come first. Filtered runs read every job's page, so they take longer than unfiltered ones; you pay only for the jobs delivered. If none of the first 200 jobs of a search matches, that search stops and the run status says so; LinkedIn marks many jobs "Not Applicable" for seniority, so an experience filter can match nothing for some companies.
Date posted, Easy Apply and company IDs are applied by LinkedIn itself.
Job type filter
Filter results by employment type:
- Full-time (F) -- Standard full-time positions
- Part-time (P) -- Part-time roles
- Contract (C) -- Contract/freelance work
- Temporary (T) -- Temporary positions
- Internship (I) -- Internship opportunities
Experience level filter
Narrow by seniority:
- Internship (1), Entry level (2), Associate (3), Mid-Senior level (4), Director (5), Executive (6)
Workplace type filter
Find jobs matching your work preferences:
- On-site (1) -- In-office positions
- Remote (2) -- Fully remote roles
- Hybrid (3) -- Mix of remote and on-site
LinkedIn does not show the workplace badge to logged-out visitors, so the type comes from the posting: the title or location naming Remote or Hybrid, or clear wording in the description such as "fully remote" or "3 days per week in the office". Jobs that do not say are left out of a workplace-filtered run, and their workplaceType is null.
Company filter
Add numeric LinkedIn company IDs to Company IDs to get only those companies' jobs. Find an ID in the f_C= part of a LinkedIn jobs URL after clicking a company filter (for example, 1035 is Microsoft). With no search query, the run returns all of the companies' jobs.
Pricing
This actor uses pay-per-event pricing, cheaper per job than most LinkedIn job scrapers:
| Event | Price | Description |
|---|---|---|
| Run started | $0.005 | One-time charge, taken with the first delivered job (a run with bad input or no results costs nothing) |
| Job scraped | $0.0005 | Per job listing extracted |
Cost estimate: Scraping 1,000 job listings costs approximately $0.505 ($0.005 start + $0.50 for listings) on the Bronze plan; higher plans pay less per job. Several popular alternatives charge $1.00 or more per 1,000 results. The run stops at your Maximum charge per run and never delivers a job it could not charge.
Pure HTTP architecture (no browser overhead) means lower platform costs too. Runs on 256MB memory with datacenter proxy.
Data handling and limitations
The Actor reads public LinkedIn guest jobs pages via Apify proxy when available (or direct network otherwise); it needs no LinkedIn account or login cookies. It does not call an AI model. Search terms and public listing data are processed in the run, with results in the default Apify dataset. Failed operations send sanitized diagnostic input, exceptions, and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed; diagnostic reports are retained for 30 days. The Actor keeps no separate persistent cache. Apify account storage settings govern retention and deletion of datasets, key-value records, inputs, and logs. Avoid entering private or sensitive search terms; delete your run storage through Apify when no longer needed. This Actor is independent of LinkedIn and is not endorsed by it. Report problems using the Store issue tab.
Tips for best results
- Use specific keywords -- "react developer" returns more relevant results than "developer"
- Combine filters -- Use job type + experience level + workplace type to narrow results; filtered runs read every job page, so allow more time
- Set
scrapeJobDetails: falsefor faster runs when you only need listing summaries (title, company, location) - Sort by date (
sortBy: "DD") to find the newest postings first - LinkedIn caps results at ~1,000 per search -- add more queries or locations to get more
- The run status says what you got, for example "Got 50 of 50 jobs" or why it stopped early
Integrations
Connect LinkedIn Jobs Scraper with your tools and workflows:
- Google Sheets -- Export job listings directly to a spreadsheet for tracking and analysis
- Slack -- Get notified when new jobs matching your criteria are found
- Zapier -- Trigger workflows when new job data is available (e.g., alert hiring managers, update CRM)
- Make -- Build automated pipelines: scrape jobs, enrich data, then push to your ATS
- Webhooks -- Send results to your own API endpoint
- Schedule -- Run daily or weekly to monitor new job postings automatically
API usage
Use the Apify API to run LinkedIn Jobs Scraper from your code.
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("automation-lab/linkedin-jobs-scraper").call(run_input={"searchQuery": "data analyst","location": "New York","maxJobs": 50,"scrapeJobDetails": True,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(f"{item['title']} @ {item['companyName']} -- {item.get('salary', 'N/A')}")
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('automation-lab/linkedin-jobs-scraper').call({searchQuery: 'data analyst',location: 'New York',maxJobs: 50,scrapeJobDetails: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();items.forEach(item => console.log(`${item.title} @ ${item.companyName} -- ${item.salary}`));
cURL
curl -X POST "https://api.apify.com/v2/acts/automation-lab~linkedin-jobs-scraper/runs?token=YOUR_API_TOKEN&waitForFinish=120" \-H "Content-Type: application/json" \-d '{"searchQuery": "data analyst", "location": "New York", "maxJobs": 50}'
Use with AI agents via MCP
LinkedIn Jobs Scraper is available as a tool for AI assistants that support the Model Context Protocol (MCP).
Setup for Claude Code
$claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/linkedin-jobs-scraper"
Setup for Claude Desktop, Cursor, or VS Code
Add this to your MCP config file:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/linkedin-jobs-scraper"}}}
Example prompts
Once connected, try asking your AI assistant:
- "Search LinkedIn for 'software engineer' jobs in San Francisco"
- "Find all remote data scientist jobs posted this week"
- "Get marketing manager positions in London"
Learn more in the Apify MCP documentation.
FAQ
How much does it cost to scrape LinkedIn jobs?
At $0.0005 per listing, scraping 1,000 jobs costs about $0.51. Apify's free plan includes $5/month of platform credits, so you can scrape roughly 8,000 to 10,000 job listings per month for free.
How fast is the scraper?
Very fast -- it uses pure HTTP requests (no browser), so it can extract 100 jobs with full details in under 60 seconds. Without details (scrapeJobDetails: false), 100 listings complete in about 5 seconds.
Does it require a LinkedIn account?
No. This scraper uses LinkedIn's public guest API, which does not require login, cookies, or any LinkedIn account. It accesses the same data visible to anyone browsing LinkedIn jobs without signing in.
Does it extract full job descriptions?
Yes. With scrapeJobDetails: true (the default), the scraper fetches the complete job detail page for each listing. This includes the full HTML and plain text description, salary, seniority level, employment type, industries, and applicant count. Job function and benefits are filled when LinkedIn shows them, which is rare on guest pages.
What is the maximum number of results?
LinkedIn's guest API caps search results at approximately 1,000 per search. The Actor's maxJobs setting caps the unique results returned by the entire run, including all queries and start URLs.
What data formats can I export?
You can download results as JSON, CSV, Excel, XML, or HTML table. You can also access the data via the Apify API or connect it to Google Sheets, Zapier, Make, and other integrations.
Legality
Is it legal to scrape LinkedIn?
This actor is provided for educational and research purposes. Users are responsible for ensuring their use complies with LinkedIn's Terms of Service and applicable laws. Always use scraped data responsibly.
Why are some fields null?
Not all LinkedIn listings include salary, workplace type, or benefits information. When employers don't provide this data, the corresponding fields will be null. Use filters in your downstream processing to handle optional fields.
Can I scrape LinkedIn jobs on a schedule?
Yes. Use Apify Schedules to run the scraper daily or weekly. Combine with Google Sheets to build a live job tracking dashboard, or use Slack notifications to get alerted when new jobs match your criteria.
How does this compare to other LinkedIn scrapers?
This scraper takes structured input (keywords, locations, companies and filters) as well as LinkedIn search and job URLs, applies the job type, experience and workplace filters that LinkedIn ignores for logged-out visitors, and runs on 256MB with datacenter proxy (many alternatives need browser-based runs or higher memory). Paid Apify plans pay $0.0005 per job or less.
Technical details
- Architecture: Pure HTTP requests with cheerio HTML parsing -- no browser, no Playwright, no Puppeteer
- Memory: 256MB (minimum Apify allocation)
- Proxy: Works with datacenter proxy (no residential proxy needed)
- Rate limiting: Built-in delays between requests to avoid LinkedIn rate limits
- Retry logic: Configurable retry attempts with exponential backoff
- Pagination: Automatically paginates through search results (25 per page) in deterministic round-robin order
- Deduplication: Normalizes duplicate searches and tracks job IDs across all inputs
Limitations
- LinkedIn caps guest API search results at approximately 1,000 per query
- Some job listings may not include salary, workplace type, or benefits data
- LinkedIn occasionally rotates HTML structure -- if extraction breaks, please report an issue
- The guest API does not support scraping company detail pages (employee count, revenue, etc.)
- Very high-volume scraping may trigger temporary rate limits from LinkedIn
How do I scrape LinkedIn job postings without a LinkedIn account?
LinkedIn Jobs Scraper uses LinkedIn's public guest API — the same data served to unauthenticated users who browse LinkedIn jobs without signing in. No LinkedIn account, cookies, or session tokens are required. You simply specify a search query and location, and the scraper returns structured job data including titles, companies, locations, salaries, descriptions, and applicant counts.
This approach is not only more convenient but also more stable than session-based scrapers, which break whenever LinkedIn rotates cookies or changes its authentication flow.
How can I use LinkedIn job data for salary benchmarking?
LinkedIn is one of the richest public sources of salary data because many job postings now include explicit salary ranges (driven by pay transparency laws in states like California, New York, and Colorado). To build a salary benchmark:
- Scrape job listings for a target role (e.g., "data scientist") across multiple locations.
- Filter results where
salaryis not null. - Parse the salary range strings (e.g.,
"$120,000/yr - $160,000/yr") into min/max figures. - Group by
locationorindustriesto build a regional or sector-level salary distribution.
This gives you a data-driven benchmark updated in near real-time — far more current than annual surveys from Glassdoor or Levels.fyi. Recruiters use this to set competitive offer ranges; candidates use it to evaluate offers and negotiate.
How do I monitor competitor hiring activity on LinkedIn?
A competitor posting 20 software engineer roles in a single month is a strong signal they are expanding their engineering team — and likely their product. Monitoring competitor hiring is a lightweight competitive intelligence technique that requires no insider information.
To track competitor hiring:
- Run LinkedIn Jobs Scraper with the competitor's company name as the
searchQuery. - Filter results by
companyNameto exclude unrelated listings. - Schedule daily or weekly runs and compare job counts over time.
- Look for patterns: are they hiring primarily in sales (revenue push), engineering (product build), or customer success (retention focus)?
By tracking which roles a competitor is filling — and at what seniority level — you can infer their strategic priorities months before any public announcement.
How do I find remote job opportunities in a specific field on LinkedIn?
To search exclusively for remote jobs in a given field, set workplaceType: "2" (Remote) alongside your keyword. For example, to find remote software engineering roles:
{"searchQuery": "software engineer","workplaceType": "2","jobType": "F","maxJobs": 100,"sortBy": "DD"}
Setting sortBy: "DD" (most recent) ensures you see freshly posted openings first. You can further narrow results with experienceLevel (e.g., "2" for entry-level, "4" for mid-senior) and datePosted: "r604800" to see only jobs posted in the past week. Use the nullable ISO 8601 postedAtDate field to sort or compare scheduled exports without parsing the human-readable postedAt label. Export to CSV for easy filtering in a spreadsheet, or use Google Sheets integration to build a live job tracker that refreshes automatically.
How can businesses use LinkedIn job scraping for lead generation?
Companies that are actively hiring in a specific function are often high-value sales prospects. A company posting 10 "data engineer" roles is likely investing heavily in their data infrastructure — which means they may need data tools, cloud services, or consulting. This "hiring signals" approach to lead generation is used by B2B sales teams to find companies at the right stage of growth.
To build a leads list from hiring signals:
- Scrape jobs for a role that signals your target buyer (e.g., "Head of Data", "VP Marketing", "Salesforce Administrator").
- Extract
companyNameandcompanyLinkedinUrlfrom results. - Deduplicate by company and sort by
applicantsCount(higher applicants = more competitive hiring = faster-growing company). - Enrich with Email Finder or Website Contact Finder to get contact details.
This produces a warm, intent-based prospect list of companies actively investing in the area your product serves.
Related scrapers
- Indeed Scraper -- Scrape job listings from Indeed with salary, company info, and descriptions
- Google Maps Lead Finder -- Find businesses and leads on Google Maps
- Email Finder -- Find email addresses for any company or domain
- Email Enrichment -- Enrich and verify email addresses in bulk
- Website Contact Finder -- Extract contact details from company websites
Server API: get LinkedIn jobs over HTTP
LinkedIn Jobs Scraper is also a Server Actor. Besides normal runs, it answers short HTTP requests directly, without starting a run for each lookup. Copy the server URL from the Actor's Server tab (do not build it from the Actor name) and authenticate with your Apify token. Use normal Actor runs for more than 25 jobs, several searches, or the job type, experience and workplace filters.
curl -sS "$SERVER_URL/job?url=https://www.linkedin.com/jobs/view/4431992044/" -H "Authorization: Bearer $APIFY_TOKEN"curl -sS "$SERVER_URL/search?keywords=python%20developer&location=United%20States&datePosted=r604800&maxJobs=10" -H "Authorization: Bearer $APIFY_TOKEN"
| Method and path | Input | Output and charge |
|---|---|---|
GET / | None | ready: true, the routes and limits; no scraping or charge |
GET /job | Query url: a LinkedIn job URL (linkedin.com/jobs/view/... or a URL with currentJobId) or a numeric job ID | {ok,count,results} with one job and its description and details, the same record as a normal run's dataset item; one Job scraped event (job-scraped); no start fee |
GET /search | Query keywords (required, 1–200 characters); optional location, datePosted (all, r3600, r86400, r604800, r2592000), sortBy (R most relevant, DD most recent), maxJobs (1–25, default 10) and details (true by default: each job's description and details; false: search fields only, faster) | {ok,count,results} with the first jobs of the search, the same records as a normal run's dataset items (a job whose page cannot be read keeps its search fields); one Job scraped event (job-scraped) per job; no start fee |
A missing job and a search without jobs return an error and are free. Each request has a 60-second deadline and a 1 MiB response cap, and one server works on at most six requests at once. Nothing is cached. Errors use { "ok": false, "error": { "code": "...", "message": "...", "retryable": false } }: 400 INVALID_URL or INVALID_INPUT; 402 spending limit; 404 NO_JOBS or unknown route; 405 wrong method; 413 RESPONSE_TOO_LARGE; 502 LINKEDIN_UNAVAILABLE, UPSTREAM_ERROR or charging failure; 503 server busy or stopping; 504 TIMEOUT. Failed requests are free. Retry only when retryable is true. The Server tab shows the full OpenAPI description.