# LinkedIn Jobs Scraper (`axlymxp/linkedin-jobs-scraper`) Actor

Scrape LinkedIn jobs by keyword, location, company or search URL: full description, salary, seniority, employment type, applicants. Goes past the 1,000-result cap, enforces job-type/experience/remote filters, can return only new jobs. No login.

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

## Pricing

from $0.80 / 1,000 dataset items

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: past the 1,000 cap, with filters that actually apply

Scrape LinkedIn job listings by keyword, location, company or pasted search URL. You get the full description, salary (when disclosed), seniority, employment type, job function, industries and applicant count, with no login and no cookies.

**What's different:**

- **More than 1,000 results per search.** LinkedIn stops every search at 1,000 results. When a search hits that cap, this actor continues through narrower "posted within" windows and merges the results without duplicates. For large searches that typically means 2–3× more unique jobs (in our test, 1,500+ unique for "software engineer" in the United States).
- **Filters you can trust.** For logged-out visitors, LinkedIn quietly ignores the job-type, experience-level and remote filters, so a plain scrape returns unfiltered jobs. This actor checks every job's detail page and returns only jobs that really match. **You're only charged for jobs that match.**
- **Strict keyword match (optional).** For rare or misspelled keywords, LinkedIn silently falls back to unrelated jobs in the area. Turn this on to keep only jobs that contain your keywords.
- **Only new jobs (optional).** The actor remembers what it has already returned for each search. Schedule it to get a feed of new postings.

### Who uses this

- **Recruiters and staffing agencies:** sourcing feeds, client hiring intelligence, and alerts when new roles open.
- **Job boards and HR-tech developers:** bulk job ingestion with full descriptions, salaries and seniority.
- **Sales and lead-gen teams:** find companies hiring for the roles your product serves, which is a strong buying signal.
- **Labour-market researchers:** job volumes past 1,000, seniority and function mix, salary disclosure.

### What you get

| Field | Example |
| --- | --- |
| `title`, `company`, `company_url`, `company_logo` | Formal Design Verification Engineer · Microsoft |
| `location`, `remote_mentioned` | Raleigh, NC · false |
| `posted_date`, `posted_ago` | 2026-09-20 · 5 days ago |
| `salary` | $117,000.00/yr - $234,000.00/yr (when disclosed) |
| `seniority_level`, `employment_type` | Mid-Senior level · Full-time |
| `job_function`, `industries` | Engineering and Information Technology · Software Development |
| `applicants`, `applicants_count` | 99 applicants · 99 |
| `benefits_badge` | Actively Hiring |
| `description_text`, `description_html` | Full job description |
| `job_id`, `job_url` | 4441465734 · https://www.linkedin.com/jobs/view/4441465734 |
| `search_keywords`, `search_location`, `posted_window` | which search and window found the job |

### Input

| Parameter | Description | Default |
| --- | --- | --- |
| **Search keywords** | One search per line, e.g. `python developer` | — |
| Location | City, region or country, matched to LinkedIn's location list | worldwide |
| Companies | Only jobs from these companies (name, LinkedIn URL or numeric ID) | — |
| LinkedIn job search URLs | Paste search URLs; their filters are enforced by the actor | — |
| Posted within | Any time / past hour / 24h / week / month | any |
| Employment type | Full-time, Part-time, Contract, Temporary, Internship, Volunteer, Other | — |
| Experience level | Internship … Executive, plus Not Applicable | — |
| Only jobs that mention remote | Title, location or clear description statement | off |
| Strict keyword match | Every keyword must appear in the title or description | off |
| Easy Apply only / Distance | Passed to LinkedIn | off / — |
| Max jobs checked per search | Budget for the post-filters (narrow filters can match under 1% of jobs) | 1000 |
| Max jobs | Total limit (0 = no limit) | 100 |
| Go past the 1,000-result cap | Split capped searches by posted date | on |
| Include full job details | Description, salary, applicants, criteria | on |
| Only new jobs | Return only jobs not returned before for the same search | off |
| Proxy (fallback) | Used only if LinkedIn starts throttling the run | off |

Provide at least one search keyword, company or search URL.

#### Example input

```json
{
  "searchQueries": ["data engineer"],
  "location": "United States",
  "postedWithin": "week",
  "employmentTypes": ["Full-time"],
  "experienceLevels": ["Mid-Senior level"],
  "maxItems": 200
}
```

#### Example output (shortened)

```json
{
  "job_id": "4441465734",
  "title": "Formal Design Verification Engineer",
  "company": "Microsoft",
  "location": "Raleigh, NC",
  "remote_mentioned": false,
  "posted_date": "2026-09-20",
  "salary": null,
  "applicants_count": 99,
  "seniority_level": "Not Applicable",
  "employment_type": "Full-time",
  "job_function": "Engineering and Information Technology",
  "industries": "Software Development",
  "description_text": "Overview\nMicrosoft Silicon, Cloud Hardware, and Infrastructure Engineering (SCHIE) is the team behind…",
  "job_url": "https://www.linkedin.com/jobs/view/4441465734",
  "posted_window": "any"
}
```

### Scheduling and monitoring

1. Save your input as a Task and turn on **Only new jobs**.
2. Schedule it (for example, every morning).
3. Each run returns only postings that weren't returned before for that search. Send them to Slack, email, Google Sheets or your ATS with Apify integrations, webhooks, Make or Zapier.

### Use with AI agents (MCP)

