# LinkedIn Jobs Scraper: job search, descriptions, no login (`pikoulas/linkedin-jobs`) Actor

Scrape LinkedIn job postings by keyword and location or from any LinkedIn job search URL: title, company, location, posted date, salary, applicants, seniority, employment type, industries and the full description. Up to 1,000 jobs per search, no account or cookies.

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

## Pricing

from $0.50 / 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.

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

Scrape job postings from LinkedIn, without an account or cookies:

- **Search:** jobs for keywords in any location, up to the 1,000 LinkedIn shows per search.
- **Search URLs:** paste a search from linkedin.com/jobs, and all the filters you set there come
  with it.
- **Job URLs:** any job by its link (`linkedin.com/jobs/view/...`) or ID.
- **Filters:** posted in the last day, week or month, remote, hybrid or on-site, job type,
  experience level, Easy Apply only, distance, and newest first.

Every job comes with its title, company and company page, logo, location, posting date, salary
where LinkedIn shows one, and badges like "Actively Hiring". With details on, the default, it
also comes with the full description as text and HTML, the number of applicants, seniority
level, employment type and industries.

It needs no browser and no login. Search cards come fast, 500 jobs a minute; with details
LinkedIn allows about one job a second from one address, so 450 jobs with descriptions took 11
minutes. It costs **$0.50 per 1,000 jobs**, details included.

### What people use it for

- **Job market research:** who is hiring for a role, where, how senior, and how many apply.
- **Lead generation:** companies hiring right now, from a search for the roles you sell to.
- **Job boards and alerts:** the jobs of the last 24 hours for any search, with the full description.
- **AI and LLM data:** full job descriptions with seniority, function and industry labels.

### How to scrape LinkedIn jobs

1. Click **Try for free**; Apify's free plan covers a first run.
2. Enter **Search terms** and a **Location**, or **LinkedIn URLs** of job searches, and how many jobs you want.
3. Click **Start**, then download the results as JSON, CSV, Excel or HTML, or read them through
   the API.

An input with more options:

```json
{
  "searchTerms": ["python developer", "product manager"],
  "location": "United States",
  "maxJobsPerSearch": 200,
  "postedWithin": "week",
  "workplace": ["remote"],
  "sortBy": "date",
  "urls": ["https://www.linkedin.com/jobs/search/?keywords=nurse&location=London&f_JT=F"]
}
```

Each search term runs with the filters and location given; a search URL keeps its own. Turn off
`includeDetails` for the search cards only, which is about 20 times faster.

### Output

```json
{
  "type": "job",
  "jobId": "4470276303",
  "title": "Sr. Technical Product Manager-Xumo Play",
  "url": "https://www.linkedin.com/jobs/view/4470276303",
  "company": "Comcast",
  "companyUrl": "https://www.linkedin.com/company/comcast",
  "location": "Philadelphia, PA",
  "postedAt": "2026-09-22",
  "salary": null,
  "benefits": "Actively Hiring",
  "searchQuery": "product manager",
  "postedAgo": "5 days ago",
  "applicants": "27 applicants",
  "applicantCount": 27,
  "seniority": "Not Applicable",
  "employmentType": "Full-time",
  "industries": "IT Services and IT Consulting, Technology, Information and Internet, and Telecommunications",
  "description": "Xumo, a joint venture between Comcast and Charter Communications, was formed to develop and offer a next-generation streaming platform for the entire entertainment industry. ..."
}
```

`applicantCount` is set only when LinkedIn gives an exact number ("62 applicants"), not for
"Over 200 applicants" or "Be among the first 25 applicants".

### Use it as an API

One call runs it and returns the results as JSON (for runs under 5 minutes; longer ones start a
run and read its dataset). Apify's Python and JavaScript clients, and its Make, Zapier and n8n
integrations, work the same way.

```bash
curl -X POST "https://api.apify.com/v2/acts/pikoulas~linkedin-jobs/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms": ["data engineer"], "location": "Germany", "maxJobsPerSearch": 10}'
```

AI agents can call it as a tool through Apify's MCP server: `https://mcp.apify.com?tools=pikoulas/linkedin-jobs`.

### How much does it cost to scrape LinkedIn jobs?

You pay **$0.0005 per job**, which is $0.50 per 1,000 jobs, with or without details. Runs that go
through Apify's residential proxy also pay its traffic, $0.0012 per 100 KB: a job with details is
about 9 KB, so about $0.11 per 1,000 jobs. There are no monthly fees.

### Good to know

- LinkedIn shows at most 1,000 jobs per search. For more, split a search by location, job type
  or date.
- A search can list the same job under several terms; each job is given once per run.

### FAQ

#### Is it legal to scrape LinkedIn?

It collects only what LinkedIn shows publicly, without logging in. Scraping public data is
generally legal, but personal data is protected by laws such as the GDPR and the CCPA, and
LinkedIn's terms may limit how you use what you collect. If you're unsure, ask a lawyer;
Apify's [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/) is a good start.

#### Something missing or not working?

Open an issue on the **Issues** tab with the input you used, or ask there for a field you need.

# Actor input Schema

## `searchTerms` (type: `array`):

Job titles, skills or companies, searched as on linkedin.com/jobs. Each is its own search, with the filters below.

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

A country, region or city, as you'd type it on LinkedIn (United States, Berlin, Remote). Empty for worldwide.

## `urls` (type: `array`):

Job search URLs copied from linkedin.com/jobs/search, with any filters set there, and job URLs (linkedin.com/jobs/view/...).

## `maxJobsPerSearch` (type: `integer`):

How many jobs to take from each search term or search URL. LinkedIn shows at most 1,000 per search.

## `includeDetails` (type: `boolean`):

The full description, applicants, seniority, employment type and industries. One more request per job, so slower; off gives the search cards only.

## `postedWithin` (type: `string`):

Only jobs posted in the last day, week or month.

## `workplace` (type: `array`):

On-site, remote or hybrid. Empty for all.

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

Empty for all.

## `experience` (type: `array`):

Empty for all.

## `easyApply` (type: `boolean`):

Only jobs you can apply to on LinkedIn.

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

Most relevant or most recent first.

## `distanceMiles` (type: `integer`):

How far from a city location to search, as LinkedIn allows (5, 10, 25, 50, 100). Empty for LinkedIn's default.

## `geoId` (type: `string`):

LinkedIn's own ID of a location (the geoId in a search URL), for a place its name doesn't pin down.

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

Not needed for most runs. On the Apify platform, a run LinkedIn refuses switches to residential proxy by itself.

## Actor input object example

```json
{
  "searchTerms": [
    "data engineer"
  ],
  "location": "United States",
  "maxJobsPerSearch": 20,
  "includeDetails": true,
  "postedWithin": "any",
  "easyApply": false,
  "sortBy": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `jobs` (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 = {
    "searchTerms": [
        "data engineer"
    ],
    "location": "United States",
    "maxJobsPerSearch": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("pikoulas/linkedin-jobs").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 = {
    "searchTerms": ["data engineer"],
    "location": "United States",
    "maxJobsPerSearch": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("pikoulas/linkedin-jobs").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 '{
  "searchTerms": [
    "data engineer"
  ],
  "location": "United States",
  "maxJobsPerSearch": 20
}' |
apify call pikoulas/linkedin-jobs --silent --output-dataset

```

## MCP server setup

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

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/dfrmaVtnBnorTC7CR/builds/hlzKBNRPw7V924cGp/openapi.json
