# LinkedIn Jobs Scraper | Details & Companies (`danthedataman/linkedin-job-atlas`) Actor

Export public LinkedIn jobs by title, location or URL with available descriptions, salary fields and optional company profiles. Deduplicate jobs and retain context.

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

## Pricing

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

### What you can export

Use this **LinkedIn jobs scraper** for role research and hiring analysis. Supply titles and locations, job/search URLs or supported company inputs to export deduplicated public guest jobs with available descriptions, salary fields and source context.

Optional company-profile reads add public company information. No LinkedIn login or uploaded CV is required; field availability and result coverage depend on the guest surfaces.

### Try the example input

The Console prefill searches Software Engineer in United States and returns up to three detailed jobs. API callers should send their own search; `{}` exits successfully with guidance and no LinkedIn reads or result rows.

```json
{
  "titles": [
    "Software Engineer"
  ],
  "locations": [
    "United States"
  ],
  "startUrls": [],
  "companyIds": [],
  "companyUrls": [],
  "companyNames": [],
  "mode": "detailed",
  "maxItems": 3,
  "maxRowsPerSearch": 0,
  "companyProfile": true,
  "datePosted": "anyTime",
  "easyApply": false,
  "under10Applicants": false,
  "geoId": "",
  "customUrlParams": {},
  "filters": {},
  "resumeKeywords": [],
  "splitByLocation": false,
  "splitCountry": "",
  "splitLocations": [],
  "splitTimeRanges": [],
  "splitCompanyIds": []
}
```

Run through the Apify API with your Actor ID:

```sh
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"titles":["Software Engineer"],"locations":["United States"],"maxItems":100}'
```

Read the resulting run’s default dataset as JSON, CSV or Excel. The output links also expose ERRORS, COVERAGE, SEARCH_TOTALS, METRICS and run-local STATE.

### Inputs

Omitted or null values use the runtime values below. Explicit empty arrays, false and zero are preserved. Schema prefill is a Console example; it is never an API default.

| Input | Type | Default | Meaning |
| --- | --- | --- | --- |
| `titles` | array | `[]` | Keywords; each title is paired with every location. |
| `locations` | array | `[]` | LinkedIn location hints; each is paired with every title. |
| `startUrls` | array | `[]` | LinkedIn job, search or company URLs; strings or objects containing url. Read together with structured searches. |
| `companyIds` | array | `[]` | Numeric LinkedIn organization IDs as strings. |
| `companyUrls` | array | `[]` | Public company root/jobs/about/posts URLs; resolve the canonical root to its numeric ID. |
| `companyNames` | array | `[]` | Exact company names; resolve uniquely from guest search and confirm the company root name. Ambiguity goes to ERRORS. |
| `mode` | string | `"detailed"` | quick reads cards; detailed adds full job descriptions and optional company profiles. |
| `maxItems` | integer | `1000` | Maximum unique delivered jobs across the run; 0 performs no reads. Maximum 100000. |
| `maxRowsPerSearch` | integer | `0` | Delivered-row cap per partition; 0 uses the 1000-card source window. Maximum 1000. |
| `companyProfile` | boolean | `true` | Join the public company root in detailed mode. Company identity/bound filters may still require a root read when false. |
| `datePosted` | string | `"anyTime"` | anyTime, past24Hours, pastWeek, pastMonth or r followed by positive seconds. Conservative observed-date post-check. |
| `easyApply` | boolean | `false` | Detailed only; require an explicit onsite-apply marker. Unknown is excluded. |
| `under10Applicants` | boolean | `false` | Detailed only; require an explicit applicant number below ten. Lower-bound captions are excluded. |
| `geoId` | string | `""` | LinkedIn geographic ID passed to the guest query. |
| `distance` | integer | `null` | Optional nonnegative distance hint in the guest query; units and nearby results are controlled by LinkedIn. |
| `customUrlParams` | object | `{}` | Supported guest parameters only: keywords, location, geoId, distance, f_TPR, f_C, f_AL, f_EA, sortBy; legacy f_WT/f_JT/f_E are translated to exact local filters. |
| `filters` | object | `{}` | Exact filters and dynamic flags described below; filters alone start a broad search. |
| `resumeKeywords` | array | `[]` | Local literal keyword/alias matching in full descriptions; no uploaded CV, model calls or external enrichment. |
| `splitByLocation` | boolean | `false` | Add capped partitions for distinct visible card locations; derived city rows must match the full observed location string. |
| `splitCountry` | string | `""` | With splitByLocation, replace each initial search location with this country hint; preserve derived city partitions. |
| `splitLocations` | array | `[]` | Additional location partitions preserving each initial query’s other constraints. |
| `splitTimeRanges` | array | `[]` | Additional time partitions, each r followed by positive seconds; preserve other constraints. |
| `splitCompanyIds` | array | `[]` | Additional numeric-company partitions preserving other constraints. |

