# Ghost Job Detector (`badruddeen/ghost-job-detector`) Actor

Identify ghost, fake, or reposted LinkedIn and company jobs. Monitors listings, extracts signals, and calculates a Hiring Likelihood Score to help job seekers focus on genuine opportunities.

- **URL**: https://apify.com/badruddeen/ghost-job-detector.md
- **Developed by:** [Badruddeen Naseem](https://apify.com/badruddeen) (community)
- **Categories:** Jobs, AI, Automation
- **Stats:** 13 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Ghost Job Detector

### What does Ghost Job Detector do?

Ghost Job Detector helps you identify ghost, fake, or reposted job listings on LinkedIn and company career pages. Instead of crawling all job boards, this Actor **monitors specific job URLs over time,** extracts key signals, and calculates a **Hiring Likelihood Score (0–100)** to help job seekers distinguish genuine opportunities from fraudulent or outdated postings.

Ghost Job Detector can analyze:

- Job title, company name, and posting URL

- Job description and requirements

- Posting date and last activity timestamp

- Repost detection and frequency analysis

- Ghosting signals (e.g., inactive hiring, repeated postings)

- Hiring Likelihood Score (0–100)

- Red flags and authenticity indicators

---

### Why monitor LinkedIn and company job listings?

LinkedIn and company career pages host millions of job listings, but not all of them represent genuine hiring opportunities. Many positions are ghost jobs—postings that remain online even when companies aren’t actively hiring. These listings can waste time and distort recruitment insights for researchers and job seekers alike.

By monitoring job URLs over time, Ghost Job Detector helps you:

- Track whether a specific job is still actively hiring

- Identify positions that are repeatedly reposted

- Build a personal job search filter to focus only on legitimate opportunities

- Research hiring patterns and company recruitment strategies

- Analyze labor market trends and see which companies are actively hiring

- Detect fraudulent or misleading job postings before applying

- Create datasets for machine learning models that predict hiring likelihood

This approach allows you to **focus on the jobs you care about,** rather than crawling entire job boards.

---

### How to analyze LinkedIn and company job listings

Using Ghost Job Detector on Apify is simple. Instead of scraping entire job boards, you provide specific job URLs that you want to monitor and analyze.

Follow these steps:

1. Go to the Actor page:  
   [Ghost Job Detector](https://apify.com/badruddeen/ghost-job-detector) and click **Try for free**.

2. Enter one or more job posting URLs (LinkedIn or company career pages) in the input field.

3. (Optional) Enable monitoring settings if you want to run the Actor regularly to track changes over time.

4. Click **Run** to start the analysis.

5. When the run finishes, open the **Dataset** tab to preview or download your results.

You can export the dataset in formats such as JSON, CSV, Excel, or HTML.

---

### Input

The Ghost Job Detector Actor accepts the following input:

- **job_urls** (array or string): One or more LinkedIn or company job posting URLs to analyze.
- **testMode** (boolean, optional): Set `true` to skip crawling and use placeholder data for testing.
- **use_residential_proxy** (boolean, optional): Set `true` to route requests through residential proxies (useful for LinkedIn).

---

### Output

Each run produces structured JSON objects with the following fields:

- **url**: Original job posting URL
- **score**: Hiring Likelihood Score (0–100)
- **classification**: Human-readable risk classification
- **checkedAt**: Timestamp of analysis
- **signals**: Array of detected ghost-job signals (type, weight, value)
- **signalsDisplay**: Human-readable summary of signals
- **error**: Error message if analysis failed

**Example for one job:**
```json
{
  "url": "https://jobcenter.mv/en/jobs/application-training-specialist",
  "score": 21,
  "classification": "Low Intent",
  "checkedAt": "2026-02-12T20:14:35.412Z",
  "signals": [
    {
      "type": "missing_location",
      "weight": 18,
      "value": null
    },
    {
      "type": "missing_posted_date",
      "weight": 12,
      "value": null
    }
  ],
  "signalsDisplay": [
    "missing_location (18)",
    "missing_posted_date (12)"
  ],
  "error": null
}
````

***

### Dataset

The full dataset tab shows results for all analyzed job URLs. Each row corresponds to a single job listing.

**Example dataset output for multiple jobs:**

```json
[
  {
    "url": "https://jobcenter.mv/en/jobs/application-training-specialist",
    "score": 21,
    "classification": "Low Intent",
    "checkedAt": "2026-02-12T20:14:35.412Z",
    "signals": [
      {
        "type": "missing_location",
        "weight": 18,
        "value": null
      },
      {
        "type": "missing_posted_date",
        "weight": 12,
        "value": null
      }
    ],
    "signalsDisplay": [
      "missing_location (18)",
      "missing_posted_date (12)"
    ],
    "error": null
  },
  {
    "url": "https://jobcenter.mv/en/jobs/aviation-executive-7",
    "score": 21,
    "classification": "Low Intent",
    "checkedAt": "2026-02-12T20:14:35.240Z",
    "signals": [
      {
        "type": "missing_location",
        "weight": 18,
        "value": null
      },
      {
        "type": "missing_posted_date",
        "weight": 12,
        "value": null
      }
    ],
    "signalsDisplay": [
      "missing_location (18)",
      "missing_posted_date (12)"
    ],
    "error": null
  },
  {
    "url": "https://jobcenter.mv/en/jobs/academic-support-officer-1",
    "score": 0,
    "classification": "Low Intent",
    "checkedAt": "2026-02-12T20:14:35.191Z",
    "signals": [
      {
        "type": "placeholder",
        "weight": 0,
        "value": ""
      }
    ],
    "signalsDisplay": [
      "placeholder (0)"
    ],
    "error": null
  }
]
```

***

### How much will it cost to scrape job listings?

Apify gives you $5 in free usage credits every month on the [Apify Free plan](https://apify.com/pricing). Depending on the scope of your job search, you may be able to analyze dozens of listings completely free!

But if you need to monitor job listings regularly or analyze large volumes of data, you should grab an Apify subscription. We recommend our [$49/month Starter plan](https://apify.com/pricing)—ideal for job seekers and researchers tracking hiring trends.

For large-scale hiring market analysis, get up to 10,000+ job analyses per month with the [$499 Scale plan](https://apify.com/pricing).

***

### Results

Ghost Job Detector outputs a structured dataset with the following information for each job listing:

```json
[
  {
    "url": "https://jobcenter.mv/en/jobs/application-training-specialist",
    "score": 21,
    "classification": "Low Intent",
    "checkedAt": "2026-02-12T20:14:35.412Z",
    "signalsDisplay": [
      "missing_location (18)",
      "missing_posted_date (12)"
    ]
  },
  {
    "url": "https://jobcenter.mv/en/jobs/aviation-executive-7",
    "score": 21,
    "classification": "Low Intent",
    "checkedAt": "2026-02-12T20:14:35.240Z",
    "signalsDisplay": [
      "missing_location (18)",
      "missing_posted_date (12)"
    ]
  },
  {
    "url": "https://jobcenter.mv/en/jobs/academic-support-officer-1",
    "score": 0,
    "classification": "Low Intent",
    "checked
```

***

## Notes:

- url – the original job posting URL.

- score – Ghost-job risk score (0–100, higher means more likely ghost job).

- classification – human-readable hiring likelihood classification.

- checkedAt – timestamp of when the analysis was performed.

- signalsDisplay – list of detected ghost-job signals in a human-readable format.

You can preview this dataset in the Output tab or download it in JSON, CSV, Excel, or HTML formats.

***

### Tips for interpreting Ghost Job Detector results

- **Track patterns over time**: Monitor the same company's job listings to see if the same positions are reposted frequently, which may indicate ghost jobs.
- **Pay attention to signals**: Check the `signalsDisplay` field for indicators such as missing location, missing posted date, or repeated postings.
- **Focus on the Hiring Likelihood Score**: Scores closer to 100 indicate a higher risk of ghost jobs; lower scores suggest active hiring.
- **Compare multiple sources**: If the same job appears on LinkedIn and the company career page, check if the signals differ.
- **Validate critical details**: Missing job location or posting date can indicate incomplete or outdated listings.
- **Use classifications for quick filtering**: The `classification` field provides a human-readable summary (`Low Intent`, `Possible Hire`, `Actively Hiring`, `Likely Ghost Job`) to help prioritize which jobs to investigate further.

***

### Is it legal to scrape job listings?

Note that personal data is protected by GDPR in the European Union and by other regulations around the world. You should not scrape personal data (such as individual applicant information or recruiter details) unless you have a legitimate reason to do so.

Job listing data itself is generally considered public information, but you should review the terms of service for LinkedIn and company career pages to ensure compliance. If you're unsure whether your use case is legitimate, consult your lawyers.

We also recommend that you read Apify blog post: [is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/).

# Actor input Schema

## `testMode` (type: `boolean`):

Fast-run mode used for automated validation. Limits crawling and analysis for testing purposes.

## `job_urls` (type: `string`):

Enter one or more public job posting URLs (one per line recommended).

Examples:
https://www.linkedin.com/jobs/view/4001234567
https://careers.google.com/jobs/results/987654321
https://jobs.example.com/position/abc-xyz

## `run_mode` (type: `string`):

Single = one-time analysis
Monitor = track changes over multiple days

## `monitor_days` (type: `integer`):

Only used in Monitor mode – how many days to keep checking the same jobs

## `use_residential_proxy` (type: `boolean`):

Enable to crawl LinkedIn (or other strict sites) using a residential proxy. Recommended for multiple pages or high volume.

## Actor input object example

```json
{
  "testMode": true,
  "job_urls": "https://jobcenter.mv/en/jobs/pr-and-marketing-officer-2",
  "run_mode": "single",
  "monitor_days": 30,
  "use_residential_proxy": false
}
```

# Actor output Schema

## `summary` (type: `string`):

Most recent pushData record with job URL, score, classification, signals, and checkedAt timestamp.

## `fullDataset` (type: `string`):

Complete dataset including URL, score, classification, signals, signalsDisplay, checkedAt, and error. View/export from the dataset tab.

## `datasetView` (type: `string`):

Click to see the table of all job analyses (sorted newest first).

## `previewNote` (type: `string`):

Inspect each dataset item to see full job analysis, signals, and scores. SignalsDisplay provides a human-readable overview.

# 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("badruddeen/ghost-job-detector").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("badruddeen/ghost-job-detector").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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 badruddeen/ghost-job-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=badruddeen/ghost-job-detector",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Ghost Job Detector",
        "description": "Identify ghost, fake, or reposted LinkedIn and company jobs. Monitors listings, extracts signals, and calculates a Hiring Likelihood Score to help job seekers focus on genuine opportunities.",
        "version": "0.0",
        "x-build-id": "KkbL8RT4vpJcwjxhK"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/badruddeen~ghost-job-detector/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-badruddeen-ghost-job-detector",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/badruddeen~ghost-job-detector/runs": {
            "post": {
                "operationId": "runs-sync-badruddeen-ghost-job-detector",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/badruddeen~ghost-job-detector/run-sync": {
            "post": {
                "operationId": "run-sync-badruddeen-ghost-job-detector",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "job_urls",
                    "run_mode"
                ],
                "properties": {
                    "testMode": {
                        "title": "Test Mode (internal)",
                        "type": "boolean",
                        "description": "Fast-run mode used for automated validation. Limits crawling and analysis for testing purposes.",
                        "default": true
                    },
                    "job_urls": {
                        "title": "Job URLs",
                        "minLength": 1,
                        "type": "string",
                        "description": "Enter one or more public job posting URLs (one per line recommended).\n\nExamples:\nhttps://www.linkedin.com/jobs/view/4001234567\nhttps://careers.google.com/jobs/results/987654321\nhttps://jobs.example.com/position/abc-xyz",
                        "default": "https://jobcenter.mv/en/jobs/pr-and-marketing-officer-2"
                    },
                    "run_mode": {
                        "title": "Run Mode",
                        "enum": [
                            "single",
                            "monitor"
                        ],
                        "type": "string",
                        "description": "Single = one-time analysis\nMonitor = track changes over multiple days",
                        "default": "single"
                    },
                    "monitor_days": {
                        "title": "Monitoring Period (days)",
                        "minimum": 1,
                        "maximum": 180,
                        "type": "integer",
                        "description": "Only used in Monitor mode – how many days to keep checking the same jobs",
                        "default": 30
                    },
                    "use_residential_proxy": {
                        "title": "Use Residential Proxy",
                        "type": "boolean",
                        "description": "Enable to crawl LinkedIn (or other strict sites) using a residential proxy. Recommended for multiple pages or high volume.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
