# LinkedIn Jobs Scraper: Job Search, No Login, With Descriptions (`redfoxscout/linkedin-jobs-scraper`) Actor

Scrape LinkedIn job listings by keyword and location, no login or cookies needed. Get title, company, location, salary, posted date, full description, seniority, employment type, applicants and apply link. Filter by date, remote, job type and level.

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

## Pricing

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

Scrape **fresh, low-competition LinkedIn jobs** without logging in. Filter to jobs posted in the **last 24 hours** with **under 10 applicants** and **Easy Apply**, drop **staffing agencies** and **reposted duplicates**, and get the salary as numbers. Every job also comes with its full description, seniority, applicant count and apply type.

**Price: $0.80 per 1,000 jobs.** Failed searches and duplicates are free. Apify's free plan ($5 monthly credit) covers about 6,000 jobs a month.

[![Jobs posted in the last 24 hours with under 10 applicants: real output preview (Posted in the last 24 hours, under 10 applicants, staffing agencies and reposts removed)](https://raw.githubusercontent.com/TikTop-Data/apify-store-assets/main/images/linkedin-jobs-scraper-output.png)](https://apify.com/redfoxscout/linkedin-jobs-scraper)

### Questions it answers

- Which companies posted data engineer jobs in Germany in the last 24 hours, and how many people applied?
- Which new jobs have fewer than 10 applicants and an Easy Apply button?
- What salary range do remote data analyst jobs in the US publish?
- Which companies are hiring for roles that need my product (e.g. "Salesforce administrator")?
- Did a specific company post new jobs this week?

### Who uses this

- 🧑‍💼 **Recruiters and agencies:** find companies hiring for the roles you place, every day.
- 📈 **Sales teams:** hiring is a buying signal; a company hiring five data engineers needs data tools.
- 📊 **Job boards and analysts:** feed fresh listings into a job site, newsletter or labor-market dashboard.
- 🎯 **Job seekers:** one sheet of fresh, uncrowded jobs with descriptions, instead of endless scrolling.

### Why this LinkedIn Jobs Scraper

- 🆕 **Fresh and uncrowded:** posted in the last 24 hours, under 10 applicants, Easy Apply. These are LinkedIn's own filters, applied on LinkedIn's side.
- 🧹 **Less noise by default:** staffing agencies and the same job posted again are removed (turn either off to keep them).
- 💵 **Salary as numbers:** minimum, maximum, currency and period, whenever the employer shows pay.
- 🏢 **Company watch:** follow companies by name or LinkedIn company ID, with their website, industry, size and logo.
- 🔒 **No login needed.** It reads the public job listings LinkedIn shows to any visitor. No cookies, no account at risk.
- 🤝 **Exact applicant counts:** the number of applicants as a number when LinkedIn shows it (33, 110...), ready to sort for the least crowded jobs.
- 💰 **Pay only for jobs delivered**, at $0.80 per 1,000.

### How to use the LinkedIn Jobs Scraper

1. Click **Try for free** (a free Apify account is enough).
2. Enter job titles or keywords and locations, one per line. Or enter company names or LinkedIn company IDs instead.
3. Optional: add the fresh-job filters, a title or company filter, or paste a LinkedIn jobs search URL to reuse its filters.
4. Click **Start**, then download the jobs as JSON, CSV or Excel, or schedule the run for a daily feed.

### Input

| Field | Default | What it does |
|---|---|---|
| `keywords` | – | Job titles or keywords, one per line. |
| `locations` | – | Countries, regions or cities. Every keyword is searched in every location. Empty = worldwide. |
| `distance` | LinkedIn's | Radius around each location, in miles. Only used with a location. |
| `postedWithin` | `any` | `day`, `week`, `month` or `any`. |
| `workplace` | all | Any of `onsite`, `remote`, `hybrid`. |
| `jobType` | all | Any of `fulltime`, `parttime`, `contract`, `temporary`, `internship`, `volunteer`, `other`. |
| `experience` | all | Any of `internship`, `entry`, `associate`, `midsenior`, `director`, `executive`. |
| `sortBy` | `relevance` | `relevance` or `date` (newest first). |
| `includeDetails` | `true` | Adds description, seniority, employment type, job function, industries, applicants, apply type and open/closed state. One extra request per job. |
| `includeHiringTeam` | `false` | Adds the hiring team when LinkedIn's public job page shows it (`hiringTeam`, plus `posterName`, `posterTitle`, `posterProfileUrl`). Rare: most public pages show none. Needs `includeDetails`. |
| `under10Applicants` | `false` | Only jobs with fewer than 10 applicants (LinkedIn's filter). |
| `easyApply` | `false` | Only jobs with Easy Apply. |
| `dropReposts` | `true` | One row per company, title and location across all searches. Set `false` to keep every repost. |
| `excludeAgencies` | `true` | Drops staffing and recruiting firms (name heuristic; with details, also LinkedIn's industry). Set `false` to keep agency posts. |
| `companyNames` | – | Keeps jobs whose company name contains one of these names, as whole words (`Meta` matches "Meta Platforms", not "Metalworks"). With no keywords, each name is searched. |
| `companyIds` | – | Numeric LinkedIn company IDs, e.g. `1441` for Google. LinkedIn filters on these, so it is the faster choice. |
| `includeCompanyDetails` | `false` | Adds company website, industry, size and logo. One extra request per company. |
| `titleInclude` | – | Keeps jobs whose title contains at least one of these words (whole words, any case). |
| `titleExclude` | – | Drops jobs whose title contains any of these words, e.g. `intern`, `senior`. |
| `searchUrls` | – | LinkedIn jobs search URLs; their filters are kept. |
| `startUrls` | – | Same as `searchUrls`, for compatibility with other job scrapers. Both lists are searched. |
| `maxItems` | 50 | Jobs per search (max 1,000). |

### Output

One row per job. A real row from a local run on the input in the Fresh jobs section below (description shortened):

```json
{
  "jobId": "4477416095",
  "title": "Process-Mining Consultant:in",
  "company": "smartist.one",
  "companyUrl": "https://de.linkedin.com/company/smartistone",
  "location": "Germany",
  "postedAt": "2026-10-08",
  "postedAgo": "4 hours ago",
  "postedAtTimestamp": 1791473577199,
  "salary": "€55,000.00/yr - €75,000.00/yr",
  "salaryMin": 55000,
  "salaryMax": 75000,
  "salaryCurrency": "EUR",
  "salaryPeriod": "year",
  "benefits": "Be an early applicant",
  "description": "Ein Freund von uns sucht nach einem Process Mining Berater (m/w/d). Dich erwartet ein eingespieltes Team ...",
  "seniorityLevel": "Associate",
  "employmentType": "Full-time",
  "jobFunction": null,
  "industries": "Telecommunications, Utilities, and IT Services and IT Consulting",
  "applicants": "Be among the first 25 applicants",
  "applicantCount": null,
  "applyUrl": null,
  "applyType": "easy_apply",
  "jobState": "open",
  "hiringTeam": [],
  "posterName": null,
  "posterTitle": null,
  "posterProfileUrl": null,
  "jobUrl": "https://www.linkedin.com/jobs/view/4477416095/",
  "searchQuery": "data engineer in Germany"
}
```

`descriptionHtml` keeps the original formatting. `postedAtTimestamp` is estimated from LinkedIn's relative time ("4 hours ago"): within about an hour for minutes and hours, within about a day for days. `postedAt` is the exact date. `applicantCount` is the exact number when LinkedIn shows one; `applicants` keeps the text as shown. `hiringTeam` is an empty list when the job page shows no hiring team.

### Example tasks

Ready-made inputs you can open, change and run:

- [Jobs posted in the last 24 hours with under 10 applicants](https://apify.com/redfoxscout/linkedin-jobs-scraper/examples/fresh-jobs-under-10-applicants-24h)
- [Find remote software engineer jobs posted this week](https://apify.com/redfoxscout/linkedin-jobs-scraper/examples/remote-software-engineer-jobs-linkedin)
- [Find data analyst jobs in the US](https://apify.com/redfoxscout/linkedin-jobs-scraper/examples/data-analyst-jobs-linkedin)
- [Find product manager jobs in New York](https://apify.com/redfoxscout/linkedin-jobs-scraper/examples/product-manager-jobs-linkedin)
- [Find jobs in Dubai and the UAE](https://apify.com/redfoxscout/linkedin-jobs-scraper/examples/jobs-in-dubai-linkedin)
- [Find entry-level jobs and internships for graduates](https://apify.com/redfoxscout/linkedin-jobs-scraper/examples/entry-level-jobs-linkedin)
- [See which companies are hiring sales reps](https://apify.com/redfoxscout/linkedin-jobs-scraper/examples/companies-hiring-sales-reps-linkedin)

### Applicant counts and hiring team

- **Exact applicant count:** `applicantCount` is the number when LinkedIn shows one, for example 33 from "33 applicants". "Over 200 applicants" and "Be among the first 25 applicants" give `null`; `applicants` keeps LinkedIn's text.
- **Hiring team:** with `includeHiringTeam` on, `hiringTeam` lists the people a public job page shows under "Meet the hiring team" (`{ name, title, profileUrl }`), and `posterName`, `posterTitle`, `posterProfileUrl` hold the first one. LinkedIn rarely shows this block to visitors who are not signed in, so expect an empty list on most jobs. Signed-in pages were checked on 2026-10-09 and did not include it either, so this Actor does not use login cookies.

### Fresh jobs with few applicants

Example input (this exact input produced the row shown under Output):

```json
{ "keywords": ["data engineer"], "locations": ["Germany"], "postedWithin": "day", "under10Applicants": true, "easyApply": true, "dropReposts": true, "excludeAgencies": true, "maxItems": 5 }
```

- **Posted within: Past 24 hours** uses LinkedIn's date filter.
- **Under 10 applicants** and **Easy Apply** are LinkedIn's own filters, so LinkedIn applies them before any job reaches you.
- **Drop reposts** keeps one row per company, title and location across all searches. The same job posted again under a new ID is removed. The same title posted in two cities stays, because those are two openings.
- **Exclude staffing agencies** removes recruiters by company name (for example "staffing", "recruitment", "executive search", Randstad, Robert Half) and, when details are on, by LinkedIn's "Staffing and Recruiting" industry. It is a heuristic: some agencies with plain names still get through.

### Salary, apply type and company details

- **Salary:** `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod` (year, month, week, day or hour) are parsed from the pay text. When the card shows no pay, the pay from the job page is used (with details on). Empty when the employer shows no pay.
- **Apply type:** `applyType` is `easy_apply` when the job can be applied to on LinkedIn, and `external` when it sends you to the company's site. `applyUrl` stays empty for logged-out visitors, so use `applyType` instead.
- **Company details** (optional): `companyWebsite`, `companyIndustry`, `companySize` and `companyLogo` come from the company's public LinkedIn page. Pages that ask for a login are skipped and left empty.

### Daily job feed

Schedule the Actor (Apify Console → Schedules) with `postedWithin: "day"`, `sortBy: "date"` and `dropReposts: true`. Each day you get the new jobs only, then send them to Google Sheets, Slack or a webhook with Apify integrations.

### What this Actor does not do

It does not log in, so LinkedIn's login-only features (such as "jobs in your network") are not offered. It cannot submit applications, message anyone, follow companies or post. The hiring team is returned only as the job page shows it: it does not visit those people's profiles, search for them, or look up emails or phone numbers. It does not fill `applyUrl` for external jobs, because LinkedIn shows that link only to logged-in users.

### How much does it cost?

$0.80 per 1,000 jobs delivered, with full descriptions included.

- 100 jobs: about $0.08
- 10,000 jobs: about $8
- Failed searches, duplicate jobs and jobs removed by your filters: free
- Hiring team and applicant count: no extra charge

Apify's free plan gives $5 of credit every month, enough for about 6,000 jobs.

### FAQ

**Is this legal?** It collects public job listings that LinkedIn shows to anyone without logging in. The only people data it returns is the hiring team that the job page shows (name, title and public profile link), not profile details or contact information. You are responsible for using the data in line with the laws and terms that apply to you.

**How many jobs can I get per search?** LinkedIn shows at most about 1,000 results per search. For more, split by location or add filters.

**Why did I get fewer jobs than `maxItems`?** Filters such as "under 10 applicants" or "exclude agencies" skip jobs before they are charged, and LinkedIn may return fewer results for a narrow search. The run log says how many jobs each filter skipped.

**Why is the salary empty?** Pay is only filled when the employer publishes it on the listing. Pay written without an amount (for example "competitive") leaves the salary fields empty.

**Why is `hiringTeam` empty?** LinkedIn rarely shows the hiring team on public job pages, so most jobs have none. Turn `includeHiringTeam` off to leave those fields out.

**Why is `applyUrl` empty?** LinkedIn shows the company's own apply link only to logged-in users. Use `applyType` to see whether a job applies on LinkedIn or on the company site.

**Some runs are slower. Why?** If LinkedIn slows requests down, the run waits and retries. Lower "Searches in parallel" for very large runs. Title, company and agency filters are checked page by page, so a narrow filter can scan many pages to find enough jobs; a company ID or a more specific keyword is faster.

### Related Actors

- [Jobs Index](https://apify.com/redfoxscout/jobs-index): search 260,000+ startup jobs from company career pages at once.
- [ATS Jobs Scraper](https://apify.com/redfoxscout/ats-jobs-scraper): every open job at companies on Greenhouse, Lever, Ashby and more.
- [Company Social Links Finder](https://apify.com/redfoxscout/company-social-links): each company's LinkedIn page and other profiles from its website.

# Actor input Schema

## `keywords` (type: `array`):

What to search for, one per line, e.g. data engineer, nurse, react developer.

## `locations` (type: `array`):

Countries, regions or cities, one per line. Every keyword is searched in every location. Leave empty for worldwide.

## `distance` (type: `integer`):

Radius around each location, in miles, e.g. 10 or 25. Leave empty for LinkedIn's default. Only used with a location.

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

Only jobs posted in this period.

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

Leave empty for all.

## `jobType` (type: `array`):

Leave empty for all.

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

Leave empty for all.

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

Order of results.

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

Adds description, seniority, employment type, job function, industries, applicants, apply type (Easy Apply or external) and open/closed state. One extra request per job.

## `includeHiringTeam` (type: `boolean`):

Add the hiring team when LinkedIn's public job page shows it (rare). Needs full details.

## `under10Applicants` (type: `boolean`):

Only jobs with fewer than 10 applicants, filtered by LinkedIn itself. Best combined with Posted within = Past 24 hours.

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

Only jobs that can be applied to on LinkedIn (Easy Apply), not only on the company's own site.

## `dropReposts` (type: `boolean`):

Keep one row per company, title and location across all searches. A job posted again under a new LinkedIn ID is removed and not charged. On by default.

## `excludeAgencies` (type: `boolean`):

Drop jobs from recruiters and staffing firms, found by company name and by LinkedIn's Staffing and Recruiting industry. A heuristic: a few agencies can slip through. On by default; turn off to keep agency posts.

## `companyNames` (type: `array`):

Keep jobs whose company name contains one of these names, e.g. Google or Siemens. With no keywords, each name is also searched.

## `companyIds` (type: `array`):

Numeric LinkedIn company IDs, one per line, e.g. 1441 for Google. LinkedIn filters on these itself, so runs are faster than with names.

## `includeCompanyDetails` (type: `boolean`):

Adds the company's website, industry, size and logo from its public LinkedIn page. One extra request per company; left empty where LinkedIn asks for a login.

## `titleInclude` (type: `array`):

Keep only jobs whose title contains at least one of these words, e.g. data or analyst. Whole words, case-insensitive.

## `titleExclude` (type: `array`):

Drop jobs whose title contains any of these words, e.g. intern or senior. Whole words, case-insensitive.

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

Paste LinkedIn jobs search URLs to reuse their filters, e.g. https://www.linkedin.com/jobs/search/?keywords=nurse\&location=Texas\&f_WT=2

## `startUrls` (type: `array`):

Same as the LinkedIn search URLs above, for compatibility with other job scrapers. Both lists are searched.

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

Stop each search after this many results.

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

How many searches run at once.

## `sessionCookies` (type: `string`):

Not used: LinkedIn signed-in pages add no data this Actor reads. Kept so older inputs still run.

## Actor input object example

```json
{
  "keywords": [
    "data engineer"
  ],
  "locations": [
    "Germany"
  ],
  "postedWithin": "any",
  "sortBy": "relevance",
  "includeDetails": true,
  "includeHiringTeam": false,
  "under10Applicants": false,
  "easyApply": false,
  "dropReposts": true,
  "excludeAgencies": true,
  "includeCompanyDetails": false,
  "maxItems": 10,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `results` (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 = {
    "keywords": [
        "data engineer"
    ],
    "locations": [
        "Germany"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("redfoxscout/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 = {
    "keywords": ["data engineer"],
    "locations": ["Germany"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("redfoxscout/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 '{
  "keywords": [
    "data engineer"
  ],
  "locations": [
    "Germany"
  ],
  "maxItems": 10
}' |
apify call redfoxscout/linkedin-jobs-scraper --silent --output-dataset

```

## MCP server setup

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