#### Exact filters

`filters.workplaceTypes` accepts `Remote`, `Hybrid`, `On-site`; `employmentTypes` accepts `Full-time`, `Part-time`, `Contract`, `Temporary`, `Internship`, `Volunteer`, `Other`; `experienceLevels` accepts `Internship`, `Entry level`, `Associate`, `Mid-Senior level`, `Director`, `Executive`. These match explicit observed values, case-insensitively. Unknown values never pass. Generic mentions of remote benefits are not workplace proof. `industries` and `jobFunctions` require any requested phrase’s words in the corresponding criterion. `easyApply` and `under10Applicants` are equally strict. An applicant caption like “Be among the first 25 applicants” is a range, and cannot pass an under-ten filter.

`titleInclude` is an OR of phrases, each requiring all its words in any order. `titleExclude` rejects any such phrase. `skipJobIds` excludes exact IDs; `locationExclude` excludes case-insensitive substrings; `companyExclude` excludes exact case-insensitive employer names. All are string arrays. Quick mode supports these card-level filters and observed dates; detail-level filters and skill matching require detailed mode.

Legacy search-URL `f_WT`, `f_JT` and `f_E` codes are translated into these local labels, rather than trusting LinkedIn to enforce them. URL and global label constraints must overlap; derived partitions retain those constraints. Global date, easy-apply and under-ten requirements also apply to URL sources and individual jobs. A URL date window and global date window use the narrower requirement. These modifiers do not add an unrelated broad search when source inputs are present. Supported custom parameters configure structured searches; unknown parameters and filters are declined into ERRORS. LinkedIn keyword/location/distance/geoId inputs are search hints, not promises of exact text or geography. Supply title filters when exact role wording matters. Automatic observed-city partitions additionally require an exact full location-string match. Explicit location partitions retain LinkedIn’s nearby-result behavior.

#### Dynamic filters and skill matching

These `filters` set `dynamicFilterMatch` and **retain both matching and nonmatching jobs**: `jobFunctionInclude`/`jobFunctionExclude`, `jobIndustryInclude`/`jobIndustryExclude`, `companyOrganizationTypeInclude`/`companyOrganizationTypeExclude` (string arrays), `companySizeMin`/`companySizeMax`, `companyFoundedDateMin`/`companyFoundedDateMax`, `companyFollowersCountMin`/`companyFollowersCountMax` (nonnegative integers), and `excludeRecruitingAgencies`, `requireRecruiterProfile`, `requireSalaryInfo` (booleans). Include takes precedence over exclude for each pair. Unknown company facts pass that dynamic check; they are not silently guessed. Company size bounds apply to the exact observed employee count, never a size band.

```json
{"titles":["Engineer"],"locations":["Canada"],"maxItems":25,"filters":{"workplaceTypes":["Hybrid"],"titleExclude":["Sales Engineer"],"requireSalaryInfo":true},"resumeKeywords":[{"keyword":"C++","aliases":["CPP"]},{"keyword":"JavaScript","aliases":["JS"]}]}
```

