# LinkedIn Jobs Scraper - Salaries, Applicants & Companies (`eiv/linkedin-jobs-scraper`) Actor

Scrape LinkedIn jobs by keyword, location, company or search URL: salary, applicants, seniority, job type, remote/hybrid, full description and company profile. Filters LinkedIn ignores are checked on every job and never charged. No login. From $0.60 per 1,000 jobs.

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

## Pricing

from $0.60 / 1,000 job scrapeds

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 Jobs Scraper** extracts job postings from **LinkedIn**: title, company, location, salary, applicants, seniority, employment type, remote or hybrid, the full description and, if you want it, the hiring company's profile. Search by keyword, location and company, or paste LinkedIn job-search, job and company URLs. No login, no API key, no browser, from **$0.60 per 1,000 jobs**.

```json
{
  "title": "Marketing Manager – Assurance Services",
  "companyName": "BDO Canada",
  "location": "Toronto, Ontario, Canada",
  "employmentType": "Full-time",
  "experienceLevel": "Not Applicable",
  "industries": "Financial Services",
  "salaryMin": 93000,
  "salaryMax": 141000,
  "salaryCurrency": "CAD",
  "salaryPeriod": "year",
  "postedAt": "2026-10-01T18:12:38.124Z",
  "applicantsCount": 200,
  "applyType": "EXTERNAL",
  "experienceYearsMin": 3,
  "companyWebsite": "http://www.bdo.ca",
  "companySize": "1,001-5,000 employees",
  "companyFollowers": 159801,
  "url": "https://www.linkedin.com/jobs/view/4459849626/"
}
```

**Measured on Apify: 1,000 jobs with full descriptions in 7.4 minutes; 150 jobs from 4 searches in 35 seconds.**

### What does LinkedIn Jobs Scraper do?

It runs LinkedIn's public job search for every keyword and location you give it, reads each job's full posting, and returns one clean row per job with more than 60 fields. LinkedIn's public search quietly ignores most of its own filters (job type, experience level, remote, industry, salary), so this scraper checks those filters on every posting itself and drops the jobs that do not match. **You never pay for a job a filter removed.**

- **Every way to search:** keywords x locations, companies by name, URL or id, pasted LinkedIn search URLs with their filters, single job URLs, and whole company job lists.
- **Filters that actually work:** job type, experience level, remote / hybrid / on-site, industry, minimum salary, maximum applicants, staffing agencies, title include / exclude, company and location exclude, company size, followers, type and founding year.
- **More data per job:** salary parsed into min / max / currency / period (also from the description text), applicants and applicants per day, years of experience asked for, contact emails, Easy Apply, closed jobs, city / region / country code, and the company's website, size, followers, headquarters address and recent posts.
- **Only new jobs:** schedule it daily and it returns, and charges for, only postings it has not returned before.
- **Past LinkedIn's 1,000-job ceiling:** "Split by city" runs a country-wide search in its main cities too.
- **Only pay for results.** Duplicates, filtered-out jobs, jobs seen in earlier runs and searches that fail are never charged.
- **Built for automation.** Run it on a schedule, call it from the API, or connect it to Make, Zapier, n8n, Google Sheets or an AI agent through Apify's MCP server.

### Why it is fast and cheap

LinkedIn's job pages work without an account. This scraper calls the same lightweight endpoints LinkedIn's own logged-out job search uses: one request returns 10 job cards, and one more request returns a job's full posting (about 9 KB compressed). No browser is started, so a run uses a fraction of the memory and time of browser-based scrapers. Requests are spread over several proxy addresses and slow down automatically when LinkedIn rate-limits, so long runs finish instead of failing halfway.

### What data can you extract from LinkedIn?

