LinkedIn Jobs Scraper — No Cookies, No Login, $1/1k avatar

LinkedIn Jobs Scraper — No Cookies, No Login, $1/1k

Pricing

from $1.00 / 1,000 job scrapeds

Go to Apify Store
LinkedIn Jobs Scraper — No Cookies, No Login, $1/1k

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

Mohammed Samaan

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

12 days ago

Last modified

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:

FieldDescription
jobIdLinkedIn job ID — the stable key used for de-duplication
titleJob title
companyHiring company name
companyUrlCompany page URL, when the card has one
locationLocation as shown on the posting
postedTextPosted date as shown, e.g. "2 days ago"
postedAtPosted date as an ISO 8601 date, e.g. 2026-09-21, when LinkedIn provides it
salaryTextSalary text when the posting shows it, otherwise null
urlLink to the job posting
keywordThe keyword this row was found under
searchLocationThe location you searched
scrapedAtWhen the row was written (ISO timestamp)

With fetchDetails: true each row also carries:

FieldDescription
descriptionFull job description text
seniorityLevele.g. "Mid-Senior level"
employmentTypee.g. "Full-time"
jobFunctione.g. "Health Care Provider"
industriese.g. "Hospitals and Health Care"
applicantsTextApplicant 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

FieldWhat it does
keywordsSearch terms, one per line (required)
locationLocation to search (default United Arab Emirates)
maxJobsPerKeywordCap per keyword (default 100, max 1000)
datePostedany / day / week / month
jobTypeany / fulltime / parttime / contract / internship
remoteany / onsite / remote / hybrid
fetchDetailsFetch 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:

EventPriceCharged
job-scraped$0.001 per job = $1.00 per 1,000 jobsOnce per unique job posting written to the dataset
job-detail$0.001 per job = $1.00 per 1,000 detailsOnce 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.
  • fetchDetails adds 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 ApifyClient
client = 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


Using this actor? A quick review helps other buyers find it: linkedin-jobs-scraper

Find us on RapidAPI

  • 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.