# Linkedin Jobs Scraper (`api-ninja/linkedin-jobs-scraper`) Actor

Search LinkedIn jobs by keyword, location, and company. Set a result limit or collect every available matching job

- **URL**: https://apify.com/api-ninja/linkedin-jobs-scraper.md
- **Developed by:** [API ninja](https://apify.com/api-ninja) (community)
- **Categories:**
- **Stats:** 3 total users, 3 monthly users, 86.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## 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.
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 finds and exports LinkedIn job listings by keyword, location, company, posting date, Easy Apply availability, and applicant count.** Enter a search such as “Python developer,” choose how many jobs you want, and receive a clean dataset ready for research, analysis, outreach planning, or automation.

The Actor searches [LinkedIn Jobs](https://www.linkedin.com/jobs/), automatically resolves human-readable company and location inputs, paginates through matching listings, and preserves the complete source record alongside normalized fields. Running it on Apify gives you scheduled runs, monitoring, API access, downloadable datasets, webhooks, and integrations with tools such as Google Sheets, Make, Zapier, and cloud storage.

Key features include:

- 🔎 Search by job title, skill, technology, or keyword
- 📍 Filter by a city, region, or country name
- 🏢 Target one or multiple companies
- 🗓️ Limit results to the past 24 hours, week, or month
- ✅ Find Easy Apply opportunities
- ⚡ Filter for jobs with fewer than 10 applicants
- 📊 Browse a normalized table while retaining the complete raw source data
- ♾️ Set a maximum result count or collect all available matches

### Why use LinkedIn Jobs Scraper?

Manually reviewing job searches is slow and difficult to repeat. LinkedIn Jobs Scraper turns search results into structured data that can be filtered, compared, and sent to other systems.

Common use cases include:

- **Job market research:** compare hiring activity across locations, roles, and companies.
- **Lead generation:** identify organizations actively hiring for specific skills.
- **Recruiting intelligence:** monitor titles, workplace arrangements, and hiring signals.
- **Career research:** build a focused list of relevant roles and Easy Apply openings.
- **Trend analysis:** schedule recurring searches and track demand for technologies or professions.
- **Workflow automation:** connect job data to spreadsheets, databases, dashboards, or notification tools.

### How to scrape LinkedIn jobs

1. Open the Actor and click **Try for free**.
2. Enter a job search query, such as `Python developer` or `Product manager`.
3. Set **Maximum jobs**, or enable **Parse all jobs**.
4. Optionally open the advanced filters and enter a location, company names, posting period, or application filters.
5. Click **Start** and wait for the run to finish.
6. Open the **Output** tab to browse the normalized job table.
7. Download the results or connect the dataset to another Apify integration.

No LinkedIn geographic or company IDs are required. The Actor resolves location and company names automatically.

### Input

Configure the Actor in the **Input** tab. A minimal input only needs `query`:

```json
{
    "query": "Python developer",
    "maxJobs": 200,
    "parseAll": false,
    "location": "London",
    "companies": ["Google", "Amazon"],
    "timePostedRange": "r604800",
    "earlyApplicant": false,
    "applyWithLinkedin": true
}
```

| Field               | Type         | Description                                                                                |
| ------------------- | ------------ | ------------------------------------------------------------------------------------------ |
| `query`             | String       | Required job title, skill, or keyword.                                                     |
| `maxJobs`           | Integer      | Maximum jobs to save when `parseAll` is disabled. This is a limit, not a guaranteed count. |
| `parseAll`          | Boolean      | Continue until all available matching search results have been processed.                  |
| `location`          | String       | Optional city, region, or country name.                                                    |
| `companies`         | String array | Optional company names or LinkedIn company URLs.                                           |
| `timePostedRange`   | String       | Any time, past 24 hours, past week, or past month.                                         |
| `earlyApplicant`    | Boolean      | Request jobs marked as having fewer than 10 applicants.                                    |
| `applyWithLinkedin` | Boolean      | Request Easy Apply jobs only.                                                              |

LinkedIn may expose fewer matching or accessible jobs than requested. Consequently, a run with `maxJobs: 200` can finish with fewer than 200 records. Partial result pages, removed listings, changing search results, and active filters can all affect the final count.

### Output

Each dataset item contains user-friendly fields for the Output table and the complete original job card in `rawData`:

```json
{
    "jobTitle": "Junior Python Developer",
    "companyName": "Albany Beck",
    "companyId": "urn:li:fsd_company:818525",
    "companyUrl": "https://www.linkedin.com/company/albany-beck/",
    "companyLogoUrl": "https://media.licdn.com/example-company-logo.jpg",
    "location": "London Area, United Kingdom",
    "workplaceType": "Hybrid",
    "postedAt": "2026-09-08T11:12:54.000Z",
    "easyApply": true,
    "hiringInsight": "Actively reviewing applicants",
    "isRepost": false,
    "isVerified": true,
    "jobUrl": "https://www.linkedin.com/jobs/view/4464477609/",
    "jobId": "4464477609",
    "jobUrn": "urn:li:jobPosting:4464477609",
    "searchQuery": "Python developer",
    "requestedLocationId": "urn:li:geo:90009496",
    "requestedCompanyIds": ["urn:li:fsd_company:818525"],
    "rawData": {
        "jobPostingTitle": "Junior Python Developer",
        "jobId": "urn:li:jobPosting:4464477609"
    }
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. The normalized columns are ideal for spreadsheets and dashboards, while `rawData` is useful when you need fields that are not displayed in the main table.

### LinkedIn jobs data table

| Field            | Description                                                           |
| ---------------- | --------------------------------------------------------------------- |
| `jobTitle`       | Job listing title.                                                    |
| `companyName`    | Hiring company name.                                                  |
| `companyLogoUrl` | Best available company logo image.                                    |
| `companyId`      | LinkedIn company identifier.                                          |
| `companyUrl`     | Link to the company page.                                             |
| `location`       | Cleaned job location without the workplace suffix.                    |
| `workplaceType`  | Remote, Hybrid, or On-site when provided.                             |
| `postedAt`       | Listing date as an ISO timestamp.                                     |
| `easyApply`      | Whether the listing is marked Easy Apply.                             |
| `hiringInsight`  | Hiring signal such as active applicant review or typical review time. |
| `isVerified`     | Whether LinkedIn provides a job verification indicator.               |
| `isRepost`       | Whether the job is marked as reposted.                                |
| `jobUrl`         | Direct link to the LinkedIn job listing.                              |
| `jobId`          | Numeric LinkedIn job identifier.                                      |
| `rawData`        | Complete original job card for advanced use.                          |

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

The final cost depends on the pricing shown in the Actor’s **Pricing** tab and the size of your search. This Actor is lightweight and processes results in batches of up to 100 jobs, so smaller limits generally finish faster and use fewer resources.

For predictable runs, begin with 100–200 jobs and review the run cost before increasing the limit. Enabling **Parse all jobs** can process a much larger result set and therefore cost more. Company and location filters also require brief lookup steps before the job search begins. If your Apify account includes free platform credits, you can use them to test a small run.

### Tips and advanced options

- 🎯 Use a specific query such as `senior Python backend engineer` instead of a broad term such as `developer`.
- 📍 Add a location to reduce irrelevant results and improve run speed.
- 🏢 Enter full company names or company page URLs for the best company match.
- 🗓️ Schedule daily searches with the **Past 24 hours** filter to monitor new openings.
- 🔢 Use a reasonable maximum before enabling **Parse all jobs** on broad searches.
- 📤 Use Apify integrations or webhooks to send completed datasets to your existing workflow.
- 🔁 Search results can change while a run is active, so repeated runs may return a different order or count.

#### Access LinkedIn jobs through the Apify API

You can start runs, retrieve datasets, and integrate results programmatically through the [Apify API](https://docs.apify.com/api/v2). Replace the placeholders below with your Actor identifier and API token:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/<username>~linkedin-jobs-scraper/runs?token=<apify_token>" \
  -H "Content-Type: application/json" \
  -d '{"query":"Python developer","location":"London","maxJobs":200}'
```

#### Related Actor

Need social content rather than vacancies? Use **LinkedIn Company Posts Scraper** to collect company posts, media, authors, and engagement data.

### FAQ, disclaimers, and support

#### Why did the Actor return fewer jobs than the maximum?

`maxJobs` is an upper limit. LinkedIn may have fewer matching listings, return partial pages, remove jobs during the run, or restrict results after filters are applied. The Actor continues pagination correctly but cannot create records that are not available in the search results.

#### Can I search several companies at once?

Yes. Add one company name or LinkedIn company URL per row in the **Companies** input. The Actor resolves the companies and applies them as a combined search filter.

#### Can I schedule recurring job searches?

Yes. Use [Apify schedules](https://docs.apify.com/platform/schedules) to run the same search hourly, daily, or weekly. You can then use webhooks and integrations to notify a team or export the newest dataset.

#### Is it legal to scrape LinkedIn job listings?

Scraping publicly available information is generally possible, but laws, contracts, and platform terms vary by country and use case. You are responsible for ensuring that your use complies with LinkedIn’s terms, applicable regulations, privacy rules, and intellectual-property requirements. Avoid collecting or using personal data without a lawful purpose.

#### What should I do if a run fails?

Check the run log for invalid inputs, unavailable searches, or temporary response errors. The Actor automatically retries failed and malformed requests. If the problem continues, open the Actor’s **Issues** tab and include the run ID, non-sensitive input, and relevant log lines.

For specialized fields, higher-volume workflows, or a custom LinkedIn data solution, contact the developer through the **Issues** tab.

# Actor input Schema

## `query` (type: `string`):

Job title, skill, or keyword to search for, for example Python or Product Manager.

## `maxJobs` (type: `integer`):

Maximum number of jobs to save. This is an upper limit, not a guaranteed result count—the Actor may return fewer jobs when LinkedIn has fewer matching or accessible results. Ignored when Parse all jobs is enabled.

## `parseAll` (type: `boolean`):

Keep requesting result pages until every available matching job has been collected.

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

Optional location name, for example Chicago or Greater London. The Actor automatically resolves it to a LinkedIn geographic ID.

## `companies` (type: `array`):

Optional company names or LinkedIn company URLs. Add one per row; the Actor resolves each to a LinkedIn company ID.

## `timePostedRange` (type: `string`):

Only include jobs posted within the selected period.

## `earlyApplicant` (type: `boolean`):

Only return jobs currently marked as having fewer than 10 applicants.

## `applyWithLinkedin` (type: `boolean`):

Only return jobs that support applying directly through LinkedIn.

## Actor input object example

```json
{
  "query": "Python developer",
  "maxJobs": 100,
  "parseAll": false,
  "companies": [],
  "timePostedRange": "",
  "earlyApplicant": false,
  "applyWithLinkedin": false
}
```

# Actor output Schema

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

Open the dataset to browse normalized jobs, companies, locations, application options, and hiring signals.

# 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 = {
    "query": "Python developer"
};

// Run the Actor and wait for it to finish
const run = await client.actor("api-ninja/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 = { "query": "Python developer" }

# Run the Actor and wait for it to finish
run = client.actor("api-ninja/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 '{
  "query": "Python developer"
}' |
apify call api-ninja/linkedin-jobs-scraper --silent --output-dataset

```

## MCP server setup

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