LinkedIn Job Market Report — Demand, Top Hiring Companies avatar

LinkedIn Job Market Report — Demand, Top Hiring Companies

Pricing

from $24.00 / 1,000 market reports

Go to Apify Store
LinkedIn Job Market Report — Demand, Top Hiring Companies

LinkedIn Job Market Report — Demand, Top Hiring Companies

A LinkedIn job market report per keyword and location: roles read, how many LinkedIn shows, top hiring companies, job titles and places, remote share and fresh postings. Run it again for the change since the last run: new companies and rank moves. $0.03 per report. No login.

Pricing

from $24.00 / 1,000 market reports

Rating

0.0

(0)

Developer

Northbell

Northbell

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Give it a list of markets — a keyword in a place, like react developer | Berlin, Germany — and get one report row per market: how many roles it read, how many LinkedIn says exist, who is hiring (top 15 companies), the title mix, the places, the remote share and how many postings are fresh. $0.03 per report ($30 per 1,000), no login, no cookies.

Run it again — or put it on a weekly schedule — and every report also tells you what changed since the last run: which companies are new in the market, how the top companies moved up or down (previousRank, rankChange, positive = moved up), and how many more or fewer roles it read. LinkedIn only shows you today's market; this keeps the history.

What you get

One row per market (type: "market"):

