# Linkedin Jobs Scraper ($1/1000 results) (`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)
- **Features:** Limited permissions
- **Stats:** 70 total users, 13 monthly users, 97.1% runs succeeded, 1 bookmarks
- **User rating**: 5.00 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.
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?

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

### 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?

This Actor uses **pay-per-event pricing** with a **$0.10 minimum total charge per run**.

| Charge | Free plan | Bronze-Diamond plans |
| --- | ---: | ---: |
| Actor start | $0.01 | $0.01 |
| Result saved to the default dataset | $0.01 per result | $0.001 per result |

The Actor start event is charged once per GB of memory, with at least one event per run. The final cost depends mainly on how many job records are saved. Begin with 100-200 jobs and enable **Parse all jobs** only when you need every available match. Check the Actor's **Pricing** tab for the latest rates before starting a large 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}'
```

### Other LinkedIn Scraping Tools

If you like this Actor, you might also find these LinkedIn tools useful:

- 👤 **[LinkedIn Profile Scraper](https://apify.com/api-ninja/linkedin-profile-scraper)**: Collect profile posts, reactions, comments, images, videos, documents, and events in one workflow.
- 👤 **[LinkedIn Profile Posts Scraper](https://apify.com/api-ninja/linkedin-profile-posts-scraper)**: Collect public posts published by LinkedIn member profiles.
- 💡 **[LinkedIn Post Reactions Scraper](https://apify.com/api-ninja/linkedin-post-reactions-scraper)**: Collect people who reacted to a post and their reaction types.
- 🏢 **[LinkedIn Company Posts Scraper](https://apify.com/api-ninja/linkedin-company-posts-scraper)**: Collect posts, media, authors, and engagement from company pages.
- 💬 **[LinkedIn Post Comments Scraper](https://apify.com/api-ninja/linkedin-post-comments-scraper)**: Extract comments and optional replies from public posts.
- 🔁 **[LinkedIn Post Reposters Scraper](https://apify.com/api-ninja/linkedin-post-reposters-scraper)**: Find people and companies that reposted a public post.
- 🔎 **[LinkedIn Post Search Scraper](https://apify.com/api-ninja/linkedin-post-search-scraper)**: Discover public posts by keyword and advanced filters.

### 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/BTNhhzRIl7Zsipa87/openapi.json