Skill scoring checks literal keywords or aliases against description text with word boundaries. JS does not match JSON. This is a transparent text match, not an assessment of employability, semantic ranking or resume processing.

### Source modes and partitions

```json
{"startUrls":["https://www.linkedin.com/jobs/search/?keywords=Data%20Engineer&location=Canada",{"url":"https://www.linkedin.com/jobs/view/4419969671"},"https://www.linkedin.com/company/microsoft/jobs/"],"companyIds":["1035"],"companyNames":["Microsoft"],"maxItems":20}
```

Company URLs resolve their public root to a numeric organization ID. Company names must resolve uniquely to an exact name in a guest search and the company root; unresolved names go to ERRORS and never broaden into all jobs. A job URL must expose its own matching ID and a full description. Search cards may carry their own job link or a child full link; either form must match the card’s numeric job ID. Quick search mode reads cards without job-detail requests; company-filter identity checks may read a company root. Individual job URLs always require a detail read, including in quick mode.

```json
{"titles":["Engineer"],"locations":["United States"],"mode":"quick","maxItems":10000,"maxRowsPerSearch":1000,"splitLocations":["Canada","United Kingdom","Germany","France","India","Singapore","United Arab Emirates","Japan","Brazil","Australia"]}
```

Every search stops before the measured `start=1000` boundary. Ten or more populated capped partitions can supply 10,000 unique jobs; this is a run capacity, not guaranteed yield. Explicit location, time and company partitions preserve other query constraints and are added once to each initial search; time/company splits can overlap. Automatic location splitting discovers locations from visible cards; it is not a complete country or city inventory. All partitions deduplicate by job ID, with first-delivered query context retained. An initial structured query equivalent to a search URL shares one partition and uses structured context (`inputUrl` is empty), including after restart. COVERAGE states whether a partition ended on an empty page or hit a source/row/global/charge limit. SEARCH_TOTALS preserves the displayed total separately; it is not an expected final dataset size.

On an Apify migration/restart, the existing run dataset supplies delivered IDs and counts. STATE retains the pending partition queue and skips completed partitions; incomplete, uncapped partitions replay from offset zero and deduplicate delivered IDs. Row-capped partitions report row_cap without further target reads. Replayed coverage/totals replace their earlier partition record; earlier errors remain available. A partial detail, company or totals failure prevents a complete coverage claim. Resume is within one run, not between new runs or a change-feed mode. No error becomes a dataset row. Invalid/unresolved inputs and source failures are recorded in ERRORS; mixed-source runs can still deliver valid jobs. A run where every source attempt fails reports FAILED. A valid empty search/filter result exits successfully. `maxItems: 0` makes no target requests. Native PPE charge limits stop delivery and further source reads; at most an already-finished batch of eight enrichments precedes a binding push.

### Output

Every job has the same nullable shape in quick and detailed modes. Quick fields from cards remain populated; unavailable detail/company facts are null or empty arrays. Full descriptions, salary, poster, external apply and workplace fields depend on the public page. No missing fact is inferred. Applicant numbers can be lower bounds; source captions remain available. `applyUrl` is the public LinkedIn job landing page; `externalApplyUrl` is nullable when the guest route exposes no usable offsite target. Posting dates retain their observed precision; exact timestamps and expiry are not manufactured.