| Field | Example | What it is |
|---|---|---|
| `title`, `companyName`, `location` | `Senior Software Developer`, `JetBrains`, `Berlin, Berlin, Germany` | The job as posted |
| `workplaceType` | `Hybrid` | Remote, Hybrid or On-site, when the posting says so |
| `employmentType`, `experienceLevel` | `Full-time`, `Mid-Senior level` | From the posting's criteria |
| `industries` | `Software Development` | Industries on the posting |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | `165000`, `225000`, `USD`, `year` | Pay, from LinkedIn's salary box or the description; `salarySource` says which |
| `postedAt`, `postedTimeAgo` | `2026-10-02T11:00:00Z`, `1 hour ago` | When it was posted |
| `applicantsCount`, `applicantsPerDay` | `73`, `73` | How many have applied, and how fast |
| `applyType`, `easyApply`, `acceptingApplications` | `EXTERNAL`, `false`, `true` | How to apply, and whether it is still open |
| `description` | `If you want to build…` | Full text with line breaks and bullets (HTML on request) |
| `experienceYearsMin`, `contactEmails`, `benefits`, `insights` | `5`, `["jobs@acme.io"]`, `["401(k)"]`, `["Actively Hiring"]` | Extracted from the posting |
| `matchedSkills`, `missingSkills`, `skillMatchScore` | `["TypeScript"]`, `["Go"]`, `50` | Against your own skill list |
| `locationCity`, `locationRegion`, `locationCountry`, `locationCountryCode` | `Toronto`, `Ontario`, `Canada`, `CA` | The location split into parts |
| `companyId`, `companyUrl`, `companyLogo` | `12515`, `linkedin.com/company/jetbrains` | The hiring company on LinkedIn |
| `companyWebsite`, `companySize`, `companyEmployeeCount`, `companyFollowers`, `companyType`, `companyFounded`, `companyAddress*`, `companySpecialties`, `companyRecentPosts` | `https://www.jetbrains.com/`, `1,001-5,000 employees`, `3035` | With **Include company details** |
| `searchKeywords`, `searchLocation`, `searchPosition`, `searchUrl` | `Software Engineer`, `United States`, `1` | Which search found the job, and its rank |

### How to scrape LinkedIn jobs

1. Click **Try for free** and type your job titles into **Job titles or keywords** and your places into **Locations**, one per line. Or paste LinkedIn URLs into **LinkedIn URLs**.
2. Set any filters, and **Max results**. You pay per job, so this is also your cost cap.
3. Click **Start**. 100 jobs take about a minute.
4. Open the **Output** tab, or download the results as JSON, CSV, Excel or HTML.

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

You pay per job returned, and the price drops on higher Apify plans:

| Apify plan | Per 1,000 jobs |
|---|---|
| Free | $1.00 |
| Starter | $0.80 |
| Scale | $0.70 |
| Business | $0.60 |

- 1,000 software-engineering jobs in the United States with full descriptions cost **$0.80** on the Starter plan.
- A daily "only new jobs" monitor that finds 150 new postings a day costs about **$3.60 a month** on Starter.
- Company details, skill matching and every filter are included in the same price. Jobs a filter removes, duplicates and failed searches cost nothing.
- A run also costs **$0.00005** to start.
- The Free plan's $5 monthly credit covers about **5,000 jobs**.

### Input

```json
{
    "keywords": ["Data Analyst", "Product Manager"],
    "locations": ["London, United Kingdom", "Berlin"],
    "postedWithin": "week",
    "experienceLevels": ["entry-level", "associate"],
    "workplaceTypes": ["hybrid", "remote"],
    "includeCompanyDetails": true,
    "maxItems": 200
}
```