Add the actor to the Apify MCP server (`https://mcp.apify.com`) and an assistant such as Claude or Cursor can run searches for you. For example: "Find senior data engineer roles posted this week in Berlin with a salary listed."

### FAQ

**Do I need a LinkedIn account or cookies?**
No. The actor reads LinkedIn's public job listings as a logged-out visitor. No account is used, so none can be restricted.

**Why do I get fewer jobs than "Max jobs" when I use filters?**
Filters are checked against each job's detail page. Some combinations are rare. For example, Contract + Entry level matched about 1 in 1,000 US Python jobs in our tests. The run checks up to "Max jobs checked per search" jobs per search, then stops with a message in the log. You're charged only for matching jobs.

**Why is "Not Applicable" an experience level?**
Many employers leave seniority unset, and LinkedIn labels those jobs "Not Applicable". Add it to your experience filter if you want to keep them.

**How does the remote filter work?**
LinkedIn doesn't show a workplace-type field to logged-out visitors. The actor keeps jobs whose title or location mentions remote or work from home, or whose description clearly says the role is remote ("fully remote", "remote-first") without negating it. The `remote_mentioned` field shows the result for every job.

**Why do some jobs have no salary?**
Salary appears only when the employer discloses it on LinkedIn.

**How far past 1,000 can it go?**
It depends on how many jobs LinkedIn has for the search. Large searches typically yield 2–3× more unique jobs through the date windows. Very large searches can also be split by location or company to go further.

**Is this legal?**
The actor collects publicly visible job postings without logging in. Make sure your use complies with the laws that apply to you and with LinkedIn's terms.

# Actor input Schema

## `searchQueries` (type: `array`):

Job titles, skills or keywords — one search per line (e.g. 'python developer').

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

City, region or country (e.g. 'Berlin', 'California', 'United Kingdom'). Matched to LinkedIn's own location list. Leave empty for worldwide.

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

Only jobs from these companies. Company name (e.g. 'Stripe'), LinkedIn company URL, or numeric company ID. Works with or without keywords.

## `searchUrls` (type: `array`):

Paste LinkedIn job-search URLs (https://www.linkedin.com/jobs/search?...). Their keywords, location and filters are used; job-type, experience and remote filters in the URL are enforced by the actor.

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

Only jobs posted in this period.

## `employmentTypes` (type: `array`):

Keep only these employment types. Checked on each job's detail page (LinkedIn ignores this filter for logged-out searches).

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

Keep only these seniority levels, checked on each job's detail page. Note: many postings are labelled 'Not Applicable' — add it to keep them.

## `remoteOnly` (type: `boolean`):

Keep jobs whose title or location mentions remote / work from home, or whose description clearly states the role is remote (e.g. 'fully remote', 'remote-first') without negating it. LinkedIn does not expose a workplace-type field to logged-out visitors, so this is a text match — see 'remote\_mentioned' in the output.

## `strictKeywordMatch` (type: `boolean`):

Keep only jobs whose title or description contains every search keyword. LinkedIn's search is fuzzy and, for rare or misspelled keywords, silently falls back to unrelated jobs in the location — turn this on for niche searches. You are charged only for jobs that match.

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

Only jobs with LinkedIn Easy Apply.

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

Search radius around the location, in miles (e.g. 10, 25, 50, 100).

## `maxJobsChecked` (type: `integer`):

When employment-type, experience or remote filters are on, stop a search after checking this many job pages against them. Narrow combinations (e.g. Contract + Entry level) can match under 1% of LinkedIn postings — this keeps run time predictable. You are charged only for jobs that match.

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

Stop after this many jobs in total (0 = no limit).

## `splitBeyond1000` (type: `boolean`):

LinkedIn returns at most 1,000 results per search. When a search hits the cap, re-run it in narrower posted-within windows (month, week, 24h, 1h) and merge without duplicates — typically 2–3× more unique jobs for large searches.

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

Fetch each job's detail page: full description, salary, applicants, seniority, employment type, job function, industries. Turning it off is faster but returns card data only (details are still fetched when filters need them).

## `onlyNewJobs` (type: `boolean`):

Remember job IDs per search across runs and return only jobs not seen before. Schedule the actor to get a feed of new postings.

## `maxConcurrency` (type: `integer`):

Job detail pages fetched at once. Keep it low (2–4) to stay under LinkedIn's rate limits.

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

Optional. Requests go out directly; if LinkedIn starts throttling (HTTP 999/429), the run switches to this proxy for the rest of the run.

## Actor input object example

```json
{
  "searchQueries": [
    "python developer"
  ],
  "location": "Berlin",
  "postedWithin": "any",
  "remoteOnly": false,
  "strictKeywordMatch": false,
  "easyApplyOnly": false,
  "maxJobsChecked": 1000,
  "maxItems": 100,
  "splitBeyond1000": true,
  "includeDetails": true,
  "onlyNewJobs": false,
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per job: title, company, location, salary, seniority, employment type, applicants and full description.

## `summary` (type: `string`):

Totals: jobs pushed, filtered out, already seen, closed, requests.

# 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 = {
    "searchQueries": [
        "python developer"
    ],
    "location": "Berlin",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/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 = {
    "searchQueries": ["python developer"],
    "location": "Berlin",
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/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 '{
  "searchQueries": [
    "python developer"
  ],
  "location": "Berlin",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axlymxp/linkedin-jobs-scraper --silent --output-dataset

```

## MCP server setup

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