| Field | Meaning |
| --- | --- |
| `id` | LinkedIn job ID; deduplication and billing identity. |
| `jobUrl` | Canonical public job URL. |
| `title` | Observed job title. |
| `companyName` | Observed employer; verified root name when joined. |
| `companyUrl` | Canonical company root URL; null for absent or other employer-link families. |
| `companyId` | Verified organization ID, nullable without a join. |
| `companyLogo` | Public company/card logo URL. |
| `location` | Displayed location; not a geocoded address. |
| `locationParsed` | Nullable; no guessed geocoding. |
| `postedTime` | Observed relative posting-age caption. |
| `publishedAt` | Card time datetime, preserving source precision. |
| `postedAtTimestamp` | Nullable; no invented millisecond posting timestamp. |
| `benefits` | Visible card benefit/badge strings. |
| `hiringBadge` | Visible card hiring badge. |
| `isActivelyHiring` | True only from a visible actively-hiring badge; otherwise null. |
| `isEarlyApplicant` | True only from an explicit early-applicant badge; otherwise null. |
| `description` | Full public description as plain text. |
| `descriptionHtml` | Inner HTML of the full public description. |
| `applicantText` | Original applicant caption, including lower-bound qualifiers. |
| `applicantsCount` | Number in the caption; may be a lower bound, not an exact count. |
| `applyUrl` | Canonical LinkedIn job landing URL in both modes. |
| `externalApplyUrl` | Offsite application target exposed by an apply anchor or embedded applyUrl JSON comment; null for Easy Apply or when no usable offsite target is exposed. |
| `applyType` | EASY_APPLY for an onsite control; EXTERNAL with a usable offsite target; NOT_EXPOSED when details expose no usable offsite target; null when quick mode skips details. |
| `easyApply` | True for an onsite control; false for a usable offsite target; otherwise null. |
| `seniorityLevel` | Labeled job criterion. |
| `employmentType` | Labeled job criterion. |
| `jobFunction` | Labeled job criterion. |
| `industries` | Labeled job criterion. |
| `workplaceType` | Remote/Hybrid/On-site from an explicit role statement or title suffix; otherwise null. |
| `workRemoteAllowed` | True only for verified Remote; false for Hybrid/On-site; unknown null. |
| `salary` | Visible compensation text, otherwise null. |
| `salaryInfo` | Observed currency-and-amount strings. |
| `salaryMin` | Parsed visible minimum; no currency conversion. |
| `salaryMax` | Parsed visible maximum. |
| `salaryCurrency` | Explicit currency, otherwise null; bare $ is ambiguous. |
| `salaryPeriod` | Explicit hour/day/week/month/year period, otherwise null. |
| `salarySource` | Nullable; no guessed source. |
| `salaryInsights` | Nullable; no hidden insights fetched. |
| `expireAt` | Nullable; not exposed by the measured guest route. |
| `jobState` | CLOSED only when the source explicitly says no longer accepting; otherwise null. |
| `repostedJob` | True only when explicitly labeled reposted; otherwise null. |
| `verified` | Nullable; no guessed verification. |
| `insights` | Empty when unavailable. |
| `posterFullName` | Public recruiter card name, otherwise null. |
| `posterProfileUrl` | Public recruiter card link; its profile is never fetched. |
| `posterHeadline` | Public recruiter card headline. |
| `posterPhoto` | Public recruiter card image. |
| `contactEmail` | An email literally present in the job description; no contact enrichment. |
| `yearsOfExperience` | Literal English years-of-experience phrases with context. |
| `companyDescription` | Public Organization JSON-LD description. |
| `companyWebsite` | Labeled company website; never visited. |
| `companyEmployeeCount` | Exact public Organization numberOfEmployees, otherwise null. |
| `companySize` | Labeled size band, distinct from the exact count. |
| `companyFollowerCount` | Public follower count. |
| `companyIndustries` | Labeled company industry. |
| `companyTagline` | Public Organization JSON-LD slogan; null when absent. Distinct from industry and company description. |
| `companyHeadquarters` | Public Organization address object, otherwise null. |
| `companyHeadquartersText` | Labeled headquarters text. |
| `companyType` | Labeled organization type. |
| `companyFoundedYear` | Labeled founded year. |
| `companySpecialties` | Visible specialties. |
| `companyOfficeLocations` | Visible office-location strings, empty if absent. |
| `companyAffiliatedPages` | Visible affiliated-page names, empty if absent. |
| `companyRecentPosts` | Visible public post text, URL and source datePublished; dates may be incomplete. |
| `companySourceUrl` | Verified company root read URL. |
| `companyScrapedAt` | Company observation UTC. |
| `dynamicFilterMatch` | Combined dynamic-filter flag; does not remove rows. |
| `matchedKeywords` | Matched requested skill keywords. |
| `unmatchedKeywords` | Unmatched requested skill keywords. |
| `keywordMatchScorePercentage` | Matched keyword fraction × 100, rounded; null when no keywords. |
| `scrapingInfo` | Input URL, title, location, query, offset, page, index and partition key. |
| `sourceUrl` | Exact guest list/detail URL used for the row. |
| `scrapedAt` | Row observation UTC. |