| Group | Fields | Notes |
|---|---|---|
| What to search | Job titles or keywords, Locations, Companies, LinkedIn URLs | Every keyword runs in every location; companies narrow every search, or list all their jobs when there are no keywords |
| Filters LinkedIn applies | Date posted (or posted within N hours), Easy Apply only, Fewer than 10 applicants, Sort by, Distance | Narrow the search itself, at no cost |
| Filters checked on every job | Job type, Experience level, Remote / hybrid / on-site, Industries, Exclude staffing agencies, Only jobs with a salary, Minimum salary, Max applicants, Title must / must not include, Exclude companies, Exclude locations, Skip job ids | Jobs they remove are never charged |
| Company filters | Company size, followers, type, founding year | Read the company page; turn on company details |
| Data to include | Include job details (on), Include description HTML, Include company details, Match my skills | Turn job details off for a fast list of titles, companies, locations and dates |
| Monitoring | Only new jobs, History name | Separate histories for separate monitors |
| Limits | Max results (100), Max results per search (1,000), Split by city | Max results is your cost cap |
| Proxy and performance | Proxy (Apify datacenter), Concurrency (8), Request timeout, Retries | Switch to residential only if a run is blocked |

### Output

Each job is one row in the dataset. The **Overview**, **Posting details** and **Companies** views show the key columns; every export includes all fields.

```json
{
  "recordType": "item",
  "id": "4459849626",
  "url": "https://www.linkedin.com/jobs/view/4459849626/",
  "title": "Marketing Manager – Assurance Services",
  "companyName": "BDO Canada",
  "location": "Toronto, Ontario, Canada",
  "workplaceType": null,
  "employmentType": "Full-time",
  "experienceLevel": "Not Applicable",
  "industries": "Financial Services",
  "salaryText": "$93,000 to $141,000",
  "salaryMin": 93000,
  "salaryMax": 141000,
  "salaryCurrency": "CAD",
  "salaryPeriod": "year",
  "salarySource": "description",
  "postedAt": "2026-10-01T18:12:38.124Z",
  "postedDate": "2026-10-01",
  "postedTimeAgo": "18 hours ago",
  "applicantsCount": 200,
  "applicantsText": "Over 200 applicants",
  "applicantsPerDay": 200,
  "applyType": "EXTERNAL",
  "easyApply": false,
  "acceptingApplications": true,
  "description": "Putting people first, every day\n\nBDO is a firm built on a foundation of positive relationships...",
  "experienceYearsMin": 3,
  "contactEmails": [],
  "insights": ["Actively Hiring"],
  "benefits": [],
  "locationCity": "Toronto",
  "locationRegion": "Ontario",
  "locationCountry": "Canada",
  "locationCountryCode": "CA",
  "companyId": "250145",
  "companyUrl": "https://www.linkedin.com/company/bdo-canada",
  "companyWebsite": "http://www.bdo.ca",
  "companyIndustry": "Financial Services",
  "companySize": "1,001-5,000 employees",
  "companyEmployeeCount": 4810,
  "companyFollowers": 159801,
  "companyHeadquarters": "Toronto, Ontario",
  "companyType": "Partnership",
  "companyFounded": 1921,
  "companyAddressStreet": "20 Wellington St E",
  "companyAddressCity": "Toronto",
  "companyAddressCountry": "CA",
  "searchKeywords": "marketing manager",
  "searchLocation": "Canada",
  "searchPosition": 1,
  "input": "https://www.linkedin.com/jobs/search/?keywords=marketing%20manager&location=Canada&f_TPR=r604800",
  "scrapedAt": "2026-10-02T12:12:38.151Z"
}
```

A search or URL that cannot be read becomes a row with `"recordType": "error"` and an `errorCode` instead of failing the whole run:

| `errorCode` | Meaning |
|---|---|
| `NOT_FOUND` | The job does not exist any more, or the link is wrong |
| `COMPANY_NOT_FOUND` | None of the companies you named were found on LinkedIn |
| `BLOCKED` / `RATE_LIMITED` | LinkedIn refused this address; run again, or switch the proxy to residential |
| `PARSE_FAILED` | LinkedIn changed its page; please report it on the Issues tab |

Error rows are never charged. The run summary (`RUN_SUMMARY` in the key-value store) shows how many jobs LinkedIn listed, how many your filters removed and how many duplicates were skipped.

