LinkedIn Jobs Scraper avatar

LinkedIn Jobs Scraper

Pricing

from $1.12 / 1,000 result items

Go to Apify Store
LinkedIn Jobs Scraper

LinkedIn Jobs Scraper

LinkedIn jobs scraper with no login or cookies. Search LinkedIn job postings by keyword and location, filter by date posted, job type and seniority, and get title, company, location and posted date, plus the salary range and full description on demand. Monitor mode returns only new jobs.

Pricing

from $1.12 / 1,000 result items

Rating

0.0

(0)

Developer

Viktor Dubnytskiy

Viktor Dubnytskiy

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Categories

Security

Limited permissions

Share

Search LinkedIn job postings by keyword and location and get one flat row per job: title, company, company page, location, posted date, and on request the salary range, the full description, seniority level, employment type, job function and industries. No LinkedIn account, no cookies, no session to keep alive. Monitor mode turns the same search into an alert on new jobs.

Try it: the prefilled example returns 20 rows in about 10 seconds and costs about $0.03. Results cost $1.40 per 1,000.

What you get

Real rows from the example dataset, which is the prefilled input (queries: ["python developer", "data engineer"], location: "United States", 10 per keyword):

title / companylocationpostedquery / rank
Python Developer III / Bank of AmericaJersey City, NJ2026-10-18python developer / 10
Senior Python Backend Developer - Onsite / CognizantWashington, DC2026-10-30python developer / 9
Senior Data Engineer, DX / AtlassianSalt Lake City, UT2026-10-18data engineer / 1
Data Engineer, Amazon Security Experience / AmazonSeattle, WA2026-10-20data engineer / 5
Data Engineer III / DeloitteGreater Indianapolis2026-10-28data engineer / 2

One full row:

{
"id": "4475996626",
"jobId": "4475996626",
"url": "https://www.linkedin.com/jobs/view/4475996626/",
"title": "Senior Python Backend Developer - Onsite",
"company": "Cognizant",
"companyUrl": "https://www.linkedin.com/company/cognizant",
"location": "Washington, DC",
"postedAt": "2026-10-30",
"salary": null,
"workplaceType": "onsite",
"query": "python developer",
"rank": 9,
"detailsFetched": false
}

With includeDetails: true the same row also gets description, salary (when the employer publishes a pay range, e.g. $102,900.00/yr - $179,900.00/yr on the Bank of America posting), seniorityLevel, employmentType, industries and applicantsText.

Full row: id / jobId, url, title, company, companyUrl, location, postedAt, salary, workplaceType, query, rank, detailsFetched, scrapedAt, and with includeDetails: true also description, seniorityLevel, employmentType, jobFunction, industries, applicantsText.

id is LinkedIn's numeric job id, so a job found by two keywords is one row, and monitor mode tracks it across runs. Rows hold job and employer data only. No recruiter names, no poster profiles, no "who was hired" people.

Use cases

  • Daily job alert. One saved task per search ("queries": ["react developer"], "location": "Germany", "postedWithin": "24h") in monitor mode, scheduled every morning. Each run returns only the jobs that were not there yesterday.
  • Hiring signal for sales. Track which companies post roles in your niche ("data engineer", "SOC analyst") in your region, and act on the company / companyUrl list.
  • Market research. Pull a few hundred postings for a role and compare locations, seniority and employment types across countries.

Try it

Hit Start: the prefilled input searches python developer and data engineer in the United States, 10 jobs per keyword, 20 rows in total, search card fields only. Set includeDetails: true to add the description, salary range, seniority and employment type.

Monitor mode. Save the input as a task and set:

{
"mode": "monitor",
"monitorStateId": "python-germany-daily",
"queries": ["python developer"],
"location": "Germany",
"postedWithin": "24h",
"webhookUrl": "https://your-endpoint.example.com/hook"
}

Put the task on a schedule (Apify, Schedules, cron 0 7 * * * for daily). Each run compares against the previous one and returns only jobs whose id it has not seen before. A job does not come back because its applicant count grew or its text was edited. Point webhookUrl or the Telegram fields at your own channel to get the new jobs pushed to you.

