AS
Apify Store
/cheap_scraper/linkedin-job-scraper
LinkedIn Jobs Scraper | Remove Duplicate Jobs | Pay Per Result
LinkedIn Jobs Scraper | Remove Duplicate Jobs. The LinkedIn jobs scraper allows you to collect jobs in 2 ways: By providing one or more start URLs, or By entering multiple keywords, search queries. Yo
liveasyncdegraded · 22.6s~30s typical
jobsdeveloper toolslinkedinjob
$0.00088
per result + $0.005 call
plus $0.001 platform fee per run
Actor charges $0.0007 per result; Cracked adds 25% plus a $0.005 call fee
Bring your own Apify Store key: provider portion drops to $0.
$Set up https://cracked-ai-pearl.vercel.app/SKILL.md, then use Cracked to run apify /cheap_scraper/linkedin-job-scraper for me.
Input
| Field | Type | Description |
|---|---|---|
| startUrls | array | One or more URLs of the pages where the crawler will start. Note that the Actor will additionally crawl job page data. |
| keyword | array | Keyword to search for. (e.g., Software Engineer) |
| locations | array | One or more locations to search in (e.g. Montreal, Canada). Each location is combined with every keyword to generate one search per pair. When set alongside the legacy Location field, both are merged. |
| location | string | Single location to search in. Use the Locations field instead to search multiple locations at once. |
| distance | string ( | 5 | 10 | 15 | 25 | 50) | Search radius from the location in miles. Leave empty for default. default "" |
| publishedAt | string ( | r86400 | r604800 | r2592000) | How old publications should be in Days. Default is ANY. default "" |
| jobType | array | Filter by job type (Full-time, Part-time, Contract, etc.). Multiple selections allowed. When LinkedIn serves its classic search engine this filter works normally. When LinkedIn serves its AI search engine the filter is ignored, so the scraper instead embeds it into the search query itself, which the AI search understands: the search is retried once with e.g. 'Full-time <keyword>' for a single selection or '(Full-time OR Contract) <keyword>' for multiple selections. |
| experienceLevel | array | Filter by experience level. Multiple selections allowed. When LinkedIn serves its classic search engine this filter works normally. When LinkedIn serves its AI search engine the filter is ignored, so the scraper instead embeds it into the search query itself, which the AI search understands: the search is retried once with e.g. 'Entry level <keyword>' for a single selection or '(Entry level OR Associate) <keyword>' for multiple selections. |
| workType | array | Filter by work location type (On-site, Remote, Hybrid). Multiple selections allowed. When LinkedIn serves its classic search engine this filter works normally. When LinkedIn serves its AI search engine the filter is ignored by LinkedIn and job pages have no field to verify it, so the scraper instead embeds the work type into the search query itself, which the AI search understands: the search is retried once with e.g. 'Remote <keyword>' for a single selection or '(Remote OR "On-Site") <keyword>' for multiple selections. |
| companyInclude | array | Restrict the search to specific companies. Add one company name per entry (e.g. Google, Shopify). Each name is resolved to a LinkedIn company ID and added to the search URL — LinkedIn will only return jobs from those companies. If a name cannot be matched, it is silently skipped. |
| filterUnder10Applicants | boolean | When enabled, LinkedIn will only return jobs with fewer than 10 applicants. Appends `f_EA=true` to the search URL. Keyword-based search only — does not affect URL-based search. default false |
| filterEasyApply | boolean | When enabled, LinkedIn will only return jobs that support Easy Apply (apply directly on LinkedIn without leaving the site). Appends `f_AL=true` to the search URL. Keyword-based search only — does not affect URL-based search. default false |
| subLocationExclude | array | Exclude jobs from specific cities or areas. Add each city name as a separate entry — any job whose location contains that name will be skipped (e.g. add "Laval" to exclude all jobs in Laval). Works independently of the Locations field. Also works with URL-based search. |
| companyExclude | array | Skip jobs from specific companies. Add one company name per entry — any job whose company name exactly matches (case-insensitive) will not be collected. Works for both keyword-based and URL-based searches. |
| jobTitleExclude | array | Skip jobs whose title contains any of these keywords (whole-word, case-insensitive). For example, entering "senior" will exclude "Senior Software Engineer" but not "seniority". Works for both keyword-based and URL-based searches. |
| jobFunctionInclude | array | Only keep jobs where the **job function** matches one of the selected values. **Note:** This takes priority over **Exclude Job Functions** when both are set. Jobs are still collected and counted toward billing. Use `dynamicFilterMatch` to filter them in your results. Non-matching jobs are saved with `dynamicFilterMatch: false`. Applies to both URL-based and keyword-based searches. Find all LinkedIn job functions here: [LinkedIn Job Function Codes](https://learn.microsoft.com/en-us/linkedin/shared/references/reference-tables/job-function-codes) |
| jobFunctionExclude | array | Exclude jobs whose **job function** matches any of the selected values. Only applies when "Include Job Functions" is not set. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. Non-matching jobs are saved with `dynamicFilterMatch: false`. Find all LinkedIn job functions here: [LinkedIn Job Function Codes](https://learn.microsoft.com/en-us/linkedin/shared/references/reference-tables/job-function-codes) |
| jobIndustryInclude | array | Only keep jobs where the **industry** matches one of the selected values. **Note:** This takes priority over **Exclude Industries** when both are set. Jobs are still collected and counted toward billing. Use `dynamicFilterMatch` to filter them in your results. Non-matching jobs are saved with `dynamicFilterMatch: false`. Find all LinkedIn industries here: [LinkedIn Industry Codes](https://learn.microsoft.com/en-us/linkedin/shared/references/reference-tables/industry-codes-v2) |
| jobIndustryExclude | array | Exclude jobs whose **industry** matches any of the selected values. Only applies when "Include Industries" is not set. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. You can find all the Linkedin industries at [LinkedIn Industry Codes](https://learn.microsoft.com/en-us/linkedin/shared/references/reference-tables/industry-codes-v2) |
| excludeRecruitingAgencies | boolean | When enabled, jobs posted by staffing and recruiting agencies will be flagged with `dynamicFilterMatch: false`. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results.` default false |
| companySizeMin | integer | Only keep jobs from companies with at least this many employees. Jobs that do not match are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out. |
| companySizeMax | integer | Only keep jobs from companies with at most this many employees. Jobs that do not match are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out. |
| companyOrganizationTypeInclude | array | Only keep jobs from companies whose LinkedIn company page organization type matches one of the selected values. Takes priority over "Exclude Company Organization Types" when both are set. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. Non-matching jobs are saved with `dynamicFilterMatch: false`. Full list of organization types at [LinkedIn Company Profile](https://learn.microsoft.com/en-us/linkedin/shared/references/fields/company-profile) |
| companyOrganizationTypeExclude | array | Flag jobs from companies whose LinkedIn company page organization type matches any of the selected values as `dynamicFilterMatch: false`. Only applies when "Include Company Organization Types" is not set. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. Full list of organization types at [LinkedIn Company Profile](https://learn.microsoft.com/en-us/linkedin/shared/references/fields/company-profile) |
| companyFoundedDateMin | integer | Only keep jobs from companies founded in or after this year. Jobs from companies whose founding year is not available always pass. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. |
| companyFoundedDateMax | integer | Only keep jobs from companies founded in or before this year. Jobs from companies whose founding year is not available always pass. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. |
| companyFollowersCountMin | integer | Only keep jobs from companies with at least this many LinkedIn followers. Jobs from companies whose follower count is not available always pass. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. |
| companyFollowersCountMax | integer | Only keep jobs from companies with at most this many LinkedIn followers. Jobs from companies whose follower count is not available always pass. Jobs are still collected and counted toward your billing — use `dynamicFilterMatch` to filter them out in your results. |
| requireRecruiterProfile | boolean | When enabled, only jobs that have a recruiter profile associated with the posting will have `dynamicFilterMatch: true`. Jobs without a recruiter profile are still collected and billed — use `dynamicFilterMatch` to filter them out. default false |
| requireSalaryInfo | boolean | When enabled, only jobs that include salary information in the posting will have `dynamicFilterMatch: true`. Jobs without salary info are still collected and billed — use `dynamicFilterMatch` to filter them out. default false |
| resumeKeywords | array | Each entry has a required `keyword` and optional `aliases` for abbreviations (e.g. `JavaScript` → `JS`). Each job in the output will include `matchedKeywords`, `unmatchedKeywords`, and `keywordMatchScorePercentage` (0–100). |
| maxItems | integer | Maximum number of job listings to scrape. Leave empty for no limit. Note: Minimum is 150 results when using pay-per-result billing. |
| saveOnlyUniqueItems | boolean | If enabled, only unique items will be saved. Default is false. default false |
| enrichCompanyData | boolean | When disabled, the scraper runs significantly faster by skipping additional company page requests. When enabled, the scraper fetches extra company details including: company description, full address (street, city, region, postal code, country), employee count, and company website. Default is disabled for optimal performance. default false |
| salaryBase | string ( | 40000 | 60000 | 80000 | 100000 | 120000) | Filter by minimum salary. Only one value allowed. 🛠️ In maintenance: this filter currently only works when LinkedIn serves its classic search engine. When LinkedIn serves its new AI-powered search, it silently ignores this filter, and since salary cannot be verified reliably from job postings, the scraper has no workaround - results will include jobs below this salary. It will be restored once LinkedIn supports it again. |
Call it
curl
curl https://cracked-ai-pearl.vercel.app/v1/run \
-H "Authorization: Bearer ck_live_..." -H "content-type: application/json" \
-d '{"provider":"apify","endpoint":"/cheap_scraper/linkedin-job-scraper","input":{"startUrls":[{"url":"https://www.linkedin.com/jobs/search/?f_TPR=r604800&geoId=100025096&keywords=data+scientist"}],"keyword":["Software Engineer"],"locations":["Montreal, Canada"],"publishedAt":"r86400","resumeKeywords":[{"keyword":"TypeScript","aliases":["TS","JS","JavaScript"]},{"keyword":"Node.js","aliases":["Node","NodeJS"]}],"maxItems":150},"wait":false}'poll
curl "https://cracked-ai-pearl.vercel.app/v1/runs/<runId>?wait=30" -H "Authorization: Bearer ck_live_..."cli
npx cracked-ai run -p apify -e /cheap_scraper/linkedin-job-scraper -i '{"startUrls":[{"url":"https://www.linkedin.com/jobs/search/?f_TPR=r604800&geoId=100025096&keywords=data+scientist"}],"keyword":["Software Engineer"],"locations":["Montreal, Canada"],"publishedAt":"r86400","resumeKeywords":[{"keyword":"TypeScript","aliases":["TS","JS","JavaScript"]},{"keyword":"Node.js","aliases":["Node","NodeJS"]}],"maxItems":150}' -w 120mcp
run_tool({ provider: "apify", endpoint: "/cheap_scraper/linkedin-job-scraper", input: {"startUrls":[{"url":"https://www.linkedin.com/jobs/search/?f_TPR=r604800&geoId=100025096&keywords=data+scientist"}],"keyword":["Software Engineer"],"locations":["Montreal, Canada"],"publishedAt":"r86400","resumeKeywords":[{"keyword":"TypeScript","aliases":["TS","JS","JavaScript"]},{"keyword":"Node.js","aliases":["Node","NodeJS"]}],"maxItems":150}, wait: false })Try it
Runs against your signed-in workspace balance. Sign in if you have not.