### Tips and limits

- **About 1,000 jobs per search.** That is LinkedIn's own ceiling. For more, add more keywords or locations, or turn on **Split by city**.
- **LinkedIn always finds something.** Its AI search returns related jobs even for rare or misspelled keywords. Use **Title must include** when the title has to match.
- **Remote, hybrid and on-site** come from what the posting says (title, location or description), because LinkedIn's public pages do not show the structured value. Postings that say nothing get `null`, and the workplace filter drops them.
- **Salary** appears on most US postings (pay-transparency laws) and fewer elsewhere. "Only jobs with a salary" keeps just those.
- **Not public without a LinkedIn login:** the recruiter who posted the job, the employer's external apply link and LinkedIn's own skills list. No logged-out scraper can return them.
- **Applicants** are shown by LinkedIn as "Over 200" above 200, so `applicantsCount` stops at 200.
- **Company details** add one request per company (cached for the run), so they make a run slower, not more expensive.
- **Hit your spending limit?** The run stops cleanly at your maximum cost per run and keeps everything it collected. Raise the limit in the run options to get more.

### FAQ

#### Is it legal to scrape LinkedIn?

This Actor collects only job postings and company pages that LinkedIn shows publicly, without logging in. Job postings are published for anyone to read, but results can still contain personal data (for example an email address in a description), which laws such as the GDPR protect. Scrape personal data only for a legitimate purpose, and ask a lawyer if you are unsure. LinkedIn is a trademark of LinkedIn Corporation; this Actor is not affiliated with or endorsed by LinkedIn.

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

No. Nothing is logged in, so no account can be restricted or banned.

#### How do I monitor new LinkedIn jobs every day?

Save your input as a task, turn on **Only new jobs**, give it a **History name**, and add a daily schedule. Each run returns only postings no earlier run with that history name returned, and you pay only for those. Add **Posted within (hours)** = 24 to keep each run short.

#### Can I use it through the API or with Make, Zapier and n8n?

