LinkedIn Jobs Scraper | AI Enrichment
Pricing
from $0.90 / 1,000 job results
LinkedIn Jobs Scraper | AI Enrichment
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.
LinkedIn Jobs Scraper | Remove Duplicates | AI Enrichment
Turn public LinkedIn jobs into clean, source-linked records for recurring alerts, job boards, databases, and automations. Search by role, location, freshness, and workplace arrangement; keep the posting details the source provides; and use cross-run deduplication so scheduled searches can return only jobs not already delivered for the same alert.
Optional features can fill missing description-backed facts, translate selected fields to English, or add facts from the public company page already linked by a job. The base source data always wins over optional enrichment.
This is an independent Actor. It is not affiliated with or endorsed by LinkedIn.
What you can build
- Daily or scheduled job alerts: rerun the same search and suppress jobs already delivered within that alert scope.
- Job-board and database feeds: store stable, source-linked records with complete descriptions when available, structured requirements, and application details.
- Automation and AI workflows: send clean records to n8n, Make, Airtable, MCP clients, webhooks, or your own API consumer.
Ready-made integrations: MCP · n8n · Make · Airtable · Claude / Codex skill
Why use this Actor
- One stable schema: every job uses the same
nomad-agent-job-v1shape, which also works with other normalized Nomad Agent job sources. - Rich job details: titles, companies, locations, workplace arrangements, dates, application links, requirements, skills, benefits, compensation, constraints, and complete descriptions when available.
- Source-faithful data: missing facts stay unknown, source-established empty lists stay empty, and optional enrichment never overwrites source facts.
- Precise selection: use LinkedIn search controls, strict normalized filters, physical-geography checks, and optional public company filters.
- Alert-friendly delivery: built-in cross-run deduplication can return only jobs not already delivered for the same search or alert scope.
- Integration-ready: export through Apify or use the API, MCP, n8n, Make, Airtable, webhooks, and the provided parsers.
What each result contains
Every item has exactly six top-level fields:
| Field | Meaning |
|---|---|
schemaVersion | Always nomad-agent-job-v1 |
identity | LinkedIn source, posting ID, and canonical job URL |
data | Normalized job, company, location, employment, application, requirement, benefit, compensation, and constraint fields |
custom | null, or a versioned public company-profile extension when requested and available |
llm | Status and provenance for optional description-backed enrichment |
raw | Complete description text and source HTML, or null when includeRaw is false |
All declared fields are present. null means unknown or unavailable. []
means the source explicitly established an empty collection. Consumers should
not treat those values as interchangeable.
Important accuracy rules:
- a location does not by itself prove that a job is on-site;
- only named people are returned as hiring contacts;
- the posting URL and an external application URL remain separate;
- optional AI fills only allowlisted fields that remain
nullafter source parsing; - raw HTML is untrusted source content and must be sanitized before rendering.
Work-arrangement evidence
workArrangements is both a LinkedIn search constraint and a normalized-field
filter. The Actor keeps the two meanings separate so the search does not invent
a job fact:
| Evidence for a returned job | Filter decision | data.employment.workArrangements |
|---|---|---|
| Explicit arrangement overlaps the request | Keep | Exact source or AI-filled value |
| Explicit arrangement contradicts the request | Exclude | Not returned |
Arrangement missing, but the job came from the matching LinkedIn f_WT request | Keep | null |
Arrangement missing without matching f_WT provenance | Exclude | null |
LinkedIn can apply a remote/hybrid union without identifying which member applies to an individual public job. In that case the job is eligible for the requested search, but its normalized arrangement remains unknown. Search eligibility does not turn an unknown per-job arrangement into a known fact. Description prose is not treated as source-confirmed evidence.
Input
| Field | Default | Purpose |
|---|---|---|
firstRunMode | false | Small evaluation mode: at most five jobs, Silver AI enrichment and English translation on, dedupe/raw/analytics off |
schemaVersion | required | Must be nomad-agent-job-search-input-v1 |
keyword | "" | Job title, skill, or role |
location | "" | City, region, country, or supported macro-region |
linkedinSearch | omitted | Up to eight keyword/location searches in one run |
postedWithin | "24h" | 1h, 24h, 7d, 30d, or any |
orderBy | "newest" | Final result order: newest or oldest |
workArrangements | omitted | Any combination of remote, hybrid, and onsite |
strictGeography | omitted | Require source-backed country, region, or city matches |
filters | omitted | Versioned filters over normalized job fields |
maxItems | 100 | Maximum returned jobs; 0 requests the bounded 1,000-item window |
dedupe | enabled | Suppress jobs already delivered in the same scope |
companyProfileEnrichment | false | Add source-backed facts from linked public company pages |
companyFilters | omitted | Filter on available public company-profile facts |
aiEnrichment | disabled | Fill selected missing facts from the complete description |
translateToEnglish | false | Translate selected normalized display fields |
includeRaw | true | Include complete description text and HTML |
analyticsEnabled | false | Share aggregate operational analytics with the Actor owner |
Unknown input fields are rejected. This prevents misspelled or retired options from silently changing the meaning of a run.
orderBy is a top-level normalized-Actor control. The separately versioned
linkedinSearch extension is now nomad-agent-linkedin-search-v2 and contains
only schemaVersion plus optional searches; legacy nested
linkedinSearch.orderBy is rejected.
First-run mode
The Apify console prefills firstRunMode: true for a small enriched first
result. The mode preserves your search terms, freshness, work-arrangement,
geography, and normalized/company filters, while applying these effective
settings before validation and billing:
maxItemsis capped at 5; a smaller explicit limit stays smaller;aiEnrichmentis forced to Silver andtranslateToEnglishis forced on;- cross-run deduplication is disabled so the evaluation can be repeated;
includeRawand anonymous analytics are disabled. Raw source content can still be used internally for requested enrichment and is then returned as top-levelraw: null.
AI enrichment and translation are separate paid events in addition to the base
result event. Start with a $0.10 Maximum cost per run; the cap can reduce or
stop output, and the Actor's Pricing tab is authoritative for current event
prices. Disable first-run mode after evaluation to use the explicit feature,
output, result-limit, and delivery settings below. API calls that omit the
field, or send false, retain the existing behavior.
{"schemaVersion": "nomad-agent-job-search-input-v1","firstRunMode": true,"keyword": "software engineer","location": "Spain","postedWithin": "24h"}
Example search
{"schemaVersion": "nomad-agent-job-search-input-v1","keyword": "software engineer","location": "Spain","postedWithin": "7d","workArrangements": ["remote", "hybrid"],"maxItems": 25,"dedupe": {"enabled": false, "key": ""},"aiEnrichment": {"enabled": false, "accuracy": "silver"},"translateToEnglish": false,"includeRaw": false,"analyticsEnabled": false}
Disable cross-run deduplication for repeatable one-off searches. Leave it
enabled for scheduled alerts, using a stable public key only when multiple
searches should intentionally share delivery history.
Optional features
Description-backed AI enrichment
Enable aiEnrichment with a silver or gold accuracy profile. The Actor
reads the complete plain-text job description and fills only supported fields
that static source parsing left null. Source facts and source-established
empty arrays always win. No customer model key is required, and an enrichment
failure leaves the base job unchanged with a failed status in llm.
When enrichment is enabled, normalized filtering is completed against the
source record plus supported fields filled by AI. This includes
data.employment.workArrangements: an AI-filled match can keep a job and an
AI-filled contradiction excludes it. AI provenance is recorded in llm; the
same words in a description never become static source evidence when AI is
disabled. Translation still happens after filtering and does not affect a
match.
{"aiEnrichment": {"enabled": true, "accuracy": "silver"}}
English translation
translateToEnglish: true translates selected normalized display fields that
are not already confidently English: title, classifications, domains,
applicant-requirement prose, benefits, eligibility and selection text, work
authorization, security clearance, and location preference. Descriptions,
company names, locations, identifiers, URLs, source-raw labels, skills,
qualifications, certifications, programme names, and provenance remain
unchanged. No customer translation key is required.
Public company profiles
companyProfileEnrichment: true can add exact public facts from the canonical
LinkedIn company page already linked by a job. Unavailable or unverifiable
profiles are fail-open when no company filter is requested: the complete base
job remains and custom is null. companyFilters can then select jobs by
supported company fields before the final result limit is applied.
Company filtering deliberately remains fail-closed. An unavailable or
unverified profile is unknown, not a verified profile whose individual
fields are null. With unknownPolicy: "exclude" (the default), its job is
excluded. With unknownPolicy: "abort", the run fails instead of returning a
row whose company predicate could not be evaluated. A verified profile with a
missing field is evaluated normally, including is_null and is_not_null.
Normalized filters
Use filters for versioned AND/OR expressions over supported normalized job
fields. Filters run on source-language values before optional output
translation. With AI enrichment disabled, unknown facts do not become guessed
matches. With enrichment enabled, predicates over supported AI-fillable fields
are finally evaluated using those enriched normalized fields; source facts
still take precedence.
{"filters": {"schemaVersion": "nomad-agent-job-filter-v1","expression": {"all": [{"field": "data.locations[].countryCode", "operator": "eq", "value": "ES"},{"field": "data.title", "operator": "not_contains", "value": "internship"}]}}}
Run with Python
from decimal import Decimalfrom apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("nomad-agent/linkedin-enrich-translate-normalize-scraper").call(run_input={"schemaVersion": "nomad-agent-job-search-input-v1","keyword": "data engineer","location": "Germany","postedWithin": "7d","maxItems": 25,}, build="latest", max_items=25, max_total_charge_usd=Decimal("0.10"))if not run["buildNumber"].startswith("1.0."):raise RuntimeError("unexpected Actor build")for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["data"]["title"], item["data"]["company"]["name"])
Pricing
The Actor uses pay-per-event pricing: one base event per confirmed job plus separate events only for optional translation or successful AI enrichment. Public company-profile enrichment has no separate event. Check the Apify Pricing tab before a paid run for the current prices, and use Apify's maximum-cost-per-run setting when you need a hard budget.
Limits
- Public LinkedIn pages can change, block requests, or omit fields.
- A run returns at most 1,000 jobs, even when
maxItemsis0. Large cold runs can take substantially longer and consume more compute. - Optional enrichment improves coverage but does not make unknown source facts certain or guarantee accuracy on every future posting.
- Cross-run deduplication affects delivery, not the identity or content of a job record.
Checking optional-feature outcomes
Optional features have observable per-row outcomes. For AI enrichment, inspect
llm.status and its provenance. For public company enrichment, a verified
profile is a versioned object in custom, while an unavailable profile is
custom: null. Minimal nomad-agent-run-summary-v4 under RUN-SUMMARY
reports only the public run outcome, delivered-item count, whether results were limited, and an
optional bounded retry recommendation. Source counters, diagnostics, errors,
and blocking reasons remain private. The summary does not turn a missing
per-row optional value into a known fact.
Privacy and removal
Contact the Actor creator through the Apify issue tab for privacy requests. For correction or source-removal requests, include the canonical public job URL or source job ID; do not post private credentials or unrelated personal data.
For lossless validation, table flattening, and integration examples, use the public integration repository.