Input

FieldMeaningDefault
queriesKeywords, one per line["python developer"]
locationCountry, region, city or metro area as typed on LinkedInUnited States
postedWithinany, 24h, week, monthany
jobTypefull-time, part-time, contract, temporary, internship, volunteer, otherall
experienceLevelinternship, entry, associate, mid-senior, director, executiveall
includeDetailsOpen each job page for description, seniority, employment type, job function, industriesfalse
maxResultsPerQueryStop each keyword after this many jobs100
strictQueryMatchSkip keywords LinkedIn answers with unrelated paddingtrue
maxItemsStop the whole run after this many rows100
modescrape, or monitor for new jobs onlyscrape
monitorStateId, webhookUrl, telegramBotToken, telegramChatIdMonitor-mode state key and alert targetsempty

Pricing

EventPrice
result$0.0014 per job ($1.40 per 1,000)
monitor-check$0.005 per monitor run
change$0.0014 per new job in monitor mode

Apify SILVER subscribers get 10% off these prices, GOLD and higher get 20% off. You pay only for rows actually pushed, and a search that finds nothing charges no result events. Apify platform usage (compute, and proxy traffic on the rare run that has to leave the free tier) is billed by Apify on top.

Found it useful? A short review on the Store page helps other people find this actor. If a search misbehaves, open an issue on the actor page.

Limits

  • LinkedIn shows a logged-out visitor at most about 1,000 jobs per search (100 pages of 10). For more, split the search by location or by keyword.
  • Of LinkedIn's own search filters only "Date posted" works for logged-out visitors. LinkedIn ignores the remote/hybrid, job type and experience filters for them, so jobType and experienceLevel are checked on each job page instead, which costs one extra request per job.
  • There is no remote/hybrid filter. workplaceType is filled only when the title or location says so explicitly ("100% Remote", "Hybrid"); LinkedIn does not print the workplace type on the public pages.
  • salary comes from the job page, so it needs includeDetails: true, and it appears only when the employer publishes a base pay range. US postings often do, most others do not.
  • jobFunction is filled only when LinkedIn prints a "Job function" line on the public job page. Most public pages show only seniority, employment type and industries, so expect it to be empty.
  • LinkedIn never returns an empty answer for a keyword it cannot match. With strictQueryMatch on, a keyword is skipped when no job on its first page names every significant word of it in the title or company (generic words such as "developer", "manager" or "senior" do not count on their own). Turn it off when your keyword and the job titles are in different languages.
  • With jobType or experienceLevel set, each keyword may open at most 5 job pages per row you asked for (5 x min(maxResultsPerQuery, maxItems), at least 50). A filter that almost nothing matches therefore stops the keyword after that budget instead of opening up to 1,000 job pages; LINKEDIN_STATS.detailBudgetHit lists the keywords where this happened.
  • E-mail addresses and phone numbers that recruiters type into the job text are removed from description.
  • LinkedIn rate-limits logged-out traffic. The actor paces its requests, retries a rate limit with backoff and moves to a datacenter, then a residential proxy only when the free tier keeps refusing. A run that is refused on every tier stops with blocked or rate_limited in the run summary instead of an empty dataset.

FAQ

Do I need a LinkedIn account or cookies? No. Every request is made as a logged-out visitor.

Why did my keyword return nothing? Either LinkedIn has no jobs for it in that location, or it padded the answer with unrelated jobs and strictQueryMatch skipped it. Both end as no_matches in the RUN_SUMMARY record of the run's key-value store; the skipped keywords are listed in LINKEDIN_STATS.skippedQueries and in the run log. A run that LinkedIn refused ends as blocked or rate_limited instead.

Can I search several locations? Run one task per location. A location is one LinkedIn search parameter, and splitting keeps each task's monitor state clean.

Changelog

  • 0.1: initial release with keyword and location search, date-posted filter, job type and seniority filters on job pages, optional job details, and monitor mode for new jobs.