Linkedin Jobs Scraper avatar

Linkedin Jobs Scraper

Pricing

$24.99/month + usage

Go to Apify Store
Linkedin Jobs Scraper

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

Scrapier

Maintained by Community

Actor stats

0

Bookmarked

66

Total users

4

Monthly active users

11 days ago

Last modified

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 geoId parameter 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 TypeExtracted FieldsPrimary Use Case
Job posting coreid, title, companyName, location, jobUrl, companyUrl, companyIdBuilding a searchable jobs dataset or feed
TimingpublishedAt (exact ISO date), postedTime (LinkedIn's relative string), scrapedAtTracking when a role went live and when your data was collected
Applicant signalapplicationsCount, applicantsCountType, applicantsTextScoring competitiveness or freshness without misreading a bucketed count
ClassificationcontractType, experienceLevel, workType, sectorFiltering a dataset by employment type, seniority or industry
Compensation and culturesalary, benefitsComparing pay signals and benefit mentions across postings
Descriptiondescription, descriptionHtmlFeeding a job description to an LLM, or rendering it in a UI
PosterposterFullName, posterProfileUrlIdentifying the recruiter or hiring manager behind a listing, when LinkedIn shows one
Run diagnosticserrorReasonAuditing 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?

  1. Open LinkedIn Jobs Scraper on the Apify Store and click Try for free (or Run) to open the input form in Apify Console.
  2. Enter your query — fill keywords (default Software Engineer) and location (default United States) for a plain search, or add one or more entries to companyInput to scope the search to specific employers.
  3. Set the real query controls the schema exposes: publishedAt for date-posted, workType for on-site/remote/hybrid, contractType for employment type, experienceLevel for seniority, and geoId if you want LinkedIn's own numeric location code sent alongside location.
  4. Set maxJobs (1–1,000, default 20) and start the run.
  5. 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.

ParameterRequiredTypeDefaultConstraints
companyInputNoarray of strings["Google"] (prefill)stringList editor. Each entry is a company name, LinkedIn company URL, or numeric company ID
keywordsNostring"Software Engineer"Free text; matched against job titles and descriptions
locationNostring"United States"Any location string LinkedIn's job search understands
maxJobsNointeger20minimum: 1, maximum: 1000
sortOrderNostring""Enum: "" (Default), "relevance" (Most relevant — ignored), "date" (Most recent — ignored). Kept for backward compatibility only
publishedAtNostring""Enum: "" (Any time), "r86400" (Past 24 hours), "r604800" (Past week), "r2592000" (Past month)
workTypeNostring""Enum: "" (Any), "1" (On-site), "2" (Remote), "3" (Hybrid)
contractTypeNostring""Enum: "" (Any), "F" (Full-time), "P" (Part-time), "C" (Contract), "T" (Temporary), "I" (Internship), "V" (Volunteer)
experienceLevelNostring""Enum: "" (Any), "1" (Internship), "2" (Entry level), "3" (Associate), "4" (Mid-Senior level), "5" (Director), "6" (Executive)
geoIdNostring""select editor with suggested numeric values; any digit string is accepted (non-digit values are ignored and treated as empty)
proxyConfigurationNoobject{"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:

  • sortOrder is 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; use publishedAt if you need recent postings, since that filter is genuinely honored by LinkedIn.
  • companyInput entries 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_result only 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 companyInput and compare contractType, experienceLevel and salary against your own openings to benchmark compensation and role framing before writing a requisition. Because companyId and companyUrl are 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 description straight into a resume-matching or job-summarization agent — the JSON is ready to pass as grounding context without any HTML cleanup on your side, since descriptionHtml and description are both already parsed. A retrieval agent can issue a keywords + location query 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, workType and experienceLevel distributions across a keyword set over time to chart which industries and seniority bands are actively hiring in a given location. Because publishedAt carries 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, companyName and applicantsCountType across 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 id values not seen in the previous run — freshly posted roles matching your search
  • applicationsCount / applicantsCountType — a jump from fewer_than to at_least on the same id signals a listing is heating up
  • Missing id values 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)
  • salary appearing where it was previously null — 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 ApifyClient
client = 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.

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.

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:

Featurecurious_coder/linkedin-jobs-scrapercheap_scraper/linkedin-job-scraperbebity/linkedin-jobs-scraperLinkedIn Jobs Scraper (this Actor)
Query inputPasted LinkedIn search URLStart URLs or keyword + locationKeyword + location formKeywords, location, company list, and structured filters
Applicant count precisionSingle applicantsCount string, no typing documentedRaw applicationsCount string, no typing documentedNot documentedapplicationsCount + applicantsCountType (exact / at_least / fewer_than)
Salary fieldsalaryInfo array, extraction method not documentedsalaryInfo array, extraction method not documentedNot documentedsalary, context-anchored to compensation wording and excluded from funding/revenue false positives
Post-fetch filtering billed before or after evaluationNot applicable (no dynamic filters)Documented as fetched and billed before dynamic filters runNot documentedNo post-fetch filters; only successfully parsed jobs are billed
README field-level schemaDocumentedDocumentedNot documentedDocumented

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.