# LinkedIn Jobs Scraper - No Cookies, Pay Per Result (`thirdwatch/linkedin-jobs-scraper`) Actor

Scrape LinkedIn public job listings worldwide. Extract title, company, location, salary, description, skills, experience level, job type. Fast and full scrape modes. 30+ countries, 100+ cities. No login needed.

- **URL**: https://apify.com/thirdwatch/linkedin-jobs-scraper.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (community)
- **Categories:** Jobs, Social media, Other
- **Features:** Limited permissions
- **Stats:** 183 total users, 4 monthly users, 48.6% runs succeeded, 5 bookmarks
- **User rating**: 3.75 out of 5 stars

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## LinkedIn Jobs Scraper

> **Thirdwatch portfolio:** 8,800+ users across 140+ public Actors, 2M+ records delivered, >95% run success. [Explore all Thirdwatch Actors](https://apify.com/thirdwatch).

Scrape public LinkedIn job listings for hiring-intent data: titles, companies, locations, salary fields, skills, descriptions, applicant counts, job type, experience level, and apply links. Use it for job boards, recruiting intelligence, labor-market research, and B2B buying-signal workflows without a LinkedIn account or API key.

### Value proposition

Job postings are one of the clearest public signals that a company is growing, changing tools, opening a new market, or investing in a function. This actor turns LinkedIn Jobs searches into structured JSON so you can track which companies are hiring, what skills they ask for, where they are expanding, and how roles are changing over time.

Use it when you need:

- Fresh public LinkedIn job data for a role and location
- Hiring velocity by company or market
- Parsed salary fields when LinkedIn exposes salary data
- Skills and descriptions for buying-signal pipelines
- Apply URLs for job-board or recruiting workflows

### What's new

- **No-login public job collection**: uses public LinkedIn job listing data without cookies or a LinkedIn account.
- **Multiple scrape modes**: choose `standard`, `full`, or `fast` depending on whether you need descriptions and enrichment fields.
- **Structured salary parsing**: returns raw salary text plus parsed min, max, currency, and pay period when salary is available.
- **Country, date, job type, and experience filters**: narrow searches before collecting results.

### What data you get

| Field | Description |
| --- | --- |
| `title` | Job title |
| `company_name` | Hiring company |
| `location` | Job location |
| `salary_raw` | Salary as displayed by LinkedIn when available |
| `salary_min` | Parsed minimum salary when available |
| `salary_max` | Parsed maximum salary when available |
| `salary_currency` | Parsed currency code when available |
| `salary_period` | Pay period such as yearly, monthly, or hourly when available |
| `experience_level` | Experience level shown by LinkedIn |
| `job_type` | Full-time, part-time, contract, internship, or related type |
| `industry` | Company industry when available |
| `skills` | Required or inferred skills in Standard and Full modes |
| `description` | Full job description in Standard and Full modes |
| `applicant_count` | Applicant count text when available |
| `is_easy_apply` | Whether LinkedIn Easy Apply appears available |
| `posted_at` | Posting date or parsed posting date when available |
| `apply_url` | LinkedIn job URL or apply link |

### Quick-start input examples

#### 1. Search one role in one location

```json
{
  "queries": ["software engineer"],
  "location": "San Francisco",
  "country": "United States",
  "maxResultsPerQuery": 25,
  "scrapeMode": "standard"
}
```

#### 2. Track hiring at a target company

```json
{
  "queries": ["sales", "customer success", "solutions engineer"],
  "companyName": "Snowflake",
  "country": "us",
  "datePosted": "pastMonth",
  "maxResultsPerQuery": 50,
  "scrapeMode": "standard"
}
```

#### 3. Fast search-card collection

```json
{
  "queries": ["data analyst remote", "analytics engineer remote"],
  "maxResultsPerQuery": 100,
  "maxPages": 4,
  "scrapeMode": "fast"
}
```

### Input parameters

| Parameter | Required | Default | Description |
| --- | --- | --- | --- |
| `queries` | Yes | - | Job search keywords. Each query runs a separate LinkedIn search. LinkedIn links also work: a job search link (`linkedin.com/jobs/search/?keywords=...`) uses its keywords, location and filters; a single job link (`linkedin.com/jobs/view/...`) returns that job; a company page link (`linkedin.com/company/...`) returns that company's open jobs. Other links, such as profiles or posts, are skipped. |
| `location` | No | - | City, region, or country text such as `London`, `Bangalore`, or `India`. LinkedIn's public search has no remote filter, so `Remote` (or `Remote, United States`) adds "remote" to the keywords and searches the rest as the location. |
| `country` | No | - | Country filter such as United States, United Kingdom, India, Canada, Australia, Germany, France, Netherlands, Singapore, UAE, Japan, Brazil, Ireland, Sweden, Switzerland, Spain, Italy, Israel, South Korea, or Mexico. |
| `companyName` | No | - | Limit results to one company name. |
| `maxResultsPerQuery` | No | `5` | Maximum jobs to return per query. Start small for previews, then increase for larger runs. |
| `maxPages` | No | `1` | Number of search result pages per query. Public LinkedIn search usually exposes about 25 jobs per page. |
| `scrapeMode` | No | `standard` | `standard` for most use cases, `full` for alternate extraction, or `fast` for search-card fields only. |
| `datePosted` | No | Any time | Filter by Any time, Past 24 hours, Past week, or Past month. |
| `jobType` | No | - | Filter by Full-time, Part-time, Contract, Temporary, or Internship. |
| `experienceLevel` | No | - | Filter by Internship, Entry level, Associate, Mid-Senior level, Director, or Executive. |
| `proxyConfiguration` | No | Apify default | Proxy settings. Leave default unless you have a specific Apify proxy setup. |

### Scrape modes

| Mode | Best for | Notes |
| --- | --- | --- |
| `standard` | Most jobs, salary, skills, descriptions, and apply links | Recommended default. |
| `full` | Alternative extraction if Standard returns incomplete data | Useful as a fallback for some searches. |
| `fast` | Bulk discovery when descriptions are not needed | Reads search-card data only, so some enriched fields may be empty. |

### Sample output snippet

```json
{
  "title": "Software Engineer",
  "company_name": "Google",
  "location": "San Francisco, CA",
  "salary_raw": "$150,000 - $200,000/yr",
  "salary_min": 150000,
  "salary_max": 200000,
  "salary_currency": "USD",
  "salary_period": "yearly",
  "experience_level": "Mid-Senior level",
  "job_type": "Full-time",
  "industry": "Technology, Information and Internet",
  "skills": ["Python", "Java", "AWS"],
  "description": "We are looking for a talented Software Engineer to join...",
  "applicant_count": "200+ applicants",
  "is_easy_apply": true,
  "posted_at": "2026-04-05",
  "apply_url": "https://www.linkedin.com/jobs/view/123456/"
}
```

### Use cases

- **B2B buying signals**: identify accounts hiring for product-relevant skills such as Salesforce, Snowflake, Kubernetes, SAP, or outbound sales roles.
- **ABM and RevOps**: monitor hiring velocity at named accounts and trigger campaigns when teams expand.
- **Recruiting intelligence**: track open roles, salary ranges, and locations across competitors or target employers.
- **Job boards**: collect public LinkedIn job data and apply links for search, alerts, or aggregation.
- **Investor and market research**: use job postings as a leading indicator of growth, contraction, geographic expansion, or new product focus.
- **Salary analytics**: compare public salary ranges by role, level, geography, and company when salary is available.

### Limitations

- Salary fields are only populated when LinkedIn or the employer exposes salary data.
- `skills` and `description` require Standard or Full mode. Fast mode reads search-card fields only.
- Easy Apply jobs may point back to LinkedIn rather than an external employer application page.
- Public guest search can be broader than logged-in LinkedIn search. Use specific titles and filters for better precision.
- LinkedIn public pagination has practical per-query limits. Split very large pulls by location, date, job type, or experience level.
- Very high-volume runs can encounter rate limits. Split large workloads across multiple runs if needed.

### FAQ

#### Do I need a LinkedIn account?

No. The actor accesses publicly visible LinkedIn job listing data and does not require login credentials.

#### Which scrape mode should I use?

Use `standard` unless you specifically need the fastest search-card-only collection. Use `full` as an alternate extraction path if a Standard run returns incomplete data for your query.

#### Why are some salary fields empty?

LinkedIn only shows salary when the employer or source listing includes it. The actor parses salary when it is available.

#### Can I filter by company?

Yes. Use `companyName` to limit results to a target company, then combine it with `datePosted`, `jobType`, or `experienceLevel` for tighter monitoring.

#### Can I use this as a LinkedIn Jobs API alternative?

Yes, for public job listings. LinkedIn does not provide an open public job-search API for this use case, so this actor returns structured public listing data through Apify.

### Support and custom builds

Need a custom hiring-intent workflow, company monitor, skills classifier, job-board feed, or multi-source jobs dataset? Contact Thirdwatch through Apify or visit [thirdwatch.dev](https://thirdwatch.dev) for custom builds.

Pairs well with [Google Jobs Scraper](https://apify.com/thirdwatch/google-jobs-scraper?fpr=9m2cd6), [Indeed Scraper](https://apify.com/thirdwatch/indeed-jobs-scraper?fpr=9m2cd6), and [Naukri Scraper](https://apify.com/thirdwatch/naukri-jobs-scraper?fpr=9m2cd6) for multi-source hiring datasets.

### Use cases and recipes

Step-by-step guides on [thirdwatch.dev/blog](https://thirdwatch.dev/blog):

- [Build a LinkedIn Jobs Aggregator with Apify (2026 Guide)](https://thirdwatch.dev/blog/build-linkedin-jobs-aggregator-with-apify)
- [Filter LinkedIn Jobs by Skill and Location (2026 Guide)](https://thirdwatch.dev/blog/filter-linkedin-jobs-by-skill-and-location)
- [Scrape LinkedIn Jobs Without Login at Scale (2026 Guide)](https://thirdwatch.dev/blog/scrape-linkedin-jobs-without-login)
- [Track LinkedIn Hiring Velocity by Company (2026)](https://thirdwatch.dev/blog/track-linkedin-hiring-velocity-by-company)

Last verified: 2026-05

# Actor input Schema

## `queries` (type: `array`):

Job search keywords (e.g., 'software engineer', 'data scientist', 'product manager'). Each query produces a separate LinkedIn search. You can also paste LinkedIn links: a job search link (linkedin.com/jobs/search/?keywords=...) uses its keywords, location and filters; a single job link (linkedin.com/jobs/view/...) returns that job; a company page link (linkedin.com/company/...) returns that company's open jobs.

## `location` (type: `string`):

Location to search in. Use a city name (e.g., 'San Francisco', 'London', 'Bangalore'), a country name (e.g., 'United States', 'India'), or leave empty for worldwide results. LinkedIn's public search has no remote filter: 'Remote' (or 'Remote, United States') adds 'remote' to the keywords and searches the rest as the location.

## `country` (type: `string`):

Filter by country. Select a country or leave empty to use the location field instead.

## `companyName` (type: `string`):

Limit results to a specific company (e.g., 'Google', 'Netflix').

## `maxResultsPerQuery` (type: `integer`):

Maximum job listings to extract per query. This is the main volume lever — the actor auto-paginates until it reaches this number, so you do NOT need to raise maxPages. Start small (5-10) to preview cost; raise for larger runs. LinkedIn's public guest API caps at ~1000 results per query — for broader searches, split by location, role, or job_type instead of asking for more.

## `maxPages` (type: `integer`):

Optional minimum number of search result pages to scrape per query (10 jobs/page). Leave at 1 in almost all cases — maxResultsPerQuery already drives pagination automatically. Only raise this if you want to force more pages than maxResultsPerQuery would imply. Public ceiling is ~100 pages (~1000 jobs) per query.

## `scrapeMode` (type: `string`):

Standard (recommended): Fastest and most affordable, gets all fields including descriptions. Full: Alternative extraction method with fallback. Fast: Search cards only, no descriptions.

## `datePosted` (type: `string`):

Filter by when jobs were posted.

## `jobType` (type: `string`):

Filter by employment type.

## `experienceLevel` (type: `string`):

Filter by experience level.

## `proxyConfiguration` (type: `object`):

Proxy settings. Leave default for best results.

## Actor input object example

```json
{
  "queries": [
    "software engineer"
  ],
  "location": "",
  "country": "",
  "companyName": "",
  "maxResultsPerQuery": 5,
  "maxPages": 1,
  "scrapeMode": "standard",
  "datePosted": "",
  "jobType": "",
  "experienceLevel": "",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "software engineer"
    ],
    "location": "",
    "maxResultsPerQuery": 5,
    "maxPages": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/linkedin-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["software engineer"],
    "location": "",
    "maxResultsPerQuery": 5,
    "maxPages": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("thirdwatch/linkedin-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "software engineer"
  ],
  "location": "",
  "maxResultsPerQuery": 5,
  "maxPages": 1
}' |
apify call thirdwatch/linkedin-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thirdwatch/linkedin-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eF0s4U6RIMuwZzfs0/builds/KLfmZ0vSPLnMVXreY/openapi.json
