Linkedin Jobs Scraper
Pricing
$24.99/month + usage
Linkedin Jobs Scraper
Retrieve LinkedIn job posts with titles, skills, experience levels, and employer details. Designed for HR teams, analysts, and researchers who need accurate market data.
Pricing
$24.99/month + usage
Rating
1.0
(1)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
66
Total users
4
Monthly active users
11 days ago
Last modified
Categories
Share
LinkedIn Jobs Scraper — Job Listings with Honest Applicant Counts
LinkedIn Jobs Scraper pulls public job postings straight from LinkedIn's guest job search — no login, no session cookie, no browser required. Give it keywords, a location, or a list of companies, and it returns typed JSON with the job title, company, exact posting date, salary (when stated), seniority, industry, the full description, and how many people applied. Every response is structured JSON, ready to pass directly to an LLM, load into a spreadsheet, or feed a monitoring pipeline. Applicant counts come back with an honesty flag — exact, at-least, or fewer-than — instead of a single ambiguous number, so downstream filtering and scoring don't quietly trust a bucketed figure as precise.
What is LinkedIn Jobs Scraper?
LinkedIn Jobs Scraper queries LinkedIn's public, logged-out job search surface and returns structured job postings as JSON, CSV, or Excel — no LinkedIn account, password, or li_at session cookie is ever requested or required. It supports two query modes: a plain keyword-plus-location search, or a company-scoped search built from a list of employer names, LinkedIn company URLs, or numeric company IDs. Where most LinkedIn job scrapers report applicantsCount as a single number, this Actor separates the raw LinkedIn phrasing ("Over 200 applicants", "Be among the first 25 applicants", "119 applicants") into a value plus a precision label — exact, at_least, or fewer_than — in the applicantsCountType field, so a report built on this data doesn't misrepresent a bucket as a count.
Key capabilities:
- 🔎 Keyword search across job titles and descriptions, with an optional location string LinkedIn's own search understands (city, country, or region name)
- 🏢 Company-scoped search by name, LinkedIn company profile URL, or numeric company ID — mixed freely in one run
- 🕐 Date-posted filtering (past 24 hours, past week, past month, or any time) — the one sort/filter control LinkedIn's guest endpoint actually honors
- 🏠 Work-arrangement, job-type and experience-level filters (on-site/remote/hybrid, full-time/contract/internship/etc., internship-through-executive)
- 📝 Full job description in both plain text and cleaned HTML, plus a description-derived salary figure and a list of benefit keywords when the posting mentions them
- 🌐 An optional
geoIdparameter for LinkedIn's own numeric location codes, with a country picklist and support for pasting any custom geoId from a LinkedIn search URL
When companyInput is used, each entry is resolved before searching: a numeric string is treated as a LinkedIn company ID directly; a linkedin.com/company/... URL has its slug extracted; anything else is treated as a company name and looked up against LinkedIn's public company page (and, if that lookup doesn't resolve, its /jobs-worldwide page) to find the matching company ID. If neither lookup resolves a name to an ID, the Actor falls back to a plain keyword search combining that company name with your keywords value, so a run never silently returns nothing just because a name couldn't be matched.
What data can you get with LinkedIn Jobs Scraper?
Every run returns one row per job posting, built from LinkedIn's guest search-result cards and each job's public detail fragment.
| Result Type | Extracted Fields | Primary Use Case |
|---|---|---|
| Job posting core | id, title, companyName, location, jobUrl, companyUrl, companyId | Building a searchable jobs dataset or feed |
| Timing | publishedAt (exact ISO date), postedTime (LinkedIn's relative string), scrapedAt | Tracking when a role went live and when your data was collected |
| Applicant signal | applicationsCount, applicantsCountType, applicantsText | Scoring competitiveness or freshness without misreading a bucketed count |
| Classification | contractType, experienceLevel, workType, sector | Filtering a dataset by employment type, seniority or industry |
| Compensation and culture | salary, benefits | Comparing pay signals and benefit mentions across postings |
| Description | description, descriptionHtml | Feeding a job description to an LLM, or rendering it in a UI |
| Poster | posterFullName, posterProfileUrl | Identifying the recruiter or hiring manager behind a listing, when LinkedIn shows one |
| Run diagnostics | errorReason | Auditing which job IDs failed to parse, without paying for them |
Honest applicant-count precision
LinkedIn's guest job pages state applicant numbers three different ways, and only one of them is an exact count: "119 applicants" is exact, "Over 200 applicants" is a floor, and "Be among the first 25 applicants" is a ceiling. Most scrapers copy the raw string or the first number they see and call it a count. This Actor parses all three forms and tags each one:
{"applicationsCount": "200","applicantsCountType": "at_least","applicantsText": "Over 200 applicants"}
applicantsCountType is one of exact, at_least, or fewer_than, and is null alongside applicationsCount: null when LinkedIn's page shows no applicant bullet at all. This matters for anything that ranks or filters on competitiveness — treating "over 200" as exactly 200 will systematically misrank against a job that genuinely has 119 exact applicants. The raw string always ships in applicantsText too, so you can re-derive your own logic if you don't want the Actor's interpretation.
Salary signals parsed from the description
LinkedIn's guest job surfaces publish no structured pay field — no min/max, no currency, no period. Every salary value in this dataset is extracted from the free-text job description, and only when it is anchored to genuine compensation wording ("salary", "per hour", "OTE", "DOE") or forms a plausible two-sided pay range ($1,000–$2,000,000). Currency figures tied to funding rounds, revenue, budgets, or reimbursements ("raised $20M", "$150 commuter reimbursement") are explicitly excluded from the match. salary is null on the (common) majority of postings that state no pay at all — a null here means LinkedIn didn't publish a figure, not that extraction failed.
Why not build this yourself?
LinkedIn does not offer a self-serve public API for job search — its Talent/Jobs API surfaces are partner-gated and require a commercial agreement, not something a developer can call with an API key today. Building a scraper directly against LinkedIn's guest job pages means maintaining your own pagination logic against an endpoint that serves 10 results per page (not the 25 many implementations assume), handling a cookie-borne session pin that silently re-serves page one after a certain point, decoding responses that mojibake without an explicit UTF-8 override, and re-discovering which selectors actually hold each field as LinkedIn's guest HTML changes. This Actor absorbs that maintenance — the retry logic, the session-reset handling, and the field selectors documented above — behind a fixed input schema and a stable JSON output shape, so a schema change on LinkedIn's side doesn't turn into a broken cron job on yours.
How to scrape LinkedIn with LinkedIn Jobs Scraper?
- Open LinkedIn Jobs Scraper on the Apify Store and click Try for free (or Run) to open the input form in Apify Console.
- Enter your query — fill
keywords(defaultSoftware Engineer) andlocation(defaultUnited States) for a plain search, or add one or more entries tocompanyInputto scope the search to specific employers. - Set the real query controls the schema exposes:
publishedAtfor date-posted,workTypefor on-site/remote/hybrid,contractTypefor employment type,experienceLevelfor seniority, andgeoIdif you want LinkedIn's own numeric location code sent alongsidelocation. - Set
maxJobs(1–1,000, default 20) and start the run. - Download results from the Dataset tab as JSON, CSV, Excel, or any other export Apify offers, or pull them programmatically with the Apify API or
apify-client.
A minimal keyword search needs no required fields at all — every input has a default, so an empty-input run still executes against keywords: "Software Engineer" and location: "United States".
A note on scale: LinkedIn's guest search endpoint itself refuses to page past offset 1,000 (it returns HTTP 400 once you ask for start=1000), which caps any single keyword-plus-location or company search at roughly 1,000 job listings no matter how high maxJobs is set. Setting maxJobs below that ceiling is purely a speed-and-cost lever — a smaller value finishes faster and bills fewer rows, since only successfully parsed jobs are charged.
How to run multiple queries in one job
companyInput accepts a list, so a single run can collect jobs across several employers at once — mix company names, LinkedIn company URLs, and numeric IDs in the same list, and the Actor resolves each to a company ID before searching. There is no built-in multi-keyword × multi-location matrix in this Actor (one keywords value and one location value per run); to cover several keyword/location combinations, schedule separate runs with different input, or drive them from the Apify API in a loop.
⬇️ Input
All fields are optional — the schema requires none of them. Below is every parameter this Actor's input schema accepts, exactly as declared in .actor/actor.json.
| Parameter | Required | Type | Default | Constraints |
|---|---|---|---|---|
companyInput | No | array of strings | ["Google"] (prefill) | stringList editor. Each entry is a company name, LinkedIn company URL, or numeric company ID |
keywords | No | string | "Software Engineer" | Free text; matched against job titles and descriptions |
location | No | string | "United States" | Any location string LinkedIn's job search understands |
maxJobs | No | integer | 20 | minimum: 1, maximum: 1000 |
sortOrder | No | string | "" | Enum: "" (Default), "relevance" (Most relevant — ignored), "date" (Most recent — ignored). Kept for backward compatibility only |
publishedAt | No | string | "" | Enum: "" (Any time), "r86400" (Past 24 hours), "r604800" (Past week), "r2592000" (Past month) |
workType | No | string | "" | Enum: "" (Any), "1" (On-site), "2" (Remote), "3" (Hybrid) |
contractType | No | string | "" | Enum: "" (Any), "F" (Full-time), "P" (Part-time), "C" (Contract), "T" (Temporary), "I" (Internship), "V" (Volunteer) |
experienceLevel | No | string | "" | Enum: "" (Any), "1" (Internship), "2" (Entry level), "3" (Associate), "4" (Mid-Senior level), "5" (Director), "6" (Executive) |
geoId | No | string | "" | select editor with suggested numeric values; any digit string is accepted (non-digit values are ignored and treated as empty) |
proxyConfiguration | No | object | {"useApifyProxy": false} | proxy editor. Apify Proxy is off by default; enable it only if LinkedIn blocks or throttles your run |
geoId suggested values (LinkedIn's own numeric country codes — you can also paste any city or other geoId copied from a LinkedIn search URL): Australia 101452733, Brazil 106057199, Canada 101174742, France 105015875, Germany 101282230, India 102713980, Italy 103350119, Japan 101355337, Mexico 103323778, Netherlands 102890719, Singapore 102454443, Spain 105646813, Switzerland 106693272, United Arab Emirates 104305776, United Kingdom 101165590, United States 103644278.
On proxyConfiguration: the default is no proxy at all — LinkedIn's public job surfaces are reachable directly, and that's the fastest and cheapest way to run this Actor. Turn Apify Proxy on only if you see blocks or empty pages from your region. When enabled, the Actor works through a built-in ladder — datacenter proxy groups first, residential as a fallback — with retries at each step, and proxy usage counts toward your normal Apify usage. An HTTP 999 response from LinkedIn during a run is a throttle signal, not a ban; the Actor backs off and retries automatically, so a proxy is usually unnecessary even when you see 999s logged.
Example input:
{"companyInput": [],"keywords": "Data Analyst","location": "Berlin","maxJobs": 100,"publishedAt": "r604800","workType": "2","contractType": "F","experienceLevel": "3","geoId": "","proxyConfiguration": { "useApifyProxy": false }}
Common pitfalls:
sortOrderis accepted and validated, but LinkedIn's public job endpoint ignores sorting entirely — the Actor's own measurement found the Default, Most relevant, and Most recent result sets byte-identical. Setting it does nothing except log a notice; usepublishedAtif you need recent postings, since that filter is genuinely honored by LinkedIn.companyInputentries are split on commas and on the standalone word "and" to support pasting a comma- or "and"-separated bulk list into one array entry. A company name that itself contains the word "and" written out (rather than "&") — for example "Procter and Gamble" — will be split into two separate names and searched as two unrelated companies. List such names as["Procter & Gamble"], or check your resolved company IDs in the run log if a company search returns unexpected results.- A search with no matching jobs is not an error: the run finishes with an empty dataset and a logged notice, and nothing is charged, since
row_resultonly fires per job actually pushed.
⬆️ Output
Results are pushed to the Actor's dataset as one typed JSON object per job — the same schema every run, whether a field is populated or null. Export the dataset as JSON, CSV, Excel (XLSX), or any other format Apify's dataset export supports.
Scraped results
[{"id": "4231987650","title": "Senior Data Analyst","companyName": "Cohere","location": "Berlin, Germany","publishedAt": "2026-07-18","postedTime": "1 week ago","salary": "€65,000 - €80,000 per year","applicationsCount": "200","applicantsCountType": "at_least","applicantsText": "Over 200 applicants","contractType": "Full-time","experienceLevel": "Associate","workType": "Information Technology","sector": "Software Development","jobUrl": "https://www.linkedin.com/jobs/view/4231987650","companyUrl": "https://www.linkedin.com/company/cohere-ai","companyId": "24024765","benefits": "health insurance, 401(k), remote, flexible","posterFullName": "Maria Keller","posterProfileUrl": "https://www.linkedin.com/in/maria-keller","description": "About the team... We are looking for a Senior Data Analyst to join our Berlin office...","descriptionHtml": "<p>About the team...</p><p>We are looking for a Senior Data Analyst...</p>","errorReason": null,"scrapedAt": "2026-07-25T09:14:02Z"},{"id": "4231987702","title": "Data Analyst, Marketing","companyName": "Delivery Hero","location": "Berlin, Germany","publishedAt": "2026-07-20","postedTime": "5 days ago","salary": null,"applicationsCount": "25","applicantsCountType": "fewer_than","applicantsText": "Be among the first 25 applicants","contractType": "Full-time","experienceLevel": "Entry level","workType": "Marketing","sector": "Internet Marketplace Platforms","jobUrl": "https://www.linkedin.com/jobs/view/4231987702","companyUrl": "https://www.linkedin.com/company/deliveryhero","companyId": "802643","benefits": null,"posterFullName": null,"posterProfileUrl": null,"description": "Delivery Hero is looking for a Data Analyst to support our regional marketing team...","descriptionHtml": "<p>Delivery Hero is looking for a Data Analyst...</p>","errorReason": null,"scrapedAt": "2026-07-25T09:14:19Z"},{"id": "4231987744","title": null,"companyName": null,"location": null,"publishedAt": null,"postedTime": null,"salary": null,"applicationsCount": null,"applicantsCountType": null,"applicantsText": null,"contractType": null,"experienceLevel": null,"workType": null,"sector": null,"jobUrl": "https://www.linkedin.com/jobs/view/4231987744","companyUrl": null,"companyId": null,"benefits": null,"posterFullName": null,"posterProfileUrl": null,"description": null,"descriptionHtml": null,"errorReason": "unparseable_page","scrapedAt": "2026-07-25T09:14:31Z"}]
The third row above is an accounting row, not a result: any job ID the Actor discovers but can't turn into a full posting (a blocked fetch, a timeout, or a page that never yields a title) is still written to the dataset with errorReason set and every other field null, but it is pushed without a charged event — it costs nothing. Only rows pushed with a parsed title are billed under the row_result event. If you're reconciling dataset size against your bill, filter on errorReason == null (or equivalently title != null) to isolate the charged rows.
A charged row is not guaranteed to be complete — a job is billed as soon as its title parses, and every other field is filled in from whatever LinkedIn's guest page actually shows for that posting. salary and posterFullName in particular are commonly null: LinkedIn's guest surfaces state no compensation figure on most postings, and only a minority of listings name an individual poster rather than just the company.
How can I use the data extracted with LinkedIn Jobs Scraper?
- 🧑💼 Recruiters and talent teams: pull competitor job postings by
companyInputand comparecontractType,experienceLevelandsalaryagainst your own openings to benchmark compensation and role framing before writing a requisition. BecausecompanyIdandcompanyUrlare captured alongside every row, you can group results by employer even when a company name is spelled inconsistently across postings. - 🤖 AI engineers and LLM developers: feed
descriptionstraight into a resume-matching or job-summarization agent — the JSON is ready to pass as grounding context without any HTML cleanup on your side, sincedescriptionHtmlanddescriptionare both already parsed. A retrieval agent can issue akeywords+locationquery through the Apify API, wait for the run to finish, and ground its answer in the returned postings instead of a stale training-data snapshot of the job market. - 📊 Market researchers: track
sector,workTypeandexperienceLeveldistributions across a keyword set over time to chart which industries and seniority bands are actively hiring in a givenlocation. BecausepublishedAtcarries LinkedIn's exact ISO posting date rather than a relative string, week-over-week and month-over-month comparisons don't require re-parsing "3 weeks ago" into a real date. - 🎯 Job seekers and career-site builders: aggregate
jobUrl,title,companyNameandapplicantsCountTypeacross several keyword searches into one feed, and use the applicant-precision field to prioritize postings that are genuinely early-stage (fewer_than) over ones already past 200 applicants (at_least) — a distinction a raw applicant-count number alone can't make.
🔁 How do you monitor new postings and applicant activity over time?
Job data goes stale fast — a listing with 25 applicants today can cross 200 within a week, and roles get filled and pulled without notice. Monitoring means running the same keywords + location (or companyInput) query on a schedule and diffing the results against the previous run by id.
Fields worth diffing between runs:
- New
idvalues not seen in the previous run — freshly posted roles matching your search applicationsCount/applicantsCountType— a jump fromfewer_thantoat_leaston the sameidsignals a listing is heating up- Missing
idvalues that were present last run — a strong signal the role was filled or pulled (LinkedIn doesn't publish a "closed" flag; absence from a fresh run is the closest available signal) salaryappearing where it was previouslynull— some postings add pay transparency after initial listing
A practical loop: schedule a daily run against a fixed keyword/location combination via an Apify schedule, store each run's dataset ID, and compare the new run's id set against the last one downstream (in a spreadsheet, database, or workflow tool) to alert on new postings or applicant-count changes. This Actor doesn't run the diff itself — it produces the clean, comparable JSON that makes the diff possible; the comparison logic lives in your own pipeline or automation tool.
Integrate LinkedIn Jobs Scraper and automate your workflow
LinkedIn Jobs Scraper works with any language or tool that can send an HTTP request — it runs on the Apify platform and is reachable through the Apify API and its client libraries.
REST API with Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("<YOUR_USERNAME>/linkedin-jobs-scraper").call(run_input={"keywords": "Data Analyst","location": "Berlin","maxJobs": 100,"publishedAt": "r604800",})for job in client.dataset(run["defaultDatasetId"]).iterate_items():if job.get("errorReason") is None:print(job["title"], job["companyName"], job["applicantsCountType"])
Swap <YOUR_API_TOKEN> for your Apify API token (Apify Console → Settings → Integrations) and <YOUR_USERNAME> for your Apify username or organization ID. The same call works from any language via the Apify REST API — query in, JSON out.
Scheduled monitoring and delivery
Apify Console's built-in Schedules feature can trigger this Actor on a cron interval (hourly, daily, or any custom cadence) with fixed input, without any code on your side. Combine a schedule with an Apify webhook on the ACTOR.RUN.SUCCEEDED event to push the new dataset — or just its items — to your own endpoint the moment a run finishes, instead of polling for results.
No-code delivery and exports
If you'd rather not write any integration code, every run's dataset can be downloaded directly from the Apify Console as JSON, CSV, or Excel, or connected through Apify's built-in integrations to push results into Google Sheets, Make, Zapier, or n8n without touching the API. This is the same dataset the Python example above reads from client.dataset(run["defaultDatasetId"]) — the no-code and code paths return identical rows.
Is it legal to scrape LinkedIn job postings?
Yes — scraping publicly accessible LinkedIn job listings is legal in the United States; LinkedIn Jobs Scraper reads the same guest job pages any visitor can open without signing in, and never accesses data behind a login. The leading precedent is hiQ Labs, Inc. v. LinkedIn Corp., 9th Circuit, 2019 (reaffirmed on remand, 2022), which held that scraping data LinkedIn makes publicly viewable does not violate the Computer Fraud and Abuse Act. Job postings and company data are business records, not personal data of the searcher, so this falls under a terms-of-service and database-rights framing rather than GDPR/CCPA — though a small amount of incidental personal data (a job poster's name and LinkedIn profile URL) can appear in posterFullName and posterProfileUrl when LinkedIn shows one, and should be handled accordingly if you store it. Scraping for a one-off research pull and scraping to continuously mirror LinkedIn's job board carry different risk profiles — the latter looks more like the bulk, systematic collection LinkedIn's ToS specifically targets. Consult your legal team for commercial use cases involving bulk data storage or redistribution.
❓ Frequently asked questions
What happens if my search returns zero jobs?
The run finishes successfully with an empty dataset — it does not fail or retry indefinitely. The Actor logs an error line ("Could not extract any job IDs for this search") and exits once it has confirmed the search truly returns nothing. Since only parsed job rows trigger the row_result charge, a zero-result run costs nothing beyond the Actor's own compute time. Try broadening keywords, clearing location, or removing filters (workType, contractType, experienceLevel, publishedAt) one at a time to isolate which one is over-narrowing the search.
Does location or geoId change which jobs I get?
Yes — location is a free-text string sent to LinkedIn's own job search, and geoId is an optional numeric LinkedIn location code sent alongside it. Setting a matching geoId (from the picklist or copied from a LinkedIn search URL) makes results more consistent with the location string; leaving geoId empty lets LinkedIn infer the location from the text alone.
Does sortOrder actually change the order of results?
No. sortOrder is accepted for backward compatibility, but LinkedIn's public guest job endpoint ignores sorting — the Actor's own measurement found identical result sets for Default, Most relevant, and Most recent. Use publishedAt to restrict to recent postings instead; that filter is genuinely applied by LinkedIn.
How does LinkedIn Jobs Scraper handle LinkedIn's anti-bot measures?
It retries failed requests with exponential backoff, and treats an HTTP 999 response as a throttle rather than a block — LinkedIn's guest endpoint returns 999 when it wants a slower request rate, and the Actor backs off and retries rather than failing the job immediately. If LinkedIn starts serving the same page repeatedly (a session pin) or blocking outright, the Actor clears its cookie session and, if Apify Proxy is enabled, retries the collection through a fresh proxy IP. Apify Proxy is off by default and only recommended if you see empty pages or persistent blocks.
Does LinkedIn Jobs Scraper report applicant counts as exact numbers?
Not always, and it says so. applicationsCount carries the number, and applicantsCountType tells you whether it's exact ("119 applicants"), at_least ("Over 200 applicants"), or fewer_than ("Be among the first 25 applicants"). The raw phrase ships alongside in applicantsText. Both fields are null when a listing shows no applicant bullet at all.
How many jobs does LinkedIn Jobs Scraper return per search?
Up to maxJobs (1–1,000, default 20) — but the real ceiling for a single keyword-plus-location combination is set by LinkedIn itself: its guest search endpoint stops paginating at start offset 1,000, which caps any one search at roughly 1,000 results regardless of maxJobs. To cover more than that, split the search across multiple keywords, locations, or companies and run them separately.
How do I monitor new postings for a role over time?
Run the same keyword/location or company search on an Apify schedule, and compare each run's set of id values against the previous run downstream. New IDs are newly posted roles; IDs that disappear were likely filled or pulled; a shift in applicantsCountType on the same ID shows a listing gaining traction. See the monitoring section above for the full pattern.
Does LinkedIn Jobs Scraper work with Claude, ChatGPT, and AI agent frameworks?
Yes, as an HTTP endpoint any agent framework can call. It has no dedicated MCP server, but any agent that can issue an HTTP request (via the Apify API or apify-client) can trigger a run, poll or await it, and pass the resulting JSON — job titles, descriptions, salaries — into the model as grounded context before it answers.
How does LinkedIn Jobs Scraper compare to other LinkedIn job scrapers?
Observed on the Apify Store, 2026-07-25:
| Feature | curious_coder/linkedin-jobs-scraper | cheap_scraper/linkedin-job-scraper | bebity/linkedin-jobs-scraper | LinkedIn Jobs Scraper (this Actor) |
|---|---|---|---|---|
| Query input | Pasted LinkedIn search URL | Start URLs or keyword + location | Keyword + location form | Keywords, location, company list, and structured filters |
| Applicant count precision | Single applicantsCount string, no typing documented | Raw applicationsCount string, no typing documented | Not documented | applicationsCount + applicantsCountType (exact / at_least / fewer_than) |
| Salary field | salaryInfo array, extraction method not documented | salaryInfo array, extraction method not documented | Not documented | salary, context-anchored to compensation wording and excluded from funding/revenue false positives |
| Post-fetch filtering billed before or after evaluation | Not applicable (no dynamic filters) | Documented as fetched and billed before dynamic filters run | Not documented | No post-fetch filters; only successfully parsed jobs are billed |
| README field-level schema | Documented | Documented | Not documented | Documented |
This Actor returns a fixed set of typed fields including the applicantsCountType precision label, and only bills for a job it successfully parsed — an unparseable job never reaches the row_result charge.
Can I use LinkedIn Jobs Scraper without managing proxies or LinkedIn credentials?
Yes. No LinkedIn account, password, or session cookie is ever requested — the Actor only reads LinkedIn's logged-out guest job pages. Apify Proxy is entirely optional and off by default; you only need to turn it on, and pick proxy groups, if your searches hit blocks or empty pages, which the Actor's own proxy ladder (datacenter, then residential) then handles automatically.
💬 Your feedback
Found a bug, a field that's coming back empty when it shouldn't, or a LinkedIn selector that broke? Let us know through the Issues tab on this Actor's Apify Store page, or message Scrapier support directly from the Actor's page — reports like these are what keep the field extraction current as LinkedIn changes its guest markup.