LinkedIn Jobs Scraper — No Cookies, No Login, $1/1k
Pricing
from $1.00 / 1,000 job scrapeds
LinkedIn Jobs Scraper — No Cookies, No Login, $1/1k
LinkedIn jobs scraper: title, company, location, posted date and URL by keyword and location. No cookies, no login. $1 per 1,000 jobs.
Pricing
from $1.00 / 1,000 job scrapeds
Rating
0.0
(0)
Developer
Mohammed Samaan
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
12 days ago
Last modified
Categories
Share
LinkedIn Jobs Scraper
Scrape LinkedIn job postings by keyword and location — title, company, location, posted date, salary (when shown), URL, and optional full detail (description, seniority, employment type, job function, industries, applicant count). No browser: it talks to LinkedIn's own public guest jobs API (the endpoint linkedin.com/jobs itself calls for "see more jobs" pagination), the same one used for the diagnostic probe that confirmed this approach.
Price: $1 per 1,000 jobs, +$1 per 1,000 detail fetches. Rows are de-duplicated by job ID across every keyword in one run.
What you get
One dataset row per job posting:
| Field | Description |
|---|---|
jobId | LinkedIn job ID — the stable key used for de-duplication |
title | Job title |
company | Hiring company name |
companyUrl | Company page URL, when the card has one |
location | Location as shown on the posting |
postedText | Posted date as shown, e.g. "2 days ago" |
postedAt | Posted date as an ISO 8601 date, e.g. 2026-09-21, when LinkedIn provides it |
salaryText | Salary text when the posting shows it, otherwise null |
url | Link to the job posting |
keyword | The keyword this row was found under |
searchLocation | The location you searched |
scrapedAt | When the row was written (ISO timestamp) |
With fetchDetails: true each row also carries:
| Field | Description |
|---|---|
description | Full job description text |
seniorityLevel | e.g. "Mid-Senior level" |
employmentType | e.g. "Full-time" |
jobFunction | e.g. "Health Care Provider" |
industries | e.g. "Hospitals and Health Care" |
applicantsText | Applicant count text, when LinkedIn shows it |
Honest limits
This actor uses no cookies, no login, and no proxies — plain HTTP requests against LinkedIn's guest API. LinkedIn may throttle or block large or repeated runs from a single IP; if that happens the actor detects it (status 429/403/999 or an "authwall" response body) and stops gracefully after 5 consecutive blocked requests, keeping whatever rows it already collected rather than retrying forever. Treat it as best-effort, not a guaranteed-reliable feed for large volumes.
Where this stands as of 21 Sep 2026, measured rather than assumed: a probe run from Apify's own servers sent 30 requests to the jobs-search endpoint and 30 to the guest jobs API and got HTTP 200 with real job data on 60 of 60 — zero blocks, zero empty pages, no degradation as the run progressed (12,377
- 2,256 job cards over ~2 minutes). A separate proof run pulled 225 unique jobs in 50 seconds. The rate limiting above is real, but it is not what you hit at normal volumes.
Who it's for
- Recruiting and staffing agencies tracking new postings in a market
- Market research — what roles/employers are hiring, by city
- Lead generation — companies actively hiring signal budget and growth
Inputs
| Field | What it does |
|---|---|
keywords | Search terms, one per line (required) |
location | Location to search (default United Arab Emirates) |
maxJobsPerKeyword | Cap per keyword (default 100, max 1000) |
datePosted | any / day / week / month |
jobType | any / fulltime / parttime / contract / internship |
remote | any / onsite / remote / hybrid |
fetchDetails | Fetch full description + criteria per job (extra charge) |
Example input
{"keywords": ["nurse", "chef"],"location": "Dubai","maxJobsPerKeyword": 100,"datePosted": "week","fetchDetails": false}
Example output
One row per job. This is a real row from a run on "software engineer" in the United States (28 Sep 2026, fetchDetails off):
{"jobId": "4419969671","title": "Senior Software Engineer – Go (Golang)","company": "General Motors","companyUrl": "https://www.linkedin.com/company/general-motors","location": "Warren, MI","postedText": "2 weeks ago","postedAt": "2026-09-12","salaryText": null,"url": "https://www.linkedin.com/jobs/view/senior-software-engineer-%E2%80%93-go-golang-at-general-motors-4419969671","keyword": "software engineer","searchLocation": "United States","scrapedAt": "2026-09-28T16:04:24.242Z"}
With fetchDetails: true, rows also get description, seniorityLevel, employmentType, jobFunction, industries and applicantsText.
Pricing
Pay per event, so you only pay for rows you actually get:
| Event | Price | Charged |
|---|---|---|
job-scraped | $0.001 per job = $1.00 per 1,000 jobs | Once per unique job posting written to the dataset |
job-detail | $0.001 per job = $1.00 per 1,000 details | Once per job whose full detail page was fetched — only when fetchDetails is enabled |
A run also incurs a one-off Actor start event (configured at $0.00005), a rounding error next to the per-job charges. Blocked pages, empty pages and retries cost nothing, de-duplication means you are never charged twice for the same job, and if the run stops early because LinkedIn is blocking it you keep — and pay for — only the rows already collected.
Tips
- Tracking fresh postings?
datePosted: "day"plus a keyword list is the cheapest way to see what changed. fetchDetailsadds a second event per job — turn it on only when you need descriptions or seniority.- Cheapest useful test: one keyword with
maxJobsPerKeyword: 25(one page) costs about $0.025. - Add a keyword for each role and each city (e.g.
nurse/Dubai,chef/Doha). Rows are de-duplicated across all keywords in a run, so overlapping searches cost nothing extra.
Disclaimer
This actor collects only job postings that LinkedIn serves publicly to logged-out visitors, with rate limiting. It does not log in, bypass any paywall, or collect candidate data. Postings can contain company contact details — please respect applicable privacy laws (e.g. UAE PDPL, GDPR) when using the data for outreach.
How it works
LinkedIn's public jobs pages call
https://www.linkedin.com/jobs-guest/jobs/api/seeMoreJobPostings/search
with keywords, location, start (25 results per page) and filter params
(f_TPR date posted, f_JT job type, f_WT workplace type) to lazily load
more cards — no login required. This actor calls that same endpoint directly
and parses the returned HTML fragment with cheerio. Job detail pages come
from the equivalent jobPosting/<id> guest endpoint. Concurrency 3, 1s delay
per request, retries with exponential backoff on 429/5xx/999.
FAQ
Do I need a LinkedIn account, cookies or a proxy? No. The actor uses LinkedIn's public guest jobs endpoints, with no login, no cookies and no proxy.
How many jobs can I get per keyword? Up to maxJobsPerKeyword, which defaults to 100 and is capped at 1000. Results come 25 per page, and a job that appears under several keywords in the same run is written and charged once.
What happens if LinkedIn blocks the run? Blocked responses (429, 403, 999 or an authwall page) are retried, and after 5 blocked requests in a row the run stops and keeps the rows it already collected. You are charged only for rows actually written. See "Honest limits" above.
Why is salaryText empty? It is filled only when LinkedIn shows a salary on the job card. In the example output above it is null.
What does fetchDetails add, and what does it cost? One extra request per job for the description, seniority, employment type, job function, industries and applicants text, plus one job-detail charge for each job whose detail page was fetched. If a detail fetch fails, the job is still written once without the detail fields and no job-detail charge applies.
Can I send the jobs to Notion? Yes, see the Notion section below. The first 500 rows of a run go to Notion and the full set stays in the dataset.
Send results to Notion (new, Sep 2026)
Authorize Notion once in Apify Console → Settings → API & Integrations → MCP connectors (choose Notion, sign in). Then pick that connector in Notion connector and paste the link of any Notion page in Notion page to create the table in. The first run creates a table inside that page and fills it with the job postings (up to 500 rows per run; the full set is always in the dataset). To keep adding to the same table on later runs, paste the table ID from the log into Existing Notion table ID. This Actor never sees your Notion login: Apify's connector proxy holds it. If the Notion step fails, your dataset results are still delivered and the reason is logged.
Use it from an AI agent (MCP)
Add this Actor to any MCP client (Claude, Cursor, VS Code) with one URL:
https://mcp.apify.com?tools=leadharbor/linkedin-jobs-scraper
Or call it through the Apify API with an input like this:
{"keywords": ["software engineer"],"location": "United States","maxJobsPerKeyword": 50,"remote": "remote"}
Returns one row per job posting: title, company, location, posted date and URL. Results land in the run's default dataset (JSON, CSV or Excel). No login or API key is needed for the sites it reads, and pay-per-event pricing works with Apify's x402 agent payments.
API usage
Run it from your own code with an Apify API token. The input below is this actor's prefilled example.
curl (runs the actor and returns the dataset items):
curl -X POST "https://api.apify.com/v2/acts/leadharbor~linkedin-jobs-scraper/run-sync-get-dataset-items" \-H "Authorization: Bearer $APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"keywords": ["nurse"],"location": "United Arab Emirates"}'
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("leadharbor/linkedin-jobs-scraper").call(run_input={"keywords": ["nurse"],"location": "United Arab Emirates"})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
Changelog
28 Sep 2026 — Optional Notion output; MCP agent section; public example tasks. Plus 5 public example tasks with their own pages.
More from leadharbor
- Google Maps MX-Checked Email Scraper
- YouTube Video Scraper
- Airbnb Listings Scraper
- E-commerce Price & Restock Monitor
- App Store Review Monitor
- Local Review Booster
- Website Contact Extractor
- Bulk Email Verifier
- USA Business Email Finder
- UK Business Email Finder
- UAE Business Email Finder
- UAE Property Broker Contacts
Using this actor? A quick review helps other buyers find it: linkedin-jobs-scraper
Find us on RapidAPI
- LinkedIn Jobs Search on RapidAPI: a REST API over the same public guest jobs endpoint, with a free plan.
Related actors
- Disposable Email & Domain Checker — Flags throwaway and free-provider email domains using 5 merged public lists. $0.30 per 1,000 checks.
- Domain Trust Check — 0-100 trust score for a domain from domain age, SSL, SPF/DKIM/DMARC and disposable-domain lists. $2.50 per 1,000 domains.
- Website Contact Extractor — Pulls emails, phone numbers and social links from website URLs.
- Bulk Email Verifier — Verifies email addresses: syntax, MX, disposable and role flags, and a 0-100 score. $0.50 per 1,000.