# 💼 LinkedIn Job Changes & Company Hiring Signals (`snuggly_beanie_970/linkedin-job-change-hiring-signal`) Actor

Find public LinkedIn jobs with full descriptions, salary and criteria. Detect new or updated listings and aggregate company hiring signals by role, location and remote share.

- **URL**: https://apify.com/snuggly\_beanie\_970/linkedin-job-change-hiring-signal.md
- **Developed by:** [Ilia](https://apify.com/snuggly_beanie_970) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 enriched linkedin jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 💼 LinkedIn Job Changes & Company Hiring Signals

Search public LinkedIn job listings and turn them into monitoring data: complete job details, `new`/`updated` fingerprints, and company-level hiring signals across roles, locations and remote work.

### More than a job export

Commodity LinkedIn job scrapers return one row per listing. This Actor additionally deduplicates overlapping keyword searches, fingerprints material fields for scheduled change detection, and groups the live result set into company hiring summaries with active-job count, remote share, location breadth and top roles.

### Job fields

- Stable LinkedIn job ID, canonical URL and every matching search keyword
- Title, company, company URL, location and posting date
- Full clean description and original description HTML
- Salary text plus parsed minimum, maximum, currency and pay period when disclosed
- Required-skill tags, benefits, seniority, employment type, functions and industries
- Applicant text, Easy Apply signal and application URL when publicly exposed
- Workplace type plus `new`, `updated` or `unchanged` state

### Company signal fields

- Active matching jobs in this search window
- Remote-job count and remote share
- Unique location count
- Most frequently hired titles, locations and skills
- Disclosed-salary coverage across the company's matching roles

### 🔄 Monitoring

Save the input as an Apify Task and enable `onlyChanges`. The first run records a baseline and emits the current listings as `new`; unchanged subsequent runs emit nothing and incur no result-event charges. When listings change, only new or materially updated jobs and affected company summaries are emitted.

### 🚀 Example

```json
{"keywords":["machine learning engineer","AI engineer"],"location":"United States","datePosted":"week","workplaceType":"remote","includeDescriptions":true,"onlyChanges":false,"emitCompanySummaries":true,"maxJobs":100}
```

### 💰 Pricing

Pay per delivered job and per company hiring summary. Duplicate searches, filtered listings and failed detail pages are not charged as extra results. Apify's maximum-charge limit is honored during dataset writes.

The Actor reads LinkedIn's signed-out public jobs surface and does not require a LinkedIn account or session cookie.

### 📥 Complete input reference

| Field | Type | Default | Purpose |
|---|---|---:|---|
| `keywords` | array | `["AI engineer"]` | One or more job searches, such as AI engineer, video editor or sales development. |
| `location` | string | `"United States"` | City, country or region used by LinkedIn search. |
| `datePosted` | string | `"week"` | Restrict listings by age. |
| `workplaceType` | string | `"all"` | All, remote, hybrid or on-site listings. |
| `includeDescriptions` | boolean | `true` | Fetch each job page for description, criteria, salary text and application link. |
| `onlyChanges` | boolean | `false` | Use with a saved Task: first run establishes the baseline; later runs emit new and changed listings. |
| `emitCompanySummaries` | boolean | `true` | Add grouped hiring signals per company for the selected search window. |
| `maxJobs` | integer | `100` | Hard cap after deduplication across keyword searches. |

### 📤 Complete output reference

The default dataset is exportable as JSON, CSV, Excel, XML or RSS. Fields remain stable for scheduled runs and API integrations.

| Field | Type |
|---|---|
| `recordType` | string |
| `jobId` | string |
| `changeType` | string |
| `jobTitle` | string |
| `companyName` | string |
| `companyUrl` | string |
| `location` | string |
| `workplaceType` | string |
| `postedAt` | string |
| `postedText` | string |
| `salaryText` | string |
| `employmentType` | string |
| `seniorityLevel` | string |
| `industries` | array |
| `jobFunction` | array |
| `skills` | array |
| `benefits` | array |
| `applicantText` | string |
| `salaryMin` | number / null |
| `salaryMax` | number / null |
| `salaryCurrency` | string |
| `salaryPeriod` | string |
| `easyApply` | boolean |
| `descriptionText` | string |
| `descriptionHtml` | string |
| `applyUrl` | string |
| `jobUrl` | string |
| `searchKeywords` | array |
| `activeJobCount` | integer / null |
| `remoteJobCount` | integer / null |
| `remoteShare` | number / null |
| `uniqueLocationCount` | integer / null |
| `topTitles` | array |
| `topLocations` | array |
| `topSkills` | array |
| `salaryCoveragePercent` | number / null |
| `scrapedAt` | string |

### 🔌 API & integrations

Run this Actor from the Apify Console, API, CLI, MCP, Make, Zapier or n8n. Replace the Actor identifier and token in this template:

```bash
curl -X POST "https://api.apify.com/v2/acts/linkedin-job-change-hiring-signal/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Results are stored in the run's default dataset and can be forwarded with Apify webhooks or scheduled Tasks.

### 🔎 Search keywords

LinkedIn Job Changes & Company Hiring Signals, linkedin, job, changes, company, hiring, signals, change, signal, Apify Actor, scraper API, structured data, scheduled monitor, automation.

# Actor input Schema

## `keywords` (type: `array`):

Run several job searches in one job.

## `searchUrls` (type: `array`):

Optional LinkedIn search URLs with filters already applied.

## `location` (type: `string`):

City, country or region used by LinkedIn search.

## `geoId` (type: `string`):

Optional precise LinkedIn geographic ID.

## `distance` (type: `integer`):

Search radius supported by LinkedIn.

## `datePosted` (type: `string`):

Restrict listings by publication age.

## `workplaceType` (type: `string`):

Simple remote, hybrid or on-site filter.

## `workplaceTypes` (type: `array`):

Values: remote, hybrid, onsite. Overrides the simple workplace filter.

## `jobTypes` (type: `array`):

Values: fullTime, partTime, contract, temporary, internship, volunteer, other.

## `experienceLevels` (type: `array`):

Values: internship, entry, associate, midSenior, director, executive.

## `companyIds` (type: `array`):

Restrict search to selected numeric company IDs.

## `easyApplyOnly` (type: `boolean`):

Return listings marked with LinkedIn Easy Apply.

## `includeDescriptions` (type: `boolean`):

Description, salary, applicants, criteria and application link.

## `onlyChanges` (type: `boolean`):

Persistent fingerprints for scheduled monitoring.

## `emitCompanySummaries` (type: `boolean`):

Create aggregated hiring intelligence rows per company.

## `maxJobs` (type: `integer`):

Hard result cap after deduplication.

## `maxConcurrency` (type: `integer`):

Parallel requests for full job details.

## `maxRetries` (type: `integer`):

Maximum attempts after blocks or transient failures.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each LinkedIn request.

## `proxyConfiguration` (type: `object`):

Residential proxy is recommended for large or repeated LinkedIn runs.

## Actor input object example

```json
{
  "keywords": [
    "AI engineer"
  ],
  "location": "United States",
  "distance": 25,
  "datePosted": "week",
  "workplaceType": "all",
  "easyApplyOnly": false,
  "includeDescriptions": true,
  "onlyChanges": false,
  "emitCompanySummaries": true,
  "maxJobs": 100,
  "maxConcurrency": 8,
  "maxRetries": 5,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("snuggly_beanie_970/linkedin-job-change-hiring-signal").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("snuggly_beanie_970/linkedin-job-change-hiring-signal").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call snuggly_beanie_970/linkedin-job-change-hiring-signal --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,snuggly_beanie_970/linkedin-job-change-hiring-signal"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0nDK3fxYxCQTtECV8/builds/ALaRZgbb3JEEdk1rn/openapi.json
