LinkedIn Jobs Scraper: No Login, Full Details, $1.10/1K Jobs
Pricing
$1.10 / 1,000 jobs
LinkedIn Jobs Scraper: No Login, Full Details, $1.10/1K Jobs
Input: job keywords and a location, with filters for date posted, job type, experience level and on-site or remote work. Output: one JSON row per job with title, company, location, posted date, salary when shown, seniority, employment type and full description. No login. $1.10 per 1,000 jobs.
Pricing
$1.10 / 1,000 jobs
Rating
0.0
(0)
Developer
Sluicebox
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
3 days ago
Last modified
Categories
Share
Search public LinkedIn job listings by keyword and location, filter by date posted, job type, experience level and on-site or remote work, and get one clean JSON row per job: title, company, location, posted date, salary when shown, seniority, employment type, industries, applicant count, the full description as text and as HTML, and the job poster when LinkedIn shows one. Use only-new mode on a schedule to get just the listings that appeared since your last run.
It reads the same public job search and job pages LinkedIn serves to a visitor who is not logged in, over plain HTTP with no page rendering, no LinkedIn account and no cookies, at a fixed pace.
What you get
One row per job:
{"jobId": "4452633172","url": "https://www.linkedin.com/jobs/view/4452633172/","title": "Brand Marketing Manager","companyName": "Clermont Hotel Group","companyUrl": "https://uk.linkedin.com/company/clermont-hotel-group","location": "London, England, United Kingdom","postedAt": "2026-10-08","salary": null,"seniorityLevel": "Not Applicable","employmentType": "Full-time","industries": "Hospitality","applicantsText": "Over 200 applicants","descriptionText": "Clermont Hotel Group Central Support Office\n\nContract: Full Time\n\n...","descriptionHtml": "Clermont Hotel Group Central Support Office<br><br>Contract: Full Time<br><br>...","posterName": "Georgina Spacey","posterTitle": "Head of Resourcing at Clermont Hotel Group","posterProfileUrl": "https://uk.linkedin.com/in/georgina-spacey-a6b74824","searchKeyword": "marketing manager","searchLocation": "London","scrapedAt": "2026-10-22T06:48:12.345Z"}
salary is present only when LinkedIn shows a pay range on the job page (about one listing in ten
in our test searches). jobFunction is present only when the page lists it. posterName,
posterTitle and posterProfileUrl are null when the page shows no job poster (most listings:
about one in eight shows one). With Include full description off, a row holds only the search
card fields: jobId, url, title, companyName, companyUrl, location, postedAt, the
search keyword and location, and scrapedAt.
Input
| Field | Type | Description |
|---|---|---|
keywords | string[] | Job titles or skills, e.g. ["data engineer", "machine learning engineer"]. Each line is a separate search. |
location | string | A country, city or region as you would type it on LinkedIn, e.g. United States, London, Remote. Empty searches worldwide. |
datePosted | string | any (default), past24h, pastWeek or pastMonth. |
jobType | string[] | Any of fullTime, partTime, contract, temporary, internship, volunteer, other. Empty keeps all. |
experienceLevel | string[] | Any of internship, entry, associate, midSenior, director, executive. Empty keeps all. |
workplaceType | string[] | Any of onSite, remote, hybrid. Empty keeps all. |
maxItems | integer | Max jobs per search (default 100, hard cap 1,000). LinkedIn itself shows at most about 1,000 results for one search. |
includeDescription | boolean | Default true: read each job's page for the description, criteria, applicant count and job poster. false keeps only the search card fields and is about ten times faster. |
startUrls | array | Public LinkedIn job search URLs (linkedin.com/jobs/search?...) with the filters set on the site, as { "url": "..." } objects. Each URL is one more search. |
onlyNew | boolean | Default false. Skip jobs this Actor already gave you from the same searches in earlier runs. See Only new since last run. |
proxyConfiguration | object | Defaults to Apify datacenter proxies, which is the supported configuration. Residential proxies work too. |
Example:
{"keywords": ["data engineer"],"location": "United States","datePosted": "pastWeek","workplaceType": ["remote"],"maxItems": 200,"startUrls": [{ "url": "https://www.linkedin.com/jobs/search?keywords=data%20engineer&location=Canada&f_TPR=r604800" }]}
How to use it
- Click Try for free or Start on this page.
- Enter one or more job keywords and a location, pick the filters you need and set Max jobs per search.
- Run it. Jobs land in the dataset as one row each. Export them as JSON, CSV or Excel, or pull them over the API.
To watch a search on a schedule, use Apify Schedules with onlyNew: true. Pricing has no
per-run start fee, so a scheduled check costs exactly the rows it delivers. To call it from code,
use the Apify API or an official client. AI agents can call it
through the Apify MCP server: the description and the input fields above are written to be read
by an agent.
Only new since last run
Turn on Only new since last run (onlyNew: true) for monitoring. Here "new" means "not delivered
to you before from the same search", not "newer by date".
- Jobs you already got from a search are not written to the dataset and not charged.
maxItemscounts new rows only. LinkedIn orders search results by relevance, not by date, so a listing that is new to you can sit below listings you already have. The Actor therefore keeps paging until it has seen three pages in a row with nothing new, then stops. A quiet search costs three requests and no row charges.- The list of delivered jobs lives in a named key-value store in your own Apify account, called
linkedin-jobs-only-new-plus a code made from your searches (the run log shows the exact name). Each set of searches (keywords with their location and filters) gets its own store, so changing a keyword or a filter starts a fresh list for the set.maxItemsandincludeDescriptiondo not. The store does not expire. The latest 2,000 jobs per search are remembered. - The list is saved once, at the end of the run. If a run is aborted or times out, the list stays as it was, so the next run delivers again what that run had delivered. For the same reason, do not let two runs with the same input overlap.
- To start over, delete that store in Apify Console under Storage, Key-value stores.
Pricing
Pay-per-event, one event, nothing else:
| Event | Rate |
|---|---|
job-scraped | $1.10 per 1,000 ($0.0011 each), one per job row |
| Run start | free, there is no start event |
What you get for $1: 909 jobs. Platform usage (compute, proxy) is charged to us, not to you, so the per-row price is the whole bill. A row costs the same with or without the full description. A daily check of three searches that finds 40 new jobs costs $0.044, every day, with no per-run surcharge. Rates are as of the last README update. The Store page stays authoritative.
Limits (honest)
- Only what LinkedIn shows a logged-out visitor. The Actor reads public job search and job pages. It does not log in, so it never sees anything that needs an account: no Easy Apply details, no recruiter contact details, no profiles.
- About 1,000 results per search. LinkedIn stops paging a search near 1,000 results. For more jobs, split the input by location, date posted or other filters: each split is its own search with its own 1,000.
- LinkedIn's search decides what matches. The Actor returns what LinkedIn's own search shows for your keywords and location, in LinkedIn's order. It is not an exhaustive scan of every listing.
- Posted date is a date, not a time. LinkedIn states the posting date on the result card as a
day (
2026-10-08), sopostedAtis a date. - Salary and job poster only when shown. In our test searches LinkedIn showed a pay range on
about one listing in ten and a job poster on about one in eight. Where it shows neither, the fields
are
null. The description is saved as is: if an employer wrote a salary or a contact into the text, it stays in the text. - Text comes as plain text plus the original HTML.
descriptionTextkeeps paragraphs and list items.descriptionHtmlkeeps the formatting LinkedIn serves (bold, lists, line breaks). - A listing that disappears between the search and the job page (withdrawn or expired) is logged and skipped, not invented.
- No login, no captcha solving. If LinkedIn refuses a request, the Actor waits, switches to a fresh proxy session and retries. It fails honestly rather than fabricate data.
- If more than 5% of requests in a run fail, the run log says so loudly. A run in which every fetch failed is marked failed, not "succeeded with 0 items". A run whose filters legitimately match nothing still succeeds, with an empty dataset and an empty bill.
Rate-limit etiquette (built in, with numbers)
- One request every 2 seconds, about 30 per minute. One search page carries 10 jobs. With the full description on, 100 jobs are about 110 requests, under 4 minutes. With it off, 100 jobs are 10 requests, about 20 seconds.
- On an HTTP
429or999the Actor waits 15 seconds (then 30, then 45), switches to a fresh proxy session and retries, at most 3 times. On any other transient refusal it backs off (3 s, then 6 s, then 9 s) and retries the same way. - If five requests in a row fail after all retries, the run stops instead of grinding through the rest of the plan.
- The default run timeout is one hour, enough for about 1,500 jobs with descriptions in one run. For bigger inputs raise the timeout or split the input across runs.
FAQ
Do I need a LinkedIn account, cookies or an API key? No. The Actor reads only publicly available pages as a logged-out visitor, never logs in, and does not use anyone's credentials.
Can I filter by company or use LinkedIn's other filters?
Set the filters on LinkedIn's own job search page and paste the URL into startUrls. The Actor
keeps the filter parameters it recognises (keywords, location, date posted, job type, experience
level, workplace type, company, sort order, distance) and drops the paging and tracking ones.
Why are posterName and salary null for most jobs?
Because LinkedIn shows them on only a part of its listings. The Actor saves them when they are on
the page and null when they are not. It never guesses.
Can I get only new jobs for a saved search?
Yes. Keep the same keywords, location and filters, set onlyNew: true, and run the Actor on a
schedule. Each run returns only the jobs it has not delivered to you before.
Does it use a browser? No. Pages are fetched over plain HTTP and read straight from the HTML LinkedIn serves, with no rendering.
Where is my data stored? In your run's dataset on your Apify account, under your control. The Actor keeps no copy of scraped data outside your run and sends nothing to any third party. With Only new since last run on, it also keeps the ids of jobs it already gave you in a key-value store in your account (see above), so you can delete them at any time.
Legal
This is an unofficial scraper. It is not affiliated with, endorsed by, or connected to LinkedIn Corporation or Microsoft in any way. It reads only data that LinkedIn serves publicly to any logged-out visitor: no login, no credentials, no captcha solving. Website terms of service are a contractual matter between a website and its visitors, not criminal law. You are responsible for ensuring that your use of the collected data complies with the laws that apply to you and with LinkedIn's terms. Job descriptions belong to the employers who published them.
Personal data
A job listing is an employer's public advertisement. The only fields about a person are
posterName, posterTitle and posterProfileUrl: the name, headline and public profile link of
the person LinkedIn itself shows on the public job page as the job poster, saved only when LinkedIn
shows them. The Actor does not open profiles, does not look up emails or phone numbers, and performs
no enrichment. A description is saved as is: if an employer wrote a contact into it, that text stays
in the description and is not extracted into a field. Scraped data lives only in your own Apify
dataset and is not retained by us outside your run. If the data you collect contains personal data
under the laws of your jurisdiction (for example the GDPR), you act as its controller: it is your
responsibility to have a legal basis for processing and to honor data-subject requests, including
deletion.
Rate this Actor
If this Actor saved you time, a short rating or review on its Store page helps other people find it. Missing a field, or did something break? Open the Issues tab on this page and tell us.
Need a custom scraper?
We can build a custom version of this Actor, for example with extra fields, other filters or another output format, or a new Actor for a site we do not cover yet. It runs on Apify like this one. Email actorforge.hq+orders@gmail.com with the site, the data you need and how often you need it.
Other Actors by ActorForge
- Reddit Data Scraper: subreddit feeds, posts with their first comments, keyword search and user history in one Actor.
- Reddit Subreddit Scraper: the hot, new, top and rising posts of any subreddit, with date bounds and only-new mode.
- Reddit Comments Scraper: the whole comment thread of a post, with "more replies" branches and deep reply chains.
- Reddit Search Scraper: posts and comments matching keywords, across Reddit or inside one subreddit, with only-new mode.
- Reddit User Scraper: a user's public posts and comments, newest first, with the profile card.
- Lazada Reviews Scraper: product reviews, ratings and buyer media from all six Lazada marketplaces.
- Wildberries Scraper: products, prices and reviews from Wildberries as clean, schema-validated JSON.
- Avito Real Estate Scraper: full property inventory from Avito with freshness stamps.
Changelog
- 0.1 (October 2026): first release. Keyword and location search with date posted, job type, experience level and workplace filters, LinkedIn search URLs as input, full description with criteria, applicant count and job poster when shown, only-new mode, $1.10 per 1,000 jobs, no start fee.