# Changelog of Linkedin Jobs Scraper (`labrat011/linkedin-jobs-scraper`) Actor

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

## Changelog

### 0.0.49

The run summary now mentions rating the actor, but only after a run that went cleanly: nothing blocked, nothing throttled, no rows dropped by a filter, and not a free-tier run that hit its ceiling. If a run gave you a reason to be unhappy, it does not ask. Scraping behaviour, input, output and pricing are unchanged.

### 0.0.44 – 0.0.48

Build tooling and Store page copy. No change to behaviour, input, output or pricing.

### 0.0.43

**Split a country into cities and reach past LinkedIn's 1,000 result ceiling.**

LinkedIn returns at most 1,000 results for any one search. A United States search cannot go deeper than that no matter how many jobs exist. Turn on **Split country into cities** and the search becomes one search per major city, which is the only way further in.

The reason this is worth the extra searches is that cities return genuinely different jobs rather than the same ones relabelled. Measured on "registered nurse", serially, with no blocked responses:

- A 500 job United States walk shared only **3%** of what New York, Houston and Phoenix each returned.
- Those three cities shared **nothing at all** with one another.
- Three cities took reachable inventory from 500 to **939**, an 88% gain. Ten cities scale roughly the same way.

Supported countries, largest markets first: United States (30 cities), United Kingdom (12), Canada (10), Australia (8), Germany (8), India (8). **How many cities** controls how many are used and defaults to 10. A location that is already a city, or a country not on that list, is searched exactly as you typed it.

Pasted search URLs split too, so a copied country-wide search expands the same way.

**This multiplies the size of your run.** Ten cities at 100 per search is 1,000 results, and results are billed per item. Set Max Results to cover cities x Max Results Per Search or the run stops part way through, which the existing truncation warning will tell you about before it happens.

### 0.0.42

**Paste a LinkedIn search URL. Search by radius. And a throttled run now says it was throttled.**

- **Search URLs.** Build the search on linkedin.com, copy the address bar, paste it into Search URLs. Keywords, location, geo ID, radius and date range are read straight out of it. Paste several and each becomes its own search, keeping its own city and radius, so one run can cover Boise at 5 miles and Denver at 100.
- **Radius, in miles.** A real filter, not a decorative one. Around Boise, 5 miles returns only Boise postings while 100 also returns Caldwell, Gooding, Hailey, McCall and Meridian. Verified against an unfiltered control before shipping, the same way Date Posted was.
- **Filters in a pasted URL that LinkedIn ignores are now named.** Copying a search from a logged-in browser usually brings `f_WT`, `f_E` or `f_JT` along. LinkedIn accepts those from the browser and discards them on the public endpoint this actor uses, so the run logs exactly which ones were dropped instead of letting you believe they applied.
- **A throttled page is no longer mistaken for the end of the results.** When an offset genuinely has nothing, LinkedIn answers with a 26 byte stub. A throttle returns a full page with no listings on it. The actor treated both as "no more results", stopped early, and still reported success. Such a page is now retried once, and if it stays empty the run says the results may be incomplete rather than implying that was everything.

Job Type and Experience Level are unchanged: still verified against each posting's published values, because LinkedIn will not filter on them for us.

### 0.0.41

**LinkedIn changed its page size, and large runs were quietly coming up short.**

Sometime between 23 August and 6 September, LinkedIn's guest job search went from returning 25 listings per response to 10. The actor still walked results 25 at a time, so it read the first ten of every twenty-five, stepped over the other fifteen, and paginated deeper to make up the difference. Nothing errored, and every run still reported success.

Small runs were unaffected and returned exactly what you asked for. Large ones were not. Measured against live LinkedIn, a request for 450 results came back with 330.

What changed:

- **Large runs fill their order again.** The same 450 result request now returns 450. The further past roughly 300 results you were asking, the more you were losing.
- **You get the top of the ranking, not a sample spread across it.** LinkedIn orders results by relevance, and the old walk skipped bands of more relevant postings to reach less relevant ones further down. Two runs of the same 100 result search, before and after this fix, share only 16 rows.
- **Slightly cheaper per result.** The fix reads pages back to back instead of jumping, which works out about 6% fewer requests per job returned.
- **A release test now catches this.** `test_contract.py` checks the page size against live LinkedIn and fails the release if it has moved again. The offline pagination tests mocked the network and asserted the old stride against their own assumption, which is why this went unnoticed. They no longer contain a page size at all.

**If you run large scheduled jobs, expect your bill to rise.** Results are billed per item, and runs that were returning 330 of the 450 you ordered will now return all 450. That is the quantity you were asking for and paying the per item rate on, but the total per run goes up accordingly. Lower Max Results if you would rather hold the old spend.

### 0.0.38

**Max Results was capped at 1,000 by mistake, and batch runs now warn instead of truncating quietly.**

`maxResults` caps the whole run, but it carried LinkedIn's *per query* limit of 1,000 as its maximum. That is the limit on a single search, which `maxResultsPerSearch` already enforces. The effect was that no batch run could return more than 1,000 rows in total, however many searches it contained, and raising the number was rejected with "This field should be <= 1000".

- **Max Results maximum raised from 1,000 to 10,000.** A 30 combination batch at 50 per search needs 1,500 and can now ask for it. Max Results Per Search stays at 1,000, which is LinkedIn's real per query limit.
- **Runs now warn when the configuration truncates the batch.** If Max Results is lower than combinations x Max Results Per Search, the run logs how many combinations will not execute and the exact number to set. Nothing is changed automatically, since results are billed per item and raising your run size without asking would raise your bill.
- Both field descriptions rewritten so the difference between the two caps is clear.

### 0.0.34 – 0.0.36

**Removed filters that LinkedIn was ignoring.**

If you used Work Arrangement, Job Type, Experience Level, or Salary, your past results were not filtered the way you expected. LinkedIn's logged-out endpoints accept these and then discard them. Verified through residential proxies: two runs of the same search, one On-site and one Remote, returned the identical 25 jobs in the same order. Only Date Posted is honored server side.

The `workplaceType` column was derived from the filter you selected rather than from the job, so every row in a remote search was labelled remote regardless of the actual arrangement.

What changed:

- **Removed** Work Arrangement (`workType`) and the `workplaceType` output column. LinkedIn publishes no per job workplace value to logged-out clients. The Hybrid/Remote chip on linkedin.com is logged-in UI only.
- **Removed** Minimum Salary (`salary`). Nothing in the public markup can back it. The `salary` output field is unchanged.
- **Job Type and Experience Level now work properly.** Instead of sending parameters LinkedIn drops, the actor verifies each job's published Employment type and Seniority level. Every returned row genuinely matches. Both enable Fetch Full Job Details automatically, which adds one request per job.
- LinkedIn publishes no seniority for roughly half of postings. With Experience Level set, those rows are dropped rather than guessed at, so expect fewer results than Max Results. Every run now reports how many rows were dropped for a real mismatch versus how many had nothing to check.
- **Fixed batch examples that silently truncated.** Several published examples set Max Results Per Search but left Max Results at its default 100. Max Results caps the whole run, so those examples stopped after two combinations and the rest never executed. If you copied one, raise Max Results to combinations x per search.

Need remote filtering? Put "remote" in your keywords, and/or enable Fetch Full Job Details and filter the `description` text. Both are heuristics over how postings are written, not verified flags.

Thanks to the user who reported this and kept pushing after my first answer was wrong.
