# Changelog of 💼 LinkedIn Jobs Scraper - Salary & Recruiter Data (`dz_omar/linkedin-jobs-scraper`) Actor

- **URL**: https://apify.com/dz_omar/linkedin-jobs-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/dz_omar/linkedin-jobs-scraper.md

## Changelog

All notable changes to the LinkedIn Jobs Scraper.

### \[0.2.5] — 2026-09-20

#### Changed

- **Now pay-per-event.** One event, `job-scraped`, charged per job delivered: $0.0007 on the free plan, $0.0006 Bronze, $0.0005 Silver, $0.00045 Gold and above. Previously free.
- **No per-run startup fee.** Every comparable Actor charges one — between $0.00005 and $0.01 every time you press run, whether it finds anything or not. This one bills only for jobs actually delivered, so an over-filtered search that returns nothing costs nothing.
- Run memory reduced to 256 MB (from 512) and the ceiling to 512 MB. Measured peak usage is ~86 MB at 200 results, and the extra memory was buying 1.8x speed for 2.2x the cost.

#### Added

- Every delivered row now carries `charged` and `charge_skip_reason`, so a row delivered without a charge — past a charge limit, for instance — explains itself from the dataset rather than looking like a billing error.
- A search that collects 300 jobs while keeping under 3% of them is now stopped, with a warning naming the filter responsible and suggesting the search term that would find the same jobs directly. Filters like salary or work arrangement can only be judged after a job's full details are fetched, so a very restrictive one was quietly turning a short run into a long one.
- Emoji and grouped sections throughout the input, plus links to related Actors.

### \[0.1.0] — 2026-09-13

First release.

#### Added

- **Three ways to search** — paste a LinkedIn job search URL, paste a single job link, or describe the search with keywords and locations. All three can be combined in one run; results are merged and de-duplicated, and every row records each search that found it.
- **Plain-language locations and companies** — type `"London"` or `"Stripe"` and the Actor resolves it on LinkedIn itself. No numeric IDs to look up.
- **Custom freshness windows** — `postedWithinHours` accepts any window, beyond the 24 hours / 1 week / 1 month that LinkedIn's own filter offers.
- **Salary parsing** — the published range is captured and split into `salary_min`, `salary_max`, `salary_currency` and `salary_period`, so hourly and annual pay are never averaged together.
- **Recruiter contacts** — `poster_name`, `poster_title` and `poster_profile_url` for postings that name the person who posted them.
- **Exact posting dates** — `posted_date` is the posting's own date, not a value reconstructed from text like "3 weeks ago".
- **Applicant counts** — with `applicants_is_estimate` flagging the cases where LinkedIn gave a range rather than a number.
- **Filters that actually filter** — employment type, experience level, workplace type, title and description keywords, company and location exclusions, "has a salary", "has a named recruiter" and a hard date cutoff, all applied to the collected data. When every job is filtered out, the run names the filter responsible.
- **Card-only mode** — `scrapeJobDetails: false` returns the search-card fields roughly 10× faster, for monitoring which jobs exist.
- **Five dataset views** — Overview, Recruiter contacts, Salary data, Full descriptions and Problems.
- Failures are delivered as rows with an `error_type` rather than being silently dropped, and `RUN_SUMMARY` records what each search collected, delivered and filtered.