FieldWhat it is
keywords, location, datePosted, searchUrlthe market and the LinkedIn search page it comes from
jobsRead, maxJobsPerMarket, stoppedBy, notehow many distinct postings were read. stoppedBy is cap (your limit), end (LinkedIn's public list had no more to give — this can be far fewer than the total it prints, see Notes) error (then note says what happened) or time (the run was about to reach its time limit; note says so)
totalShownByLinkedIn, totalShownText, totalShownIsLowerBound, totalShownPlace, totalShownNotethe number LinkedIn prints above the results. Big markets show as a rounded floor such as 1,000+ or 10,000+ (totalShownIsLowerBound: true). totalShownNote appears only when the number is missing or answers for another place, and says why
shareOfTotalReadjobsRead as a share of the exact total LinkedIn prints (0.147 = you read 15% of it); null when the total is missing or a floor like 10,000+
postedLast24h, postedLast7dpostings by posting date: dated today or yesterday (UTC), and dated within the last 7 days
remoteShare, activelyHiringShareshare of postings whose title or place says "Remote", and share with LinkedIn's "Actively Hiring" badge
distinctCompanies, top5CompaniesSharehow many companies are hiring, and how much of the market the five biggest hold
topCompaniestop 15: company, slug (LinkedIn's company page name, null when the posting links none), jobs, rank, previousRank, rankChange, jobsChange, isNew
topTitlestop 15 job titles with jobs — normalised, so "Data Engineer (m/w/d)", "Data Engineer - Remote" and "Sr. Data Engineer" fall into the right groups
topLocationstop 10 places with jobs
previousObservedAt, jobsReadChange, totalShownChange, postedLast7dChangethe change since your previous run of the same market (null on the first run)
newCompaniesCount, newCompaniesSinceLastRuncompanies hiring now that were not in the previous run (top 15 listed, with jobs; an empty list when nothing is new)
requestsUsedHTTP requests this report took, retries included
observedAtwhen it was read

With Include job details on, the row also has: detailsRead (of detailsAsked), seniorityMix, employmentTypeMix (each [{level or type, jobs, share}]), easyApplyShare, and detailsNote when too few job pages could be read.

Error rows (type: "error": keywords, location, message) are free.

Use it for

  • Hiring and recruiting — see which companies are competing for the same people in your city, and which just started
  • Career moves and salary talks — how deep is the market for your title in a place, and how much of it is remote
  • Sales and lead generation — companies hiring in a field are companies with budget for it; newCompaniesSinceLastRun is a weekly lead list
  • Market research and newsletters — demand by role and place, tracked the same way every week

Input

{
"markets": [
{ "keywords": "data engineer", "location": "United States" },
"react developer | Berlin, Germany"
],
"maxJobsPerMarket": 200,
"datePosted": "past-week"
}
  • markets — up to 100 per run. Objects with keywords and location, or the short string "keywords | location". Put them all in one run and you pay the start fee once.
  • maxJobsPerMarket — default 200, up to 1,000. Ten postings per request.
  • datePosted — past-week (default), past-24-hours, past-month or any.
  • includeDetails — default false. Opens a sample of job pages for the seniority mix, employment-type mix and Easy Apply share (see Pricing).
  • detailsPerMarket — job pages to open per market when details are on: 30 by default, 10 to 100, spread evenly over the postings read.

The history is kept per market, period and size in a named key-value store in your Apify account, so the second run already shows changes. Schedule it (Apify → Schedules) for a weekly log. Changing datePosted or maxJobsPerMarket starts a new history for that market.

Pricing

$0.03 per market report, plus $0.01 per run. A report that reads 200 postings takes about 21 requests (20 pages of results and 1 for the total); at 1,000 postings about 101; a search whose public list is shorter takes fewer. LinkedIn is read at 30 requests a minute, so a 200-posting report takes about 40 seconds: a run of 100 markets at that size needs more than the default 1-hour run timeout, so lower maxJobsPerMarket or raise the timeout. Each report is saved as soon as it is done. Error rows (markets that could not be read) are free. The $0.01 run-start fee is the one charge every run pays, even one that returns nothing.

With Include job details on, a report costs $0.10 instead ($100 per 1,000) and takes up to detailsPerMarket more requests (30 by default). If too few job pages could be read to give a mix, the report is kept and charged as a plain one.

Notes

  • Public data only: what anyone sees on LinkedIn without signing in. No login, no cookies; the Actor cannot send either. No people are read — only job postings, company names and places.
  • The lists come from the postings read, which can be a small part of the market. The company, title and place lists are ranked by the number of postings among the postings read. LinkedIn serves anonymous visitors at most the first 1,000 postings of a search, and for many searches the public list ends much earlier: in October 2026 a search that printed "4,000+" listed 100 postings and one that printed 680 listed 100 (stoppedBy: "end"). So stoppedBy: "end" means LinkedIn had nothing more to show, not that you have the whole market. Compare jobsRead with totalShownByLinkedIn (shareOfTotalRead) to see how much of it a report covers, and compare markets with each other by shares (remoteShare, top5CompaniesShare) rather than by raw counts.
  • "New since last run" compares what each run could read. A company shows as new when it was not in the previous run's list; with a list that is a ranked slice of a bigger market (stoppedBy is cap, or end well short of the total) it can also mean it moved into the slice. Narrow the market (one city, past-24-hours) for steadier changes. A run cut short by an error (stoppedBy: "error") is not saved, so the next run is compared with the last complete one.
  • totalShownByLinkedIn can be empty. It comes from LinkedIn's public search page, which sometimes answers for a different place than the one you asked for (we saw "Berlin, Germany" answered as the district "Köpenick"). Then the number is not used, it is null, and totalShownNote says what happened; the same field is also empty when that page could not be read. It never fails the report. totalShownChange is only filled when both totals are exact (not 10,000+). A place LinkedIn does not recognise is widened to a bigger one (a made-up town came back as the whole United States): check topLocations against the place you asked for.
  • Dates have no time of day. LinkedIn publishes the posting date, so postedLast24h counts postings dated today or yesterday (UTC), and postedLast7d those dated within 7 days. Choosing past-week makes postedLast7d about equal to jobsRead; choose any or past-month to see the age mix.
  • remoteShare is a floor. The public job list has no workplace-type field, so it counts postings that say "Remote" in the title or place ("Remote Sensing" excepted).
  • Job details are a sample. seniorityMix, employmentTypeMix and easyApplyShare are computed over the job pages read (detailsRead), not the whole market. easyApplyShare is the share of postings where you apply on LinkedIn itself (LinkedIn's public page shows an Apply button without the external-link arrow); the rest send you to the company's own site. Postings that state no seniority or employment type are left out of that mix. seniorityMix uses LinkedIn's own levels, including "Not Applicable".
  • Not included: salary (see the salary Actor below), job descriptions, applicant counts. Fields from job pages are empty unless Include job details is on.
  • If LinkedIn stops answering part-way, a report built from at least 30 postings is kept and marked stoppedBy: "error" with a note; with fewer you get a free error row. After three markets in a row that LinkedIn refuses, the rest of the run is skipped instead of waiting for each. Two minutes before the run's time limit the market in progress stops the same way (stoppedBy: "time"), and the markets not started come back as free kind: "time-limit" rows, so nothing read is lost to a timeout.
  • rank is shared between companies with the same number of postings (1, 1, 1, 4), so a new company does not push the tied ones down.

Need the postings themselves, pay or one company's openings?

For AI agents

{"markets": ["data engineer | United States"], "maxJobsPerMarket": 100} returns one row with jobsRead, totalShownByLinkedIn, topCompanies, topTitles, remoteShare and the change since the last run. Rows have type: market or error. Pass several markets in one run to compare them. jobsRead is the size of the sample behind the lists (LinkedIn's public list often ends at 100); for demand use totalShownByLinkedIn when it is present and not a floor (totalShownIsLowerBound: false), and compare the lists by shares (remoteShare, top5CompaniesShare).

**Something broke or looks wrong?** Open an issue on this Actor's Issues tab and I'll look at it. **Found it useful?** A short review on the Store page helps other people find it.