# LinkedIn Jobs Scraper With Details (`dtrungtin/linkedin-jobs-scraper-with-details`) Actor

Scrape public LinkedIn job postings by keyword, location and company – no login required. Returns title, company, location, posting date, salary, seniority, full description and more, with pagination, de-duplication, proxy support and an automatic stealth-browser fallback.

- **URL**: https://apify.com/dtrungtin/linkedin-jobs-scraper-with-details.md
- **Developed by:** [Tin](https://apify.com/dtrungtin) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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.

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** extracts **public job postings from [LinkedIn Jobs](https://www.linkedin.com/jobs)** – no LinkedIn account, cookies or login required. Search by **keyword, location and company**, apply the same filters LinkedIn offers (date posted, job type, experience level, remote/hybrid/on-site) and get clean, de-duplicated **JSON, CSV or Excel** with the job title, company, location, posting date, salary (when shown), seniority level, employment type, industries, applicant count and the **full job description**.

Because it runs on the [Apify platform](https://apify.com), you also get an **API**, **scheduling**, **integrations** (Google Sheets, Slack, Make, Zapier, webhooks), **proxy rotation** and **run monitoring** out of the box. Try it with the prefilled example in the Input tab – it takes about a minute.

### Why scrape LinkedIn jobs?

- **Lead generation** – companies that are hiring are companies that are buying. Find businesses opening sales, engineering or marketing roles in your territory and reach out while the budget exists.
- **Recruiting and sourcing** – monitor which competitors are hiring for which roles, benchmark job descriptions and spot new openings the day they appear.
- **Market and salary research** – track demand for skills, technologies and job titles over time, by region or by industry.
- **Job aggregation** – feed a job board, newsletter or Slack channel with fresh, structured postings from the world's largest professional network.

### How to scrape LinkedIn jobs

1. Open the Actor in Apify Console and click **Try for free**.
2. Enter one or more **Keywords** (e.g. `data engineer`) and a **Location** (e.g. `Berlin`).
3. Optionally narrow the search with **Date posted**, **Job type**, **Experience level**, **Workplace type** or **Company** filters.
4. Set **Maximum jobs** to control how many postings (and therefore how much compute) the run uses.
5. Click **Start**. Results appear in the **Output** tab as they are scraped and can be exported in any format.

Already have a LinkedIn search URL? Paste it into **Start URLs** – every filter encoded in the URL is preserved. Individual job URLs (`linkedin.com/jobs/view/...`) work too.

### Input

The Input tab documents every field. The important ones:

| Field                | What it does                                                                                                |
| -------------------- | ----------------------------------------------------------------------------------------------------------- |
| `keywords`           | List of search terms. Each runs as its own search; results are de-duplicated across searches.               |
| `location`           | Free-text location, exactly as you would type it into LinkedIn.                                             |
| `datePosted`         | `any`, `pastHour`, `past24Hours`, `pastWeek` or `pastMonth`.                                                |
| `jobTypes`           | Any of `fullTime`, `partTime`, `contract`, `temporary`, `internship`, `volunteer`, `other`.                 |
| `experienceLevels`   | Any of `internship`, `entryLevel`, `associate`, `midSeniorLevel`, `director`, `executive`.                  |
| `workplaceTypes`     | Any of `onSite`, `remote`, `hybrid`.                                                                        |
| `companyIds`         | Numeric LinkedIn company IDs – filters on LinkedIn's side (e.g. `1441` for Google).                         |
| `companyNames`       | Case-insensitive company-name filter applied by the scraper (`Amazon` also matches `Amazon Web Services`).  |
| `sortBy`             | `relevance` (default) or `date`.                                                                            |
| `startUrls`          | LinkedIn job search or job posting URLs to scrape in addition to the search above.                          |
| `maxItems`           | Stop after this many jobs (default `100`, `0` = unlimited).                                                 |
| `scrapeJobDetails`   | Open every posting for the description and criteria (default `true`). Turn off for a fast listing-only run. |
| `fetchMode`          | `auto` (HTTP first, stealth-browser fallback), `http` or `browser`.                                         |
| `proxyConfiguration` | Apify Proxy settings. Residential proxies are strongly recommended.                                         |

Example input:

```json
{
    "keywords": ["data engineer", "analytics engineer"],
    "location": "Germany",
    "datePosted": "pastWeek",
    "workplaceTypes": ["remote", "hybrid"],
    "experienceLevels": ["midSeniorLevel"],
    "maxItems": 200,
    "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

### Output

Each job is one item in the default dataset. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel, or read it through the API.

```json
{
    "id": "4419969671",
    "url": "https://www.linkedin.com/jobs/view/4419969671",
    "title": "Senior Software Engineer – Go (Golang)",
    "companyName": "General Motors",
    "companyUrl": "https://www.linkedin.com/company/general-motors",
    "companyLogo": "https://media.licdn.com/dms/image/v2/.../general_motors_logo",
    "location": "Warren, MI",
    "postedAt": "2026-08-22",
    "postedText": "1 week ago",
    "salary": null,
    "benefits": "Actively Hiring",
    "seniorityLevel": "Not Applicable",
    "employmentType": "Full-time",
    "jobFunction": "Engineering and Information Technology",
    "industries": "Motor Vehicle Manufacturing, Appliances, Electrical, and Electronics Manufacturing, and IT Services and IT Consulting",
    "applicantsCount": 136,
    "applicantsText": "136 applicants",
    "descriptionText": "Job Description\nAs a Senior Software Engineer – Go (Golang), you will design, develop, and deliver ...",
    "descriptionHtml": "<p><strong>Job Description</strong></p><p>As a Senior Software Engineer – Go (Golang), you will ...</p>",
    "applyUrl": null,
    "detailScraped": true,
    "query": { "keywords": "software engineer", "location": "United States" },
    "scrapedAt": "2026-09-05T10:41:12.345Z"
}
```

#### Data fields

| Field                                                           | Description                                                                                     |
| --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `id`, `url`                                                     | LinkedIn job ID and canonical posting URL.                                                      |
| `title`                                                         | Job title.                                                                                      |
| `companyName`, `companyUrl`, `companyLogo`                      | Hiring company, its LinkedIn page and logo.                                                     |
| `location`                                                      | Location as shown on the posting.                                                               |
| `postedAt`, `postedText`                                        | Posting date (`YYYY-MM-DD`) and LinkedIn's relative wording ("2 days ago").                     |
| `salary`                                                        | Salary range when LinkedIn displays one, otherwise `null`.                                      |
| `benefits`                                                      | Listing badge such as "Actively Hiring" or "Be an early applicant".                             |
| `seniorityLevel`, `employmentType`, `jobFunction`, `industries` | The criteria block from the posting (details only).                                             |
| `applicantsCount`, `applicantsText`                             | Number of applicants when LinkedIn shows a concrete figure (details only).                      |
| `descriptionText`, `descriptionHtml`                            | Full job description as plain text and as HTML (details only).                                  |
| `applyUrl`                                                      | Off-site apply link when LinkedIn exposes it to guests, otherwise `null`.                       |
| `detailScraped`                                                 | `false` when only listing data could be fetched (details disabled, posting removed or blocked). |
| `query`                                                         | The keywords and location that produced the job – handy when running several searches.          |

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

The Actor is charged for the compute it uses. With job details enabled, every 10 jobs cost 11 HTTP requests (one search page plus 10 postings) at roughly one second each, so a 1 GB run collects about **100 jobs per minute**:

- **100 jobs ≈ 0.02–0.04 compute units** over HTTP – well within the Apify free tier.
- **1,000 jobs ≈ 0.2–0.4 compute units**, plus proxy traffic (about 60 KB per job).

Turning **Scrape job details** off cuts the request count by about 90%. The browser fallback is considerably heavier (a Camoufox instance per concurrent request), which is why `auto` mode only uses it for the requests LinkedIn actually blocked.

### Tips for reliable LinkedIn scraping

- **Use residential proxies.** LinkedIn throttles datacenter IPs within a few hundred requests. Set the proxy group to `RESIDENTIAL` for anything beyond a small test.
- **LinkedIn caps every search at 1,000 results.** To collect more, split the search: several locations, tighter keywords, or `datePosted: "past24Hours"` on a daily schedule.
- **Schedule incremental runs.** `sortBy: "date"` with `datePosted: "past24Hours"` and a modest `maxItems` gives you a daily feed of new postings for a fraction of the cost of re-scraping everything.
- **Filter by company on LinkedIn's side** with `companyIds` whenever you know the IDs – it avoids fetching pages you would only throw away. Use `companyNames` when you don't.
- **Lower `maxConcurrency`** (to 2–3) if you see many `999` or `429` responses in the log.

### FAQ, disclaimers and support

**Is it legal to scrape LinkedIn jobs?** The Actor only reads pages LinkedIn serves to anonymous visitors and does not log in or collect data about individual people. Public data is generally scrapable, but you are responsible for complying with LinkedIn's terms, applicable law and how you use the output. Read Apify's [note on the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) if in doubt.

**Why do some items have `detailScraped: false`?** Either you disabled job details, the posting was removed between the listing and detail request, or LinkedIn blocked the detail page even after the browser fallback. The listing data (title, company, location, date) is still saved so you don't lose the lead.

**Why did I get fewer than `maxItems` jobs?** LinkedIn returned fewer results for that search (it never shows more than 1,000), or the company-name filter removed some. The run log shows how many were listed, de-duplicated and filtered.

**Can I scrape LinkedIn profiles or companies with this Actor?** No – it is deliberately limited to job postings. Profile scraping requires a login and raises privacy issues this Actor avoids.

Found a bug or need another field? Open an issue in the **Issues** tab of this Actor. Need a custom solution built around LinkedIn or other job boards? [Get in touch with Apify](https://apify.com/custom-solutions).

# Actor input Schema

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

Job titles, skills or company names to search for – anything you would type into the LinkedIn Jobs search box. Each entry runs as its own search and results are de-duplicated.

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

City, region or country exactly as you would type it into LinkedIn, e.g. <code>New York</code>, <code>Germany</code> or <code>European Union</code>.

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

Only return jobs posted within this time window.

## `jobTypes` (type: `array`):

Leave empty for all job types.

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

Leave empty for all experience levels.

## `workplaceTypes` (type: `array`):

Leave empty for on-site, remote and hybrid jobs alike.

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

Restrict the search to these companies using their numeric LinkedIn company IDs (LinkedIn's <code>f\_C</code> filter). Filter by company on linkedin.com/jobs and copy the number from the URL, e.g. <code>1441</code> for Google. This filters on LinkedIn's side, so no extra pages are fetched.

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

Only keep jobs whose company name contains one of these values (case-insensitive, e.g. <code>Amazon</code> also matches <code>Amazon Web Services</code>). Applied by the scraper after fetching, so it does not reduce the number of pages requested.

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

Order in which LinkedIn returns results. Sorting by date works well with a small <b>Maximum jobs</b> for daily monitoring.

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

Optional. Paste LinkedIn job search URLs (<code>linkedin.com/jobs/search?keywords=...</code> – all filters in the URL are preserved) or individual job posting URLs (<code>linkedin.com/jobs/view/...</code>). These are scraped in addition to the search defined above.

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

Stop after this many jobs have been saved across all searches. Use <code>0</code> for no limit. Note that LinkedIn never returns more than 1,000 results for a single search – split broad searches by location or date to get more.

## `geoId` (type: `string`):

LinkedIn's numeric location identifier (the <code>geoId</code> parameter visible in LinkedIn job search URLs, e.g. <code>103644278</code> for the United States). More precise than the free-text location and used together with it.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "location": "United States",
  "datePosted": "any",
  "jobTypes": [],
  "experienceLevels": [],
  "workplaceTypes": [],
  "sortBy": "relevance",
  "maxItems": 100
}
```

# 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": [
        "software engineer"
    ],
    "location": "United States"
};

// Run the Actor and wait for it to finish
const run = await client.actor("dtrungtin/linkedin-jobs-scraper-with-details").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": ["software engineer"],
    "location": "United States",
}

# Run the Actor and wait for it to finish
run = client.actor("dtrungtin/linkedin-jobs-scraper-with-details").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": [
    "software engineer"
  ],
  "location": "United States"
}' |
apify call dtrungtin/linkedin-jobs-scraper-with-details --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dtrungtin/linkedin-jobs-scraper-with-details"
        }
    }
}
```

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/QtB4aHnbEoLENzzrj/builds/h6R45HdfILIhDtMDf/openapi.json
