# LinkedIn Job Postings Scraper (`blueskyscraper/linkedin-job-postings-scraper`) Actor

Scrape LinkedIn job postings without login by keyword and location: title, company, location, posting date, seniority, employment type, industries, applicants, salary, full description, job poster and apply type. Filters for date, remote, job type, experience. Export, schedule or call via API.

- **URL**: https://apify.com/blueskyscraper/linkedin-job-postings-scraper.md
- **Developed by:** [BlueskyScraper](https://apify.com/blueskyscraper) (community)
- **Categories:** Jobs, Lead generation, Agents
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.70 / 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

**LinkedIn Job Postings Scraper** collects job postings from LinkedIn **without a login, cookies or an API key**: search by **keyword and location**, apply LinkedIn's own filters, and get one row per job with **title, company, location, posting date, seniority, employment type, industries, applicants, salary when posted, the full description, the job poster and the apply type** — plus **free company details**: website, industry, size, employees on LinkedIn, headquarters. **$1.6 per 1,000 jobs on the free plan, from $0.70 per 1,000 on paid plans. No start fee.**

### What is LinkedIn Job Postings Scraper?

A **LinkedIn jobs API** you do not have to apply for. LinkedIn has no public job-search API, so this Actor reads the public job pages LinkedIn shows to logged-out visitors and returns them as clean, flat rows you can open in Excel, Google Sheets or your own database.

- **Search like on LinkedIn:** keywords × locations, posted within (past hour, 24 hours, week, month), workplace (on-site, remote, hybrid), job type, experience level, distance, Easy Apply only, fewer than 10 applicants.
- **Paste a LinkedIn search URL** with your filters already set, or company pages and job links — all in one run.
- **Full job page for every result** — not just the search card.
- **Company details, free:** each hiring company's LinkedIn page is read once per run and its website, domain, industry, size, employees, followers, headquarters, founded year and description go on every row.
- **Only new jobs:** name the search and schedule it; each run returns only jobs not delivered before.
- **Optional contacts ($):** e-mails and phones written in the job post, and the hiring company's website e-mails and phones.

### What data can you get from LinkedIn job postings?

| Field | Example |
|---|---|
| `title` | Data Analyst |
| `company`, `companyUrl`, `companyLogo` | Confido, linkedin.com/company/confidotech |
| `location`, `workplaceType`, `isRemote` | New York, NY · hybrid |
| `postedAt`, `postedText` | 2026-09-28 · 4 days ago |
| `seniority`, `employmentType`, `industries` | Mid-Senior level · Full-time · Software Development |
| `applicants`, `applicantsText` | 200 · Over 200 applicants |
| `salaryText`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | $155,000/yr – $200,000/yr |
| `applyType` | easyApply or external |
| `posterName`, `posterTitle`, `posterProfileUrl` | the recruiter who posted the job, when LinkedIn shows them |
| `description` (+ `descriptionHtml` on request) | full job description |
| `jobId`, `url`, `query`, `queryLocation` | 4473018168 |
| `emails`, `phones`, `companyWebsite`, `companyEmails`, `companyPhones`, `companySocials` | with the Contacts options |
| `companyWebsite`, `companyDomain`, `companyIndustry`, `companySize` (+ `companySizeMin`/`Max`), `companyEmployeesOnLinkedIn`, `companyFollowers`, `companyHeadquarters`, `companyCity`, `companyCountry`, `companyFounded`, `companyType`, `companySpecialties`, `companyDescription`, `companyTagline` | **free company details** from the company's LinkedIn page, read once per run: venmo.com · Financial Services · 201-500 employees · 715 on LinkedIn · New York, NY |

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

| Event | Free plan | Paid plans (Bronze → Gold and up) |
|---|---|---|
| **Job** | $0.0016 ($1.6 per 1,000) | $0.0008 → $0.0007 |
| **Add-on: Contacts in the job post** — only on jobs where an e-mail or phone was found | $0.003 | $0.0027 → $0.0021 |
| **Add-on: Company website contacts** — once per company, only when an e-mail or phone was found | $0.008 | $0.0072 → $0.0056 |

No start fee and no proxy charge. Error rows, jobs skipped by your filters and jobs whose page LinkedIn did not show (`partial: true`) are free. **Maximum jobs per run** is a hard ceiling on the bill. Apify's free plan ($5 of monthly credit) covers about 3,000 jobs a month.

### How to scrape LinkedIn job postings

1. Click **Try for free** and sign in to Apify (free account, no card).
2. Type job titles in **Job titles or keywords** and places in **Locations**.
3. Set filters if you need them — posted within, workplace, job type, experience.
4. Click **Start**. Jobs appear in the table one by one; export them as Excel, CSV or JSON, or read them through the API.

In our test on Apify, 300 jobs for three keywords in the United States came back in under two minutes on the default 256 MB memory, every one with its full job page.

### ⬇️ Input

```json
{
    "keywords": ["data analyst", "data engineer"],
    "locations": ["New York, NY", "Chicago, IL"],
    "datePosted": "week",
    "experience": ["mid"],
    "maxJobsPerQuery": 200
}
```

#### Search with a LinkedIn URL

Set up a search on linkedin.com/jobs, copy the address and paste it into **LinkedIn search URLs**. Filters in the link (`f_TPR`, `f_WT`, `f_JT`, `f_E`, `f_AL`, `f_C`, `geoId`, `distance`) are kept.

#### Only new jobs every day

Put a name into **Only new jobs** (e.g. `nyc-data-jobs`) and schedule the Actor daily. Every run returns only the jobs that earlier runs with that name have not delivered — a job alert that lands in your sheet or Slack.

### ⬆️ Output

```json
{
    "type": "job",
    "jobId": "4473018168",
    "title": "Data Analyst",
    "company": "Confido",
    "location": "New York, NY",
    "postedAt": "2026-09-28T00:00:00.000Z",
    "postedText": "4 days ago",
    "workplaceType": null,
    "seniority": "Not Applicable",
    "employmentType": "Full-time",
    "industries": "Software Development",
    "applicants": 200,
    "applicantsText": "Over 200 applicants",
    "salaryText": "$155,000.00/yr - $200,000.00/yr",
    "salaryMin": 155000,
    "salaryMax": 200000,
    "salaryCurrency": "USD",
    "salaryPeriod": "year",
    "applyType": "external",
    "description": "The brands on your kitchen shelf are run by people doing extraordinary work…",
    "url": "https://www.linkedin.com/jobs/view/data-analyst-at-confido-4473018168",
    "companyUrl": "https://www.linkedin.com/company/confidotech",
    "query": "data analyst",
    "queryLocation": "New York, NY"
}
```

Every job row also carries the hiring company's details — free, on by default (**Company details**), null when LinkedIn did not open the company page. For a Venmo job:

```json
{
    "companyWebsite": "http://www.venmo.com",
    "companyDomain": "venmo.com",
    "companyIndustry": "Financial Services",
    "companySize": "201-500 employees",
    "companySizeMin": 201,
    "companySizeMax": 500,
    "companyEmployeesOnLinkedIn": 715,
    "companyFollowers": 69458,
    "companyHeadquarters": "New York, NY",
    "companyCity": "New York",
    "companyCountry": "US",
    "companyFounded": null,
    "companyType": "Public Company",
    "companySpecialties": [
        "Mobile Payments",
        "Social Payments",
        "P2P Payments"
    ],
    "companyTagline": null,
    "companyDescription": "At Venmo, we’re working to build a payment experience that's …"
}
```

### Use cases for LinkedIn jobs data

#### Job market and salary research

Count openings by title, city, seniority and industry; compare published salary ranges.

#### Recruiting and staffing lead generation

Companies that post jobs are companies that are hiring. Turn on the Contacts options to get their e-mails and phones, or use [LinkedIn Jobs Email Scraper](https://apify.com/blueskyscraper/linkedin-jobs-email-scraper).

#### Job boards and aggregators

Feed fresh LinkedIn postings into your own board with the only-new-jobs mode.

#### AI agents and RAG

Full descriptions as plain text make a ready corpus for matching CVs to jobs or answering "who is hiring for X in Y".

### Integrations and API

Run it from your own code with the Apify client — the dataset comes back as a list of jobs:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("blueskyscraper/linkedin-job-postings-scraper").call(run_input=INPUT)
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], job.get("company"), job.get("url"))
```

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('blueskyscraper/linkedin-job-postings-scraper').call(INPUT);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

- **No code:** schedule the Actor in Apify Console and send new jobs to Google Sheets, Slack, Airtable or e-mail.
- **n8n, Make, Zapier:** use the Apify app — "Run Actor" and "Get dataset items".
- **AI agents:** call it through the [Apify MCP server](https://mcp.apify.com) — `blueskyscraper/linkedin-job-postings-scraper`.
- **Webhooks:** get a call to your endpoint when a run finishes.

### ❓ FAQ

#### Is it legal to scrape LinkedIn jobs?

LinkedIn Job Postings Scraper reads only what LinkedIn shows any logged-out visitor on its public job pages: job posts, company names and the public name of the person who posted a job. It does not log in, does not use cookies and cannot see anything behind a login. Job posts are published to be read by as many people as possible, but names, e-mails and phone numbers are personal data under laws like the GDPR and CCPA — have a lawful reason to process them, and check LinkedIn's terms and your local law with a lawyer if in doubt.

#### Do I need a LinkedIn account, cookies or a proxy?

No. There is nothing to log in to and nothing to configure. The Actor chooses its own routes to LinkedIn; if LinkedIn turns a request away, it retries on another address by itself.

#### Can I use LinkedIn Job Postings Scraper with the Apify API?

Yes. Every run can be started through the [Apify API](https://docs.apify.com/api/v2) with a JSON input and returns a dataset you read as JSON, CSV, Excel or XML. See the code examples above.

#### Can I use it through an MCP server or an AI agent?

Yes. The Actor is available through the [Apify MCP server](https://mcp.apify.com) to Claude, ChatGPT, Cursor and other MCP clients, and AI agents can call it and pay per event with Apify's agentic payments. The input is plain JSON, every field has a description, and the output is flat, so an agent can call it without reading this page.

#### Can I integrate it with other apps?

Yes: Google Sheets, Make, n8n, Zapier, Slack, Airtable, webhooks and anything else through [Apify integrations](https://apify.com/integrations).

#### Why are some fields empty?

LinkedIn shows each field only when the employer filled it in. In our tests salary was published on about 15% of US jobs, and the job poster on 4% of a mixed sample (more often on recruiting and staffing jobs). The apply link of external jobs is no longer shown to logged-out visitors, so the Actor tells you the apply type (Easy Apply or external) instead.

#### How many jobs can I get?

LinkedIn lists about 1,000 jobs per search. For more, split the search: several locations, several keywords, or a date filter and a daily schedule. Repeated jobs across your searches are delivered once.

#### Do I pay for errors or empty results?

No. Error rows — a closed job, a company that does not exist, a search with no results — are free, and so is a job whose page LinkedIn did not show this time (`partial: true`).

### Your feedback

Found a field that is wrong or missing? Open an issue on the **Issues** tab — we answer every one.

### You might also like

| Actor | What it does |
|---|---|
| [LinkedIn Job Details Scraper](https://apify.com/blueskyscraper/linkedin-job-details-scraper) | Job URLs or IDs → full job postings |
| [LinkedIn Company Jobs Scraper](https://apify.com/blueskyscraper/linkedin-company-jobs-scraper) | Every open job of the companies you name |
| [LinkedIn Remote Jobs Scraper](https://apify.com/blueskyscraper/linkedin-remote-jobs-scraper) | Remote and work-from-home jobs only, by keyword and country |
| [LinkedIn Jobs Email Scraper](https://apify.com/blueskyscraper/linkedin-jobs-email-scraper) | Jobs with e-mails and phones of the hiring company and the job poster |

# Actor input Schema

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

What you would type into LinkedIn's job search: <code>data analyst</code>, <code>python developer</code>, <code>nurse</code>. Each keyword is searched in each location.

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

City, region or country as LinkedIn spells it: <code>New York, NY</code>, <code>London, England, United Kingdom</code>, <code>Germany</code>, <code>Worldwide</code>. Empty = LinkedIn's default (worldwide).

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

Paste a LinkedIn job search link with your filters already set (<code>https://www.linkedin.com/jobs/search/?keywords=designer\&location=Berlin\&f_TPR=r604800</code>). Job links and company links pasted here work too.

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

All open jobs of these companies. Paste a LinkedIn company URL (<code>https://www.linkedin.com/company/stripe</code>), the numeric company ID (<code>1441</code>) or just the name (<code>HubSpot</code>). Keywords, if given, narrow each company's jobs.

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

LinkedIn job links (<code>https://www.linkedin.com/jobs/view/4472178009</code>, links with <code>currentJobId=</code>) or bare job IDs (<code>4472178009</code>). Each becomes one full job row.

## `maxJobsPerQuery` (type: `integer`):

Cap for each keyword × location pair, each company and each search URL — not for the whole run. LinkedIn shows at most about 1,000 jobs per search; split big searches by location or date to get more.

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

LinkedIn's own date filter.

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

On-site, remote, hybrid — any combination. Empty = all.

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

Empty = all job types.

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

Empty = all levels.

## `radius` (type: `integer`):

LinkedIn's distance filter around a city: <code>5</code>, <code>10</code>, <code>25</code>, <code>50</code> or <code>100</code>. Empty = LinkedIn's default.

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

Only jobs you apply to on LinkedIn itself.

## `under10ApplicantsOnly` (type: `boolean`):

LinkedIn's "Under 10 applicants" filter: fresh jobs few people applied to.

## `excludeCompanies` (type: `array`):

Leave out jobs whose company name contains any of these words — e.g. staffing agencies: <code>Jobot</code>, <code>Robert Half</code>. Skipped jobs are free.

## `includeContacts` (type: `boolean`):

Find e-mail addresses and phone numbers written inside the job description (recruiters often add them). Charged only on jobs where at least one was found.

## `enrichCompanyContacts` (type: `boolean`):

Open each hiring company's LinkedIn page, take its website and read the home and contact pages: e-mails, phones and social links. Charged once per company, only when an e-mail or phone was found.

## `maxCompaniesToEnrich` (type: `integer`):

Ceiling for the company website lookup — each company is looked up once per run.

## `includeDescription` (type: `boolean`):

Full description, seniority, employment type, industries, applicants, job poster and apply type. Off = only what the search card shows (title, company, location, date, salary) — faster, same price.

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

Read each hiring company's LinkedIn page once per run and add its website and domain, industry, size, employees on LinkedIn, followers, headquarters, founded year, type, specialties, description and tagline to every job row. Free — no extra charge.

## `includeDescriptionHtml` (type: `boolean`):

Add <code>descriptionHtml</code> with LinkedIn's formatting (lists, bold).

## `onlyNewJobsStoreName` (type: `string`):

Give the search a name (e.g. <code>nyc-data-jobs</code>) and every later run with the same name returns <b>only jobs it has not delivered before</b>. Schedule it daily for a job alert. Empty = normal run.

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

Stop after this many jobs in the whole run — a hard ceiling on cost.

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

Leave as is: the Actor picks its own routes to LinkedIn. With your own proxy URLs, only those are used.

## Actor input object example

```json
{
  "keywords": [
    "data analyst"
  ],
  "locations": [
    "New York, NY"
  ],
  "maxJobsPerQuery": 20,
  "datePosted": "any",
  "easyApplyOnly": false,
  "under10ApplicantsOnly": false,
  "includeContacts": false,
  "enrichCompanyContacts": false,
  "maxCompaniesToEnrich": 100,
  "includeDescription": true,
  "includeCompanyDetails": true,
  "includeDescriptionHtml": false,
  "maxItems": 20000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `rows` (type: `string`):

One row per LinkedIn job; free error rows explain inputs that gave no jobs.

# 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 analyst"
    ],
    "locations": [
        "New York, NY"
    ],
    "maxJobsPerQuery": 20,
    "includeCompanyDetails": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("blueskyscraper/linkedin-job-postings-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 analyst"],
    "locations": ["New York, NY"],
    "maxJobsPerQuery": 20,
    "includeCompanyDetails": True,
}

# Run the Actor and wait for it to finish
run = client.actor("blueskyscraper/linkedin-job-postings-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 analyst"
  ],
  "locations": [
    "New York, NY"
  ],
  "maxJobsPerQuery": 20,
  "includeCompanyDetails": true
}' |
apify call blueskyscraper/linkedin-job-postings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,blueskyscraper/linkedin-job-postings-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/CruN22zvQ2KMhHsVy/builds/SP0ngeOGTLs7XSJiA/openapi.json