### Access, limits and billing

The Actor uses ordinary anonymous HTTP on LinkedIn public guest search, detail and company roots. It uses Apify’s automatically allocated US datacenter proxy pool and up to eight concurrent reads. Company reads may reuse a successful sticky session for less than 50 seconds; classified blocks retire it and retry with fresh sessions, up to ten attempts with backoff capped at two seconds. Other reads use fresh sessions and at most three classified attempts with shared backoff for blocking/rate limits/transient failures. Redirects, unknown pages and absent identities are errors. Login-gated profile data, company employees, website crawling and residential fallback are outside this version.

One successfully delivered unique job is one native dataset-item billing event. Errors, totals, coverage and state are key-value-store records. See the Store Pricing tab for current pay-per-event prices and any Actor Start charge. Compute and proxy costs still depend on filters, retries and company diversity. METRICS response-body bytes are useful diagnostics, not an invoice or exact billable network traffic.

LinkedIn can change its guest surfaces, omit fields, cap results or block requests. The public route offers no exhaustive coverage or long-term reliability guarantee.

Guest pages may expose only a sign-in or join modal for an offsite application. Those account controls are not application destinations: externalApplyUrl stays null and applyType is NOT_EXPOSED. The Actor does not sign in or derive an application URL from a company website.

# Changelog

This Actor's version history is a separate document: https://apify.com/danthedataman/linkedin-job-atlas/changelog.md

# Actor input Schema

## `titles` (type: `array`):

Keywords; each title is paired with every location.

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

LinkedIn location hints; each is paired with every title.

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

LinkedIn job, search or company URLs; strings or objects containing url. Read together with structured searches.

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

Numeric LinkedIn organization IDs as strings.

## `companyUrls` (type: `array`):

Public company root/jobs/about/posts URLs; resolve the canonical root to its numeric ID.

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

Exact company names; resolve uniquely from guest search and confirm the company root name. Ambiguity goes to ERRORS.

## `mode` (type: `string`):

quick reads cards; detailed adds full job descriptions and optional company profiles.

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

Maximum unique delivered jobs across the run; 0 performs no reads. Maximum 100000.

## `maxRowsPerSearch` (type: `integer`):

Delivered-row cap per partition; 0 uses the 1000-card source window. Maximum 1000.

## `companyProfile` (type: `boolean`):

Join the public company root in detailed mode. Company identity/bound filters may still require a root read when false.

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

anyTime, past24Hours, pastWeek, pastMonth or r followed by positive seconds. Conservative observed-date post-check.

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

Detailed only; require an explicit onsite-apply marker. Unknown is excluded.

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

Detailed only; require an explicit applicant number below ten. Lower-bound captions are excluded.

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

LinkedIn geographic ID passed to the guest query.

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

Optional nonnegative distance hint in the guest query; units and nearby results are controlled by LinkedIn.

## `customUrlParams` (type: `object`):

Supported guest parameters only: keywords, location, geoId, distance, f_TPR, f_C, f_AL, f_EA, sortBy; legacy f_WT/f_JT/f_E are translated to exact local filters.

## `filters` (type: `object`):

Exact filters and dynamic flags described below; filters alone start a broad search.

## `resumeKeywords` (type: `array`):

Local literal keyword/alias matching in full descriptions; no uploaded CV, model calls or external enrichment.

## `splitByLocation` (type: `boolean`):

Add capped partitions for distinct visible card locations; derived city rows must match the full observed location string.

## `splitCountry` (type: `string`):

