# LinkedIn Jobs Scraper \[FAST] | Search & Job Details (`apizy/linkedin-jobs-scraper`) Actor

Scrape public LinkedIn jobs by keyword and location, or fetch full details from job URLs. Run multiple searches, filter by date and title, and export via Dataset or Standby API. No login required. $0.00015 per delivered listing or $0.0004 per detailed job. No result-event charge for empty searches.

- **URL**: https://apify.com/apizy/linkedin-jobs-scraper.md
- **Developed by:** [Apizy](https://apify.com/apizy) (community)
- **Security:** Limited permissions
- **Stats:** 4 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.15 / 1,000 job listing scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

Search public LinkedIn jobs by keyword and location, filter by posting date and title, or collect full job descriptions from known job IDs and URLs. Run several searches together and get clean, deduplicated job rows in an Apify Dataset. For an immediate JSON response, call the Standby HTTP API. No LinkedIn login or browser is required.

Use it to monitor hiring, research companies and job markets, build recruiting workflows, compare skill demand, or give an AI assistant real job descriptions to analyze. **Result events are charged only for jobs delivered:** $0.00015 per listing or $0.0004 per full-detail job. Failed, filtered, duplicate, and empty results have no result-event charge.

### What does LinkedIn Jobs Scraper do?

| Mode | What you provide | What you get |
| --- | --- | --- |
| **Search** | A job phrase and location, or up to 10 keyword/location pairs | Public job listings with title, company, location, posting date, and URL |
| **Search with full details** | Search input plus `fullDetail: true` | Listings enriched with full descriptions and available job criteria |
| **Job details** | 1–50 LinkedIn job IDs or public job URLs | Full details for each available job |

Search can scan multiple keyword/location pairs in one run, alternate between them, and save each job ID once. `maxResults` is the **total cap across all searches**, not a cap per keyword. Detail mode deduplicates repeated IDs before fetching. By default, a search keeps only jobs whose title contains every keyword as a whole term. Turn off **Require every keyword in job title** if you want LinkedIn's broader related results.

#### What can you use it for?

- **Find relevant openings:** Search for roles in a city, country, or worldwide and filter to the last day, week, or month.
- **Monitor hiring demand:** Repeat a search over time to see which roles, technologies, and companies appear.
- **Research a job market:** Compare the same role across locations or compare several roles in one run.
- **Build a recruiting pipeline:** Send structured job rows to a spreadsheet, CRM, Make, n8n, Zapier, or your own application.
- **Analyze skills and requirements:** Collect descriptions and criteria to find recurring tools, experience levels, and responsibilities.
- **Explore product opportunities:** Look for problems companies are hiring people to solve before building a new service or AI-assisted product.
- **Create better job alerts:** Filter broad LinkedIn search results by posting period and title before notifying your users.
- **Enrich known jobs:** Give the Actor job URLs from a watchlist and collect the public details in one batch.

### How to use

1. Choose **Search** or **Job details** in the input form.
2. For Search, enter a phrase and location. Add `searches` when you want several keyword/location pairs in one run.
3. Set a posting period or additional title filters if needed. Enable **Fetch full job details** when you need descriptions and criteria.
4. Click **Run**. Open the **Dataset** for job rows and **Output** for counts, errors, and the stop reason.

For a direct JSON response, use the [HTTP API (Standby)](#http-api-standby) below.

#### Which input should you use?

| Goal | Mode | Main fields | Result event |
| --- | --- | --- | --- |
| Find software engineer openings in Singapore | Search | `keywords`, `location`, `maxResults` | Listing: $0.00015 per delivered job |
| Monitor several roles this week | Search | `searches`, `datePosted: "pastWeek"` | Listing: $0.00015 per delivered job |
| Read descriptions for matching roles | Search | `fullDetail: true` | Detail: $0.0004 per delivered job |
| Include related roles beyond the keyword title | Search | `requireAllKeywordsInTitle: false` | Listing or Detail, according to `fullDetail` |
| Refine title matches further | Search | `titleIncludes`, `titleExcludes` | Listing or Detail, according to `fullDetail` |
| Enrich a list of known jobs | Job details | `jobUrls` | Detail: $0.0004 per delivered job |

The table shows **result-event prices**. Actor Start and Apify platform usage are separate.

### Input examples

#### Find jobs by keyword and location

```json
{
  "mode": "search",
  "keywords": "software engineer",
  "location": "Singapore",
  "maxResults": 20,
  "fullDetail": false
}
```

This saves up to 20 unique listings. The source may return fewer. `location: "Worldwide"` removes the location filter.

#### Monitor several roles posted in the past week

```json
{
  "mode": "search",
  "searches": [
    { "keywords": "React Developer", "location": "Singapore" },
    { "keywords": "Node.js Developer", "location": "Australia" }
  ],
  "datePosted": "pastWeek",
  "maxResults": 100,
  "fullDetail": false
}
```

When `searches` is provided, it replaces the single `keywords` and `location` fields. The Actor alternates between searches and saves a repeated job ID once. `maxResults: 100` means **up to 100 jobs total** across both searches.

#### Collect descriptions for relevant roles

```json
{
  "mode": "search",
  "keywords": "product manager",
  "location": "United States",
  "datePosted": "pastMonth",
  "requireAllKeywordsInTitle": true,
  "titleExcludes": ["intern", "assistant"],
  "maxResults": 10,
  "fullDetail": true
}
```

Title filters run before detail requests. If a job description cannot be fetched, that job is skipped and the error is recorded in `OUTPUT.summary.errors`; it has no result-event charge. A delivered full-detail row uses only the Detail event, not both events.

#### Get details for known jobs

```json
{
  "mode": "detail",
  "jobUrls": [
    "https://www.linkedin.com/jobs/view/4479305237/",
    "4479305237"
  ]
}
```

You can provide 1–50 job IDs or public LinkedIn job URLs. The sample contains the same ID twice to show that it is fetched and charged at most once in this run.

#### Input fields

| Field | Mode | Default | Description |
| --- | --- | --- | --- |
| `mode` | Both | `search` | `search` or `detail` |
| `keywords` | Search | `software engineer` | One job title or search phrase, up to 200 characters |
| `location` | Search | `United States` | City, country, region, or `Worldwide` |
| `searches` | Search | None | Up to 10 keyword/location pairs; replaces the single pair |
| `maxResults` | Search | `10` | Total unique jobs to save across searches, 1–1,000 |
| `datePosted` | Search | `anyTime` | `anyTime`, `past24Hours`, `pastWeek`, or `pastMonth` |
| `fullDetail` | Search | `false` | Fetch each matching job's description and criteria |
| `requireAllKeywordsInTitle` | Search | `true` | Require each keyword as a whole term in the job title; set `false` to include related roles |
| `titleIncludes` | Search | None | Up to 10 phrases; every phrase must appear in the title |
| `titleExcludes` | Search | None | Up to 10 phrases; jobs containing any phrase are skipped |
| `jobUrls` | Detail | None | 1–50 job IDs or public LinkedIn job URLs |

Title matching is case-insensitive. For example, `CRM Developer` matches `Senior CRM Developer`, but not `Salesforce Developer`. If three consecutive search pages contain no new jobs matching the active title filters, that search stops and returns the matches already found. This limit applies separately to each search in a multi-search run. LinkedIn controls the source ranking and date filter; `maxResults` is a ceiling, not a guaranteed count.

### HTTP API (Standby)

Use the Actor as an HTTP service when your application needs JSON directly. Find the hostname and authentication instructions in the Actor's **Server** tab. Send your Apify token in the `Authorization: Bearer` header. Standby returns job rows in `items`; it does **not** save them to a Dataset. The **Run** form remains available for batch jobs.

| Endpoint | Example path | Result event |
| --- | --- | --- |
| Search | `GET /search?keyword=software%20engineer&location=Singapore&limit=10` | Listing per delivered job |
| Search with details | `GET /search?keyword=product%20manager&limit=5&fullDetail=true` | Detail per delivered job |
| One known job | `GET /details?job=4479305237` | Detail if the job is delivered |

`/search` accepts one keyword and location per request, `limit` from 1 to 100 (default 10), `datePosted`, `fullDetail`, and `requireAllKeywordsInTitle` (default `true`). Set `requireAllKeywordsInTitle=false` to include related jobs. `/details` accepts one ID or URL. Use a batch run for several searches, known job URLs, or the advanced `titleIncludes` and `titleExcludes` filters.

An HTTP response includes `mode`, `detailLevel`, `count`, `durationMs`, `stopReason`, and `items`. Invalid inputs return HTTP 400. Empty results have no Listing or Detail event. Apify Standby platform usage is additional, including time an instance waits for requests.

### Output

Each delivered job in a batch run is **one row in the default Dataset**. The default Key-Value Store contains `OUTPUT.summary`, which reports requested and saved counts, filtered and duplicate counts, pages fetched, errors, duration, and stop reason. Standby returns job rows directly in the HTTP response.

**Example listing row** (illustrative, shortened):

```json
{
  "jobId": "4479305237",
  "title": "Software Engineer",
  "company": "Example Company",
  "location": "Singapore",
  "postedAt": "2026-10-29",
  "jobUrl": "https://www.linkedin.com/jobs/view/4479305237",
  "allKeywordsInTitle": true,
  "searchKeywords": "software engineer",
  "searchLocation": "Singapore",
  "searchDatePosted": "pastWeek",
  "detailFetched": false,
  "source": "linkedin-public-guest",
  "scrapedAt": "2026-10-30T08:00:00.000Z"
}
```

| Field group | Dataset fields | Notes |
| --- | --- | --- |
| Job identity | `jobId`, `jobUrl`, `title`, `company`, `companyUrl`, `companyLogo`, `location` | Public listing fields; some may be missing |
| Posting | `postedAt`, `postedAgo`, `applicantsText` | Availability depends on the public page |
| Full details | `description`, `descriptionHtml`, `criteria`, `detailFetched` | Descriptions and criteria require Detail mode or `fullDetail: true` |
| Search context | `searchKeywords`, `searchLocation`, `searchDatePosted`, `allKeywordsInTitle` | Shows how a Search result was found |
| Capture | `source`, `scrapedAt` | Source type and capture time |

**Example `OUTPUT.summary`** (shortened):

```json
{
  "mode": "search",
  "requested": 20,
  "foundCount": 18,
  "savedCount": 15,
  "filteredCount": 2,
  "duplicatesSkipped": 1,
  "failedCount": 0,
  "pagesFetched": 3,
  "stopReason": "completed",
  "eventName": "job-listing-scraped",
  "chargedCount": 15
}
```

The summary is inside the `summary` property of the `OUTPUT` record. `requested` is the input ceiling; `savedCount` is the number of delivered Dataset rows. `matchedCount` counts jobs that passed the title filters before detail fetching. A run may stop with `completed`, `no_results`, `no_relevant_results`, `relevance_exhausted`, or `event_limit`.

### Pricing

| Delivered jobs | Search listings | Full details |
| ---: | ---: | ---: |
| 10 | $0.0015 | $0.004 |
| 100 | $0.015 | $0.04 |
| 1,000 | $0.15 | $0.40 |

The result events are **`job-listing-scraped` at $0.00015 per delivered listing** and **`job-detail-scraped` at $0.0004 per delivered full-detail job**. A full-detail job gets one Detail event only. Failed, filtered, duplicate, and empty results have no result-event charge. If you request 100 jobs and only 10 are delivered, only those 10 trigger result events.

The standard Actor Start event is $0.00005 per event; Apify platform usage is additional. Standby can also incur platform usage while an instance is idle. The table shows result-event charges only. Check the [Pricing tab](https://apify.com/apizy/linkedin-jobs-scraper/pricing) for current complete pricing.

### Notes

- The Actor reads public LinkedIn guest pages. LinkedIn can change its HTML, return related roles, limit requests, or provide fewer results than requested.
- Some public fields, including posting date, company logo, applicant count, and job criteria, may be absent.
- This Actor does not promise salary ranges or an external application URL. It does not invent missing fields.
- Search scans at most 100 source pages per keyword/location pair in a batch run. A narrower posting period or stricter title filter may produce fewer saved jobs.

### More Actors You Might Like

Built by the same Apizy team and backed by our transparent pricing philosophy: see which results are delivered, pay result events for successful rows, and avoid result charges for failed or empty items.

| Actor | What it helps you collect |
| --- | --- |
| [Google Play Store Scraper](https://apify.com/apizy/google-play-store-scraper) | Android app search results, charts, and full details |
| [App Store Scraper](https://apify.com/apizy/apple-app-store-scraper) | iOS app search results, charts, and full details |
| [YouTube Channel Scraper \[FAST\]](https://apify.com/apizy/youtube-channel-scraper-v2) | Channel stats, engagement, and contact information |
| [YouTube Video Scraper](https://apify.com/apizy/youtube-video-scraper) | Video titles, views, and publish dates |

### Get in Touch

Have a question or need a custom scraping workflow? Email **apizy.studio@gmail.com**.

# Actor input Schema

## `mode` (type: `string`):

Search for jobs or fetch known job IDs and URLs.

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

Job title or search phrase. Search results are ranked by LinkedIn and may include related jobs.

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

City, country, or region, for example United States or Singapore. Use Worldwide for no location filter.

## `searches` (type: `array`):

Add up to 10 keyword/location pairs. When provided, these replace the single Keywords and Location fields. Results are combined and duplicate job IDs are saved once.

## `maxResults` (type: `integer`):

Maximum unique job rows saved across all searches. The source can return fewer than requested. Up to 100 pages are scanned per search.

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

LinkedIn's public search filter. Applies to every search; availability and ordering depend on LinkedIn.

## `fullDetail` (type: `boolean`):

Fetch each job's description and criteria after searching. Jobs whose detail fails are skipped.

## `requireAllKeywordsInTitle` (type: `boolean`):

Keep only jobs whose title contains every keyword as a whole term. Uncheck to include related jobs returned by LinkedIn. After three consecutive pages without a matching title, the search stops.

## `titleIncludes` (type: `array`):

Optional. Every phrase here must appear in the job title, case-insensitive.

## `titleExcludes` (type: `array`):

Optional. Jobs whose title contains any phrase here are skipped, case-insensitive.

## `jobUrls` (type: `array`):

One or more numeric LinkedIn job IDs or public LinkedIn job URLs. Duplicates are fetched once.

## Actor input object example

```json
{
  "mode": "search",
  "keywords": "software engineer",
  "location": "United States",
  "maxResults": 10,
  "datePosted": "anyTime",
  "fullDetail": false,
  "requireAllKeywordsInTitle": true
}
```

# Actor output Schema

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

One Dataset item per saved job.

## `output` (type: `string`):

Search, counts, source pages, and errors.

# 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 = {};

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

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

```

## MCP server setup

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