Yes. Every run can be started through the [Apify API](https://docs.apify.com/api/v2) and returns the dataset as JSON, CSV or Excel. Schedules, webhooks and integrations for Make, Zapier, n8n and Google Sheets are on the **Integrations** tab.

#### Can AI agents use it?

Yes. Agents connected to [Apify's MCP server](https://mcp.apify.com) can find and run this Actor as a tool, with the same per-job pricing. Plain inputs (keywords, locations, companies) make it easy for an agent to call.

#### Why did I get fewer results than I asked for?

The search may have fewer jobs than your limit, your filters may have removed many of them (the log and run summary say how many), the run may have reached your maximum cost per run, or LinkedIn's ceiling of about 1,000 jobs per search was reached. Nothing collected before that is lost.

### Related scrapers

- [Indeed Jobs Scraper](https://apify.com/eiv/indeed-jobs-scraper): the same kind of job data from Indeed, with salaries and company ratings.
- [Company Job Postings & Hiring Signals Scraper](https://apify.com/eiv/company-jobs-scraper): every open role straight from a company's own careers site (Greenhouse, Lever, Ashby and more).
- [Company Jobs & Salary Scraper](https://apify.com/eiv/job-postings-scraper): open roles and salary ranges from the job boards companies publish on.
- [LinkedIn Ad Library Scraper](https://apify.com/eiv/linkedin-ad-library-scraper): the ads a company runs on LinkedIn, with impressions and targeting.

### Support

Missing a field, or found a search that does not work? Open an issue on the **Issues** tab with the input you used, and it will be looked at quickly.

# Actor input Schema

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

What to search for, one search per line: a job title, skill or company name (e.g. "Data Analyst", "React developer"). Each line is searched separately in every location below. Leave empty to list all jobs in the locations, or all jobs at the companies.

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

Where to search, one per line: a country, region or city as you would type it on LinkedIn ("United States", "London, United Kingdom", "Berlin"), "Worldwide", or a numeric LinkedIn geoId. Every keyword is searched in every location. Leave empty for worldwide.

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

Only jobs at these companies: names ("Google"), LinkedIn company URLs (linkedin.com/company/openai) or numeric company ids, one per line. With keywords, every search is limited to these companies; without keywords, you get every open job at each company.

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

Paste LinkedIn URLs: a job search (linkedin.com/jobs/search?... with your filters applied), a single job (linkedin.com/jobs/view/...) or a company page (all its jobs). Also takes the URL list another Actor outputs.

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

Only jobs posted within this window. Applied by LinkedIn itself, so it costs nothing extra.

## `postedWithinHours` (type: `integer`):

A custom window in hours, e.g. 6 for jobs from the last 6 hours or 72 for the last 3 days. Overrides "Date posted" when set. Ideal for scheduled monitoring runs.

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

Only jobs you can apply to on LinkedIn with Easy Apply.

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

Only jobs that fewer than 10 people have applied to so far.

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

Result order. LinkedIn applies it only when it serves its classic search; its AI search, which most public visitors get, keeps its own relevance order.

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

Search radius around the location. Passed to LinkedIn, which applies it only on its classic search.

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

Keep only these employment types, checked against each job's own posting (LinkedIn's public search ignores this filter). Jobs that do not match are not charged.

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

Keep only these seniority levels as LinkedIn lists them on the posting. Many postings say "Not applicable"; select it too to keep those.

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

Keep only jobs whose title, location or description says they are remote, hybrid or on-site. Postings that do not say are dropped when this is set.

## `industries` (type: `array`):

Keep only jobs in these industries, as LinkedIn writes them on the posting ("Software Development", "Hospitals and Health Care", "Financial Services"). Partial words match.

## `excludeStaffingAgencies` (type: `boolean`):

Drop jobs whose posting lists the "Staffing and Recruiting" industry, i.e. jobs posted by recruiters for a client.

## `salaryOnly` (type: `boolean`):

Keep only jobs that state pay, either in LinkedIn's salary box or in the description.

## `minSalary` (type: `integer`):

Keep only jobs whose top of the stated range, converted to a yearly amount (hourly x 2,080, monthly x 12), reaches this, in the posting's currency. Jobs without a stated salary are dropped.

## `maxApplicants` (type: `integer`):

Keep only jobs with at most this many applicants so far, e.g. 50 for less competitive roles.

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

Keep only jobs whose title contains all the words of at least one of these phrases, in any order ("senior python" keeps "Senior Backend Engineer (Python)"). Checked before any posting is fetched.

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

Drop jobs whose title contains all the words of any of these phrases. Whole words: "senior" drops "Senior Engineer" but not "Seniority Analyst".

## `companyExcludes` (type: `array`):

Drop jobs from companies whose name contains any of these, as whole words ("Amazon" also drops "Amazon Web Services").

## `locationExcludes` (type: `array`):

Drop jobs whose location contains any of these, e.g. a city you do not want ("Laval").

## `skipJobIds` (type: `array`):

Job ids or job URLs to leave out, e.g. jobs you already have.

## `companyEmployeesMin` (type: `integer`):

Keep only jobs at companies with at least this many employees on LinkedIn. Turns on company details (one extra request per company). Companies that show no size are kept.

## `companyEmployeesMax` (type: `integer`):

Keep only jobs at companies with at most this many employees on LinkedIn, e.g. 200 for startups. Turns on company details.

## `companyFollowersMin` (type: `integer`):

Keep only jobs at companies with at least this many LinkedIn followers. Turns on company details.

## `companyFollowersMax` (type: `integer`):

Keep only jobs at companies with at most this many LinkedIn followers. Turns on company details.

## `companyTypes` (type: `array`):

Keep only jobs at these kinds of organisation, as LinkedIn labels them. Turns on company details.

## `companyFoundedAfter` (type: `integer`):

Keep only jobs at companies founded in or after this year, e.g. 2018 for young companies. Turns on company details.

## `companyFoundedBefore` (type: `integer`):

Keep only jobs at companies founded in or before this year. Turns on company details.

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

Fetch each job's full posting: description, employment type, experience level, industry, applicants, salary, apply type and benefits. Turn off for a fast list (title, company, location, date) at about one request per 10 jobs.

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

Also return the description as HTML (bullets, bold, links), next to the plain-text description. Roughly doubles the size of each row.

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

Add the hiring company's profile to each job: website, industry, size, employee and follower counts, headquarters address, type, founding year, specialties, description and recent posts. One extra request per company, reused for all its jobs.

## `matchSkills` (type: `array`):

Your skills, one per line, with optional aliases after commas ("JavaScript, JS"). Each job then lists the skills its title and description mention, the ones it does not, and a match score from 0 to 100.

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

Skip jobs that earlier runs with the same history name already returned, so a scheduled run returns, and charges for, new postings only. The job ids are kept in a key-value store on your account.

## `historyKey` (type: `string`):

Keeps separate "Only new jobs" histories for different monitors, e.g. "data-jobs-berlin". Letters, digits and dashes.

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

Stop after this many jobs in total. You pay per job, so this is also your cost cap for the run.

## `maxItemsPerSearch` (type: `integer`):

Stop after this many jobs from any single search (one keyword in one location). LinkedIn shows at most about 1,000 per search; use "Split by city" for more.

## `splitByCity` (type: `boolean`):

Get past LinkedIn's limit of about 1,000 jobs per search: a country-wide search also runs in the country's main cities (US, UK, Canada, Germany, France, India, Australia and 10 more). Duplicates are dropped and not charged.

## `addFiltersToKeywords` (type: `boolean`):

LinkedIn's AI search ignores the job type, experience and remote filters but understands words, so "Internship" or "Remote" is added to the keywords to get more matching jobs per page. Results are still checked on every posting.

## `extraSearchParams` (type: `array`):

Advanced: more query parameters for LinkedIn's job search, as key/value pairs (e.g. f\_JIYN = true). Sent as they are.

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

Apify datacenter proxy by default. If LinkedIn blocks or rate-limits a run, switch to the RESIDENTIAL group.

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

How many requests to LinkedIn run at the same time (and how many searches run in parallel). Lower it if you see rate-limit warnings.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for one response before giving up on it.

## `maxRetries` (type: `integer`):

Retries for blocked, rate-limited or failed requests, each from a new IP. Timeouts are not retried.

## Actor input object example

```json
{
  "keywords": [
    "Software Engineer"
  ],
  "locations": [
    "United States"
  ],
  "postedWithin": "any",
  "easyApplyOnly": false,
  "under10Applicants": false,
  "excludeStaffingAgencies": false,
  "salaryOnly": false,
  "includeDetails": true,
  "includeDescriptionHtml": false,
  "includeCompanyDetails": false,
  "onlyNewJobs": false,
  "historyKey": "default",
  "maxItems": 100,
  "maxItemsPerSearch": 1000,
  "splitByCity": false,
  "addFiltersToKeywords": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8,
  "requestTimeoutSecs": 30,
  "maxRetries": 3
}
```

# Actor output Schema

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

One row per job (recordType "item"), plus one uncharged row per search or URL that could not be read (recordType "error").

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

Totals for the run: searches, jobs delivered, jobs your filters removed, duplicates, requests and why the run stopped.

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

// Run the Actor and wait for it to finish
const run = await client.actor("eiv/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": ["Software Engineer"],
    "locations": ["United States"],
}

# Run the Actor and wait for it to finish
run = client.actor("eiv/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": [
    "Software Engineer"
  ],
  "locations": [
    "United States"
  ]
}' |
apify call eiv/linkedin-jobs-scraper --silent --output-dataset

```

## MCP server setup

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