With splitByLocation, replace each initial search location with this country hint; preserve derived city partitions.

## `splitLocations` (type: `array`):

Additional location partitions preserving each initial query’s other constraints.

## `splitTimeRanges` (type: `array`):

Additional time partitions, each r followed by positive seconds; preserve other constraints.

## `splitCompanyIds` (type: `array`):

Additional numeric-company partitions preserving other constraints.

## Actor input object example

```json
{
  "titles": [
    "Software Engineer"
  ],
  "locations": [
    "United States"
  ],
  "startUrls": [],
  "companyIds": [],
  "companyUrls": [],
  "companyNames": [],
  "mode": "detailed",
  "maxItems": 3,
  "companyProfile": true,
  "datePosted": "anyTime",
  "customUrlParams": {},
  "filters": {},
  "resumeKeywords": [],
  "splitLocations": [],
  "splitTimeRanges": [],
  "splitCompanyIds": []
}
```

# Actor output Schema

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

No description

## `errors` (type: `string`):

Unresolved inputs, source reads and partial field-family failures; never dataset rows.

## `coverage` (type: `string`):

Per-partition status, scanned/delivered/rejected/duplicate counts, next offset and completeness.

## `searchTotals` (type: `string`):

Observed full-search displayed totals; not an exhaustive delivery count.

## `metrics` (type: `string`):

Response-body download bytes, decoded bytes, requests, retries and delivered rows.

## `state` (type: `string`):

Run-local persistent state for Apify migrations/restarts; not a cross-run feed.

# 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 = {
    "titles": [
        "Software Engineer"
    ],
    "locations": [
        "United States"
    ],
    "startUrls": [],
    "companyIds": [],
    "companyUrls": [],
    "companyNames": [],
    "mode": "detailed",
    "maxItems": 3,
    "maxRowsPerSearch": 0,
    "companyProfile": true,
    "datePosted": "anyTime",
    "easyApply": false,
    "under10Applicants": false,
    "geoId": "",
    "customUrlParams": {},
    "filters": {},
    "resumeKeywords": [],
    "splitByLocation": false,
    "splitCountry": "",
    "splitLocations": [],
    "splitTimeRanges": [],
    "splitCompanyIds": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("danthedataman/linkedin-job-atlas").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 = {
    "titles": ["Software Engineer"],
    "locations": ["United States"],
    "startUrls": [],
    "companyIds": [],
    "companyUrls": [],
    "companyNames": [],
    "mode": "detailed",
    "maxItems": 3,
    "maxRowsPerSearch": 0,
    "companyProfile": True,
    "datePosted": "anyTime",
    "easyApply": False,
    "under10Applicants": False,
    "geoId": "",
    "customUrlParams": {},
    "filters": {},
    "resumeKeywords": [],
    "splitByLocation": False,
    "splitCountry": "",
    "splitLocations": [],
    "splitTimeRanges": [],
    "splitCompanyIds": [],
}

# Run the Actor and wait for it to finish
run = client.actor("danthedataman/linkedin-job-atlas").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 '{
  "titles": [
    "Software Engineer"
  ],
  "locations": [
    "United States"
  ],
  "startUrls": [],
  "companyIds": [],
  "companyUrls": [],
  "companyNames": [],
  "mode": "detailed",
  "maxItems": 3,
  "maxRowsPerSearch": 0,
  "companyProfile": true,
  "datePosted": "anyTime",
  "easyApply": false,
  "under10Applicants": false,
  "geoId": "",
  "customUrlParams": {},
  "filters": {},
  "resumeKeywords": [],
  "splitByLocation": false,
  "splitCountry": "",
  "splitLocations": [],
  "splitTimeRanges": [],
  "splitCompanyIds": []
}' |
apify call danthedataman/linkedin-job-atlas --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,danthedataman/linkedin-job-atlas"
        }
    }
}
```

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/iT52A0kwhDKI7VO29/builds/b32gKjhefWFTfZcOH/openapi.json
