# LinkedIn Jobs Scraper | AI Enrichment (`job-atlas/linkedin-enrich-translate-normalize-scraper`) Actor

Get up to 1,000 LinkedIn jobs per run with full descriptions and original links. Skip repeat jobs for alerts, job boards, and spreadsheets. Add AI enrichment and English translation when needed.

- **URL**: https://apify.com/job-atlas/linkedin-enrich-translate-normalize-scraper.md
- **Developed by:** [Job Atlas](https://apify.com/job-atlas) (community)
- **Categories:** Jobs
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 job 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

## LinkedIn Jobs Scraper | AI Enrichment

Get LinkedIn jobs ready for alerts, job boards, and spreadsheets. Search by role
and location, keep full descriptions and original job links, and skip jobs
already returned by earlier runs. Add AI enrichment or English translation when
you need them.

### Why choose this Actor?

- **Less cleanup:** consistent fields for titles, companies, locations, salaries,
  skills, and application links, when available.
- **Fewer repeat alerts:** built-in deduplication remembers jobs already delivered
  for the same search.
- **More useful details:** optional AI reads descriptions to fill missing facts
  without replacing source data.
- **Ready to connect:** export results or use the API, n8n, Make, Airtable, and MCP.

### Start with a small search

1. Enter a **Job keyword** and **Location**.
2. Set **Maximum results** to **5** and leave **First-run mode** and **Add company details** off for a basic search.
3. Set Apify's **Maximum cost per run** to **$0.10**, then click **Start**.
4. Open the results to review the jobs and export your data.

AI enrichment and translation are optional paid extras. The cost cap can reduce
or stop output; the **Pricing** tab is authoritative for current charges.

Want to try the extras? Enable **First-run mode** for up to five jobs with Silver
AI enrichment and selected-field English translation. It keeps your search and
filters, disables deduplication and analytics, and omits descriptions from the
output. Turn it off again to use your own settings.

### Choose your results

| Setting | Default / option | What it does |
|---|---|---|
| Job keyword / Location | — | Search for a role or skill in a city, region, or country. An empty location searches worldwide. |
| Posted within | — | Choose how recent the jobs should be. Default: past 24 hours. |
| Work arrangements | — | Select remote, hybrid, on-site, or any combination. Leave empty for all. |
| `maxItems` | `100` | Maximum jobs returned; up to 1,000 per run. `0` requests that limit. |
| Result order | — | Newest or oldest first. |
| Cross-run deduplication | — | Skip jobs already delivered. Turn off for repeatable one-off searches. |
| Include descriptions | — | Keep full text and HTML in `raw`. Turn off for smaller exports. |

For separate alerts, use separate deduplication keys. An empty key keeps history
separate for each search; reusing a named key shares history across those searches
within your account. Duplicate tracking is bounded, so it is not permanent history.

Advanced controls support up to eight searches per run, job-field filters, strict
location checks, and company filters. Use the examples in the input form's JSON
editors. Clear the main keyword and location when providing multiple searches.

### Optional extras

- **AI enrichment:** fills supported missing fields from the job description.
  Silver is the standard tier; Gold adds a second check. Use Silver until Gold
  appears in the current Pricing table. AI can make mistakes; review important facts.
- **English translation:** translates selected job fields, including titles,
  requirements, and benefits. Full descriptions, company names, locations, skills,
  and URLs stay in their original form.
- **Company details:** adds available facts from the job's linked public company
  page, with no separate result-event charge. Company filters require this option.
  Off by default. Unavailable profiles are excluded by default when company filters are used.

### What you get

Each job has its LinkedIn ID and URL, structured job details, optional company
facts and AI status, and the full description when requested. Missing facts remain
unknown; the Actor does not guarantee that every field will be filled.

The JSON format is `nomad-agent-job-v1`: `identity`, `data`, `custom`, `llm`,
`raw`, and `schemaVersion`. `null` means unknown; `[]` means confirmed empty.
A matching workplace search can still return an unknown per-job arrangement.
Sanitize source HTML before displaying it.

### Use the API or an integration

```python
from decimal import Decimal
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor(
    "job-atlas/linkedin-enrich-translate-normalize-scraper"
).call(run_input={
    "schemaVersion": "nomad-agent-job-search-input-v1",
    "keyword": "software engineer",
    "location": "Spain",
    "maxItems": 5,
    "firstRunMode": False,
    "aiEnrichment": {"enabled": False, "accuracy": "silver"},
    "translateToEnglish": False,
    "companyProfileEnrichment": False,
    "analyticsEnabled": False,
    "dedupe": {"enabled": False, "key": ""},
}, build="latest", max_items=5, max_total_charge_usd=Decimal("0.10"))

if run["status"] != "SUCCEEDED" or not run.get("buildId") or not run.get("buildNumber"):
    raise RuntimeError("Actor run failed or omitted its resolved build identity")

for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["data"]["title"], job["identity"]["url"])
```

This standalone example follows `latest`. Check the [current default build API](https://api.apify.com/v2/acts/job-atlas~linkedin-enrich-translate-normalize-scraper/builds/default)
for the default build number and immutable ID. Maintained integration templates
use `latest`; follow the selected template's compatibility
guide when running it. A `1.0.x` check alone does not prove compatibility.

[Integration guides and templates](https://github.com/Exdenta/nomad-agent-job-scrapers)
cover MCP, n8n, Make, Airtable, and agent skills.

### Pricing and limits

You pay per returned job, plus applicable translation and successful AI-enrichment
charges. Check the **Pricing** tab for current rates and scheduled changes.

Results depend on available public LinkedIn postings. Filters, source restrictions,
and your budget can reduce the count. Large searches take longer. Check
`RUN-SUMMARY` for the returned count, limits, and any retry suggestion; check
`llm.status` for each job's AI outcome. Strict location and company filters can
exclude jobs with missing evidence.

This independent Actor is not affiliated with or endorsed by LinkedIn.
Contact the Actor creator through the Apify issue tab for help or privacy requests.
For corrections or removal, include the job URL or ID and avoid private information.

### Job Atlas

Explore the Job Atlas job-data and matching Actors. Use `latest` and retain the immutable build ID returned by each run.

- [Linkedin](https://apify.com/job-atlas/linkedin-enrich-translate-normalize-scraper)
- [Euraxess](https://apify.com/job-atlas/euraxess-enrich-translate-normalize-scraper)
- [YC](https://apify.com/job-atlas/ycombinator-enrich-translate-normalize-scraper)
- [Scorer](https://apify.com/job-atlas/ai-job-fit-scorer)

[Website and integration guides](https://nomadagent.dev/) | [Source and client examples](https://github.com/Exdenta/nomad-agent-job-scrapers)

# Actor input Schema

## `firstRunMode` (type: `boolean`):

Try up to five jobs with Silver AI enrichment and translate selected fields to English. Paid extras apply. Keeps your search and filters; disables deduplication and analytics and omits descriptions. Turn off to use your own settings.

## `keyword` (type: `string`):

Job title or skill, such as software engineer or Python. Leave empty to search all roles in your chosen location.

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

City, region, or country, such as London, Spain, or European Union. Leave empty for worldwide results.

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

Choose how recent the jobs should be. Any time removes this filter.

## `orderBy` (type: `string`):

Sort matching jobs by posting date. Jobs with unknown dates appear last.

## `workArrangements` (type: `array`):

Select remote, hybrid, on-site, or a combination. Leave empty for all. A matching search may return jobs whose individual arrangement is unknown; explicitly conflicting arrangements are excluded.

## `linkedinSearch` (type: `object`):

Combine up to eight keyword/location searches and remove duplicate jobs. Leave empty to use the main search. Clear the main keyword and location when supplying multiple searches.

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

Filter job fields with AND/OR rules. Filters use original-language values and any supported facts added by AI. Use the JSON example to start.

## `strictGeography` (type: `object`):

Require a country, region, or city confirmed by the source. All conditions must match the same location. Jobs with unknown locations are excluded by default; you can choose to stop the run instead.

## `companyProfileEnrichment` (type: `boolean`):

Add available facts from the public company page linked to a job. No separate event charge. If the page is unavailable, keep the job without company details unless company filters apply.

## `companyFilters` (type: `object`):

Filter by company facts. Requires Add company details. Unavailable or unverified profiles are excluded by default, even for missing-field checks; choose abort to stop the run instead.

## `aiEnrichment` (type: `object`):

Fill supported missing fields from the description. Source facts are preserved. AI-filled fields can affect job filters. Failed enrichment leaves the base data unchanged. Paid extra; see Pricing. No API key needed.

## `translateToEnglish` (type: `boolean`):

Translate selected fields, including titles, requirements, and benefits. Descriptions, company names, locations, skills, qualifications, certifications, programme names, IDs, URLs, source labels, and AI metadata stay unchanged. Paid extra; see Pricing. No translation key needed.

## `includeRaw` (type: `boolean`):

Include full description text and HTML in raw. Turn off for smaller exports; AI enrichment still works. First-run mode omits descriptions.

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

Return up to this many jobs, with a maximum of 1,000 per run. Set 0 to request 1,000. First-run mode caps results at five. Large searches take longer; filters and budget may reduce the count.

## `dedupe` (type: `object`):

Avoid repeat jobs in recurring searches. An empty key keeps each search separate. A named key shares history across searches using that key within your account. Turn off for repeatable one-off searches.

## `analyticsEnabled` (type: `boolean`):

Optionally share aggregate run statistics to help improve reliability. Excludes account and run IDs, searches, job data, URLs, credentials, and persistent caller identifiers.

## `schemaVersion` (type: `string`):

Keep this value unchanged. It identifies the input format expected by the Actor.

## Actor input object example

```json
{
  "firstRunMode": false,
  "keyword": "frontend developer typescript",
  "location": "Germany",
  "postedWithin": "24h",
  "orderBy": "newest",
  "workArrangements": [
    "remote"
  ],
  "linkedinSearch": {
    "schemaVersion": "nomad-agent-linkedin-search-v2",
    "searches": [
      {
        "keyword": "frontend engineer",
        "location": "Spain"
      },
      {
        "keyword": "typescript developer",
        "location": "European Union"
      }
    ]
  },
  "filters": {
    "schemaVersion": "nomad-agent-job-filter-v1",
    "expression": {
      "all": [
        {
          "field": "data.title",
          "operator": "not_contains",
          "value": "manager"
        },
        {
          "field": "data.employment.workArrangements",
          "operator": "overlaps",
          "value": [
            "remote",
            "hybrid"
          ]
        }
      ]
    }
  },
  "strictGeography": {
    "schemaVersion": "nomad-agent-linkedin-strict-geography-v1",
    "countries": [
      "ES"
    ],
    "regions": [
      "Catalonia"
    ],
    "cities": [
      "Barcelona"
    ],
    "unknownPolicy": "exclude"
  },
  "companyProfileEnrichment": false,
  "companyFilters": {
    "schemaVersion": "nomad-agent-linkedin-company-filter-v1",
    "expression": {
      "all": [
        {
          "field": "industry",
          "operator": "contains",
          "value": "software"
        },
        {
          "field": "employeeCountRange.minimum",
          "operator": "gte",
          "value": 50
        }
      ]
    },
    "unknownPolicy": "exclude"
  },
  "aiEnrichment": {
    "enabled": true,
    "accuracy": "silver"
  },
  "translateToEnglish": false,
  "includeRaw": true,
  "maxItems": 100,
  "dedupe": {
    "enabled": true,
    "key": "default"
  },
  "analyticsEnabled": false,
  "schemaVersion": "nomad-agent-job-search-input-v1"
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (type: `string`):

See how many jobs were returned, whether results were limited, and any retry suggestion.

# 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 = {
    "firstRunMode": false,
    "keyword": "Software Engineer",
    "location": "Germany",
    "postedWithin": "24h",
    "orderBy": "newest",
    "workArrangements": [
        "remote"
    ],
    "linkedinSearch": {
        "schemaVersion": "nomad-agent-linkedin-search-v2",
        "searches": []
    },
    "filters": {
        "schemaVersion": "nomad-agent-job-filter-v1",
        "expression": {
            "field": "identity.source",
            "operator": "eq",
            "value": "linkedin"
        }
    },
    "companyProfileEnrichment": false,
    "aiEnrichment": {
        "enabled": false,
        "accuracy": "silver"
    },
    "translateToEnglish": false,
    "includeRaw": true,
    "maxItems": 100,
    "dedupe": {
        "enabled": true,
        "key": "default"
    },
    "analyticsEnabled": false,
    "schemaVersion": "nomad-agent-job-search-input-v1"
};

// Run the Actor and wait for it to finish
const run = await client.actor("job-atlas/linkedin-enrich-translate-normalize-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 = {
    "firstRunMode": False,
    "keyword": "Software Engineer",
    "location": "Germany",
    "postedWithin": "24h",
    "orderBy": "newest",
    "workArrangements": ["remote"],
    "linkedinSearch": {
        "schemaVersion": "nomad-agent-linkedin-search-v2",
        "searches": [],
    },
    "filters": {
        "schemaVersion": "nomad-agent-job-filter-v1",
        "expression": {
            "field": "identity.source",
            "operator": "eq",
            "value": "linkedin",
        },
    },
    "companyProfileEnrichment": False,
    "aiEnrichment": {
        "enabled": False,
        "accuracy": "silver",
    },
    "translateToEnglish": False,
    "includeRaw": True,
    "maxItems": 100,
    "dedupe": {
        "enabled": True,
        "key": "default",
    },
    "analyticsEnabled": False,
    "schemaVersion": "nomad-agent-job-search-input-v1",
}

# Run the Actor and wait for it to finish
run = client.actor("job-atlas/linkedin-enrich-translate-normalize-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 '{
  "firstRunMode": false,
  "keyword": "Software Engineer",
  "location": "Germany",
  "postedWithin": "24h",
  "orderBy": "newest",
  "workArrangements": [
    "remote"
  ],
  "linkedinSearch": {
    "schemaVersion": "nomad-agent-linkedin-search-v2",
    "searches": []
  },
  "filters": {
    "schemaVersion": "nomad-agent-job-filter-v1",
    "expression": {
      "field": "identity.source",
      "operator": "eq",
      "value": "linkedin"
    }
  },
  "companyProfileEnrichment": false,
  "aiEnrichment": {
    "enabled": false,
    "accuracy": "silver"
  },
  "translateToEnglish": false,
  "includeRaw": true,
  "maxItems": 100,
  "dedupe": {
    "enabled": true,
    "key": "default"
  },
  "analyticsEnabled": false,
  "schemaVersion": "nomad-agent-job-search-input-v1"
}' |
apify call job-atlas/linkedin-enrich-translate-normalize-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,job-atlas/linkedin-enrich-translate-normalize-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/KMflYVTHiIAXE6nKN/builds/Pny0KQh791X7UJ9nq/openapi.json
