Oink

Article

How to scrape LinkedIn jobs without login or cookies

linkedinscrapingjob-searchapify

If you have ever tried to automate a LinkedIn job search, you have probably hit the wall: the moment you script a logged-in session, LinkedIn's anti-automation defenses start throwing checkpoints, and you are one CAPTCHA away from a locked account. The good news is that for job postings specifically, you almost never need to log in at all.

This guide explains the approach that actually holds up: reading LinkedIn's public guest job-search endpoint — the same data an anonymous visitor sees before any sign-in prompt — and turning it into clean, structured JSON.

Why avoid login and cookies?

Scraping behind a login is fragile and risky for three reasons:

  • Account risk. Automated activity on an authenticated session is exactly what LinkedIn's systems flag. A scraped account can get restricted or banned.
  • Session rot. Cookies expire, sessions get invalidated, and 2FA challenges appear at the worst time. Any pipeline built on a logged-in cookie jar breaks constantly.
  • You do not need it. Job listings are public. Anyone can browse linkedin.com/jobs without an account, and there is a lightweight guest endpoint behind that page that returns postings as HTML fragments.

The guest endpoint is the key. It is designed to serve the public, un-authenticated jobs page, so hitting it needs no cookies, no session token, and no headless browser.

How the public guest endpoint works

When you open LinkedIn's jobs search while logged out, the page loads results from a paginated guest API. Each request takes a keyword, a location, an optional remote filter, a time window, and an offset for pagination, and it returns a batch of job cards as HTML.

From each card you can parse the fields that matter:

Field What it is
id Numeric posting id, extracted from the job URL
title Job title as posted
company Hiring company or organisation
location Location text (often includes a remote hint like Berlin, Germany (Remote))
postedAt Posting date, read from the card's machine-readable <time datetime> attribute
url Direct link to the posting

For the full description you follow the posting URL to LinkedIn's guest posting API — again, no login — and pull the plain-text body.

One thing the guest cards never carry is salary. If a scraper hands you a salary field for LinkedIn, it either fabricated it or scraped it from somewhere else. Honest LinkedIn data has no salary column.

The one real limitation: the ~200-result cap

Here is the single most important thing to know, and the thing most tutorials leave out:

LinkedIn's guest search endpoint only paginates to roughly 200 postings per query. Past that offset, it simply stops returning new results — it does not matter whether you ask for 500 or set "no limit." The ceiling is on LinkedIn's side, not on your scraper's.

This is not a bug you can code around by hammering the offset. Instead, you narrow your queries so each one stays under the cap and covers a slice you care about:

  • Split by keyword. Run react developer and vue developer as separate searches instead of one broad frontend.
  • Split by location. Berlin, Munich, Remote Germany as three runs rather than one country-wide sweep.
  • Split by time window. Search "past 24 hours" on a schedule (e.g. every day) so you continuously harvest new postings before they age out, rather than trying to backfill a month at once.

The last one is the real trick: a narrow query run often beats a broad query run once. Fresh postings are exactly what you want for a job search anyway.

Doing it without writing a scraper

You can implement all of the above yourself — parse the guest HTML, handle pagination, follow through for descriptions, and apply filters. But if you would rather skip the maintenance, we maintain a ready-to-run Actor that does exactly this on the Apify Store.

It reads only the public guest endpoint (no login, no cookies, no proxies to configure), applies the filters below, and returns one flat JSON record per posting:

  • keyword and location to target the search
  • remote to restrict to remote-eligible postings
  • timeFilter — past hour / 24 hours / week / month
  • maxItems (remember the ~200 hard ceiling per run)
  • includeDescription to fetch the full plain-text body
  • titleExclude / companyExclude to drop noise by keyword
LinkedIn Jobs Scraper — No Login, No Cookies

Filter by keyword, location, remote and posting age. Clean JSON out, no account required. Pay per run on the Apify Store.

Open on Apify →

Calling it from your own code is a single HTTP request that runs the Actor and returns the items in one response:

curl -X POST \
  "https://api.apify.com/v2/acts/nomad-agent~linkedin-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"keyword": "frontend developer typescript", "location": "Germany", "maxItems": 100}'

Each record comes back like this:

{
  "id": "4429472960",
  "title": "Senior Frontend Engineer (React)",
  "company": "Acme Software",
  "location": "Berlin, Germany (Remote)",
  "postedAt": "2026-06-30",
  "url": "https://www.linkedin.com/jobs/view/4429472960",
  "source": "linkedin",
  "description": "We are hiring a Senior Frontend Engineer..."
}

Is scraping public LinkedIn jobs legal?

This approach reads only publicly available job postings — data any visitor can see without logging in — and touches no personal data behind authentication. That is a materially different posture from scraping member profiles behind a login. Still, "public" is not a blanket legal clearance: review LinkedIn's terms of service and the regulations that apply to your specific use case and jurisdiction before you build on it.

Where this fits in a job-search pipeline

Raw postings are only step one. In practice you also want to:

  1. Deduplicate across runs (the id field makes this easy).
  2. Score each posting against what you actually want, instead of eyeballing hundreds of cards.
  3. Verify the listing is still open before you spend time applying.

That scoring-and-alerting layer is the hard part, and it is exactly what we built Oink to do.

Rather have the jobs come to you?

Oink runs this kind of search for you around the clock — upload a resume, describe what you want, and an AI pipeline scores fresh postings against your profile and pings you on the web or Telegram.

Try Oink free →

Happy hunting — and remember, keep each query narrow and let the freshness do the work.