# LinkedIn Jobs Scraper: Full Descriptions, No Login (`kyungminlee/linkedin-jobs-scraper`) Actor

Search public LinkedIn jobs by keyword and location with full descriptions, no cookies or login: 25 jobs in about 30 s. Fields: title, company, location, workplace type, seniority, posted date, applicants, description, apply URL; date/remote/experience filters. JSON/CSV, API, daily alerts.

- **URL**: https://apify.com/kyungminlee/linkedin-jobs-scraper.md
- **Developed by:** [Kyungmin Lee](https://apify.com/kyungminlee) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does LinkedIn Jobs Scraper do?

**LinkedIn Jobs Scraper** gives you public LinkedIn job postings with **full descriptions** for any keyword and location, using LinkedIn's guest search — no account, cookies or browser, so nothing of yours can be flagged. Filter by date posted, workplace type (remote/hybrid/on-site), job type, experience level and Easy Apply; 25 jobs with details take about 30 seconds.

Each job is one record: `jobId`, `title`, `company`, `companyUrl`, `location`, `workplaceType`, `seniorityLevel`, `employmentType`, `postedAt`, `applicantCount`, `description` (text, HTML optional), `salary` when shown, `applyUrl` and `jobUrl`. Export JSON/CSV, call the API from your ATS or dashboard, or schedule daily searches and push new postings to Slack, Sheets or email.

### Why use LinkedIn Jobs Scraper?

- Monitor hiring demand for technologies, roles, or markets.
- Build job alerts and internal recruiting dashboards.
- Research which companies are hiring in a city or country.
- Compare remote, hybrid, and on-site opportunities.
- Analyze employment types, experience levels, industries, and posting activity.
- Feed current public job data into spreadsheets, databases, or automated workflows.

It uses fast HTTP requests instead of a headless browser, keeping compute overhead low. Duplicate job IDs are removed within each run. Failed detail pages are skipped and are not charged as result events.

### How to scrape LinkedIn jobs

1. Open the Actor and select **Try for free**.
2. Enter a keyword such as `software engineer`.
3. Enter a location such as `United States`, `Berlin`, or `South Korea`.
4. Set the maximum number of jobs and any optional filters.
5. Click **Start**.
6. Download the dataset or connect it to another Apify integration.

No LinkedIn credentials are requested or accepted.

### Input

The Input tab provides a form for all options. A minimal request looks like this:

```json
{
  "keywords": "Python developer",
  "location": "United States",
  "maxItems": 25,
  "datePosted": "pastWeek",
  "workplaceTypes": ["remote"],
  "includeDescription": true
}
```

Available filters include date posted, job type, experience level, workplace type, Easy Apply only, and relevance or newest-first sorting. Set `includeDescription` to `false` for faster search-card-only collection. Set `includeDescriptionHtml` to `true` when you need the public description markup as well as plain text.

The optional `proxyConfiguration` is off by default because the public guest endpoints normally work from Apify data-center IPs. Enable an Apify or custom proxy for a larger run if LinkedIn begins rate-limiting requests.

### Output

Each charged dataset item represents one successfully collected job posting:

```json
{
  "jobId": "4465379983",
  "title": "Senior Software Engineer - Python",
  "companyName": "Venmo",
  "location": "Austin, TX",
  "postedDate": "2026-09-10",
  "applicantCount": 111,
  "seniorityLevel": "Not Applicable",
  "employmentType": "Full-time",
  "jobFunction": "Engineering",
  "industries": "Financial Services",
  "descriptionText": "The Company ...",
  "url": "https://www.linkedin.com/jobs/view/...",
  "scrapedAt": "2026-09-13T09:30:00+00:00"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data fields

| Field | Description |
|---|---|
| `jobId` | Stable numeric LinkedIn job posting ID |
| `title` | Public job title |
| `companyName`, `companyUrl` | Hiring company name and public company URL |
| `location` | Location displayed on the search card |
| `postedDate`, `postedTime` | Machine-readable date and relative posting time when available |
| `descriptionText`, `descriptionHtml` | Full public description as text and optional source HTML |
| `applicantCount`, `applicantText` | Public applicant indicator when displayed |
| `seniorityLevel`, `employmentType` | LinkedIn job criteria |
| `jobFunction`, `industries` | Function and industry labels |
| `salary` | Salary label when displayed on the public search card |
| `benefits` | Search-card badges, for example “Be an early applicant” |
| `companyLogoUrl` | Public company logo image URL |
| `url` | Direct public LinkedIn job URL |
| `searchKeywords`, `searchLocation` | Search context that produced the item |
| `scrapedAt` | UTC collection timestamp |

### Pricing: how much does it cost to scrape LinkedIn jobs?

The Actor uses pay-per-event pricing at **$0.0005 per successfully collected job**: $0.50 per 1,000 jobs. Apify platform compute and proxy costs may also apply according to your plan. Search requests, duplicate IDs, empty pages, and failed detail pages are not charged as job events.

Set a maximum Actor charge in the run options for a hard spending cap. The Actor checks that limit before collecting more results and stops when the available event allowance is exhausted.

### Tips and advanced options

- Start with 25 jobs to confirm that your keyword and location are precise.
- Use `past24Hours` or `pastWeek` for recurring job-monitoring schedules.
- Combine the remote workplace filter with a country location because LinkedIn interprets location context as well as workplace type.
- Disable full descriptions when you only need title, company, location, date, URL, and badges. This reduces requests and is faster.
- Very narrow filters may legitimately return fewer jobs than `maxItems`.
- If a large direct-IP run becomes rate-limited, retry later or enable proxy rotation.

### FAQ, disclaimers, and support

#### Does this Actor require a LinkedIn account?

No. It only accesses pages LinkedIn exposes to unauthenticated visitors. It does not accept or store credentials and does not scrape member profiles.

#### Why are some fields empty?

LinkedIn and employers do not publish every field for every vacancy. Applicant counts, salary labels, dates, and criteria can be absent. Job postings can also expire between the search and detail requests.

#### Is scraping LinkedIn legal?

Web-scraping rules vary by jurisdiction and use case. You are responsible for your inputs, data use, and compliance with applicable law and website terms. Avoid personal-data enrichment, spam, discriminatory screening, or excessive request volumes.

#### Is this an official LinkedIn product?

No. This is an unofficial independent Actor with no affiliation with LinkedIn Corporation. LinkedIn is a trademark of its respective owner.

For bugs, selector changes, or feature requests, use the Actor’s **Issues** tab. Custom job-data workflows and output fields can also be discussed there.

# Actor input Schema

## `keywords` (type: `string`):

Job title, skill, or other keywords to search for, such as `software engineer` or `Python developer`.

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

City, region, or country used by LinkedIn search, such as `New York, NY`, `Germany`, or `South Korea`.

## `maxItems` (type: `integer`):

Maximum number of unique job postings to save. The pay-per-event spending limit can reduce this number.

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

Only include jobs posted within the selected time range.

## `sortBy` (type: `string`):

Order LinkedIn search results by relevance or recency.

## `jobTypes` (type: `array`):

Optional employment-type filters. Leave empty to include every job type.

## `experienceLevels` (type: `array`):

Optional seniority filters. Leave empty to include all experience levels.

## `workplaceTypes` (type: `array`):

Optional workplace filters for on-site, remote, and hybrid jobs.

## `easyApplyOnly` (type: `boolean`):

Return only postings marked with LinkedIn Easy Apply.

## `includeDescription` (type: `boolean`):

Fetch each public job page to include the description, applicant count, seniority, employment type, job function, and industry.

## `includeDescriptionHtml` (type: `boolean`):

Include the source description HTML alongside plain text. This only applies when full descriptions are enabled.

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

Optional proxy settings. Public guest pages normally work from Apify data-center IPs; enable a proxy if LinkedIn rate-limits a larger run.

## Actor input object example

```json
{
  "keywords": "software engineer",
  "location": "United States",
  "maxItems": 25,
  "datePosted": "anyTime",
  "sortBy": "relevance",
  "easyApplyOnly": false,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "keywords": "software engineer",
    "location": "United States",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kyungminlee/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 = {
    "keywords": "software engineer",
    "location": "United States",
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("kyungminlee/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 '{
  "keywords": "software engineer",
  "location": "United States",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call kyungminlee/linkedin-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kyungminlee/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/4VQ4fIn8IryTwddHt/builds/cFS5puCUBSlzh3YZy/openapi.json
