Ghost Job Detector — Stale, Reposted & Evergreen Job Check
Pricing
from $0.80 / 1,000 job scoreds
Ghost Job Detector — Stale, Reposted & Evergreen Job Check
Check job data you already have for ghost jobs: open too long, reposted, re-dated, evergreen wording, closed but still listed, no pay. Every job gets a 0-100 score and the reason for each point, quoted from the posting. Works on any job scraper's rows. Nothing is scraped.
Pricing
from $0.80 / 1,000 job scoreds
Rating
0.0
(0)
Developer
Northbell
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 hours ago
Last modified
Categories
Share
Ghost Job Detector
Some job postings are not a seat someone is hiring for right now: they have been open for months, they come back every few weeks with a fresh date, or the text itself says it is collecting a "talent pipeline". Give this Actor the jobs you already have — from any job scraper, an ATS export, your own board — and every job gets a ghost score from 0 to 100 and the reason for each point, quoted from the posting or counted from your data. Turn on Remember jobs between runs and a job that comes back with a newer posting date is also flagged as re-dated. Nothing is scraped: the Actor only reads what you send.
$1 per 1,000 jobs returned, plus $0.01 per run.
Example
Input: three rows (two of them the same role listed twice on LinkedIn).
Output (a real run of the Actor's example input on 11 October 2026):
| title | ghostScore | signals |
|---|---|---|
| Customer Success Manager (Acme Corp) | 100 · high | evergreen: the posting says "We are always accepting applications and building a talent pipeline for future opportunities on our customer team." · age: open for 101 days (posted 2026-07-01) · reposted: listed 2 times on linkedin.com under the same title and place (posted 2026-07-01, 2026-09-30) · noPay · thin: the description is only 114 characters |
| Customer Success Manager (Acme) | 25 · low | reposted (same as above). Pay and description not checked: the row has neither |
| Payments Engineer (Example Pay) | 0 · low | — |
Run it again and again
- On a schedule — save your input as a task and add a Schedule: after your job scraper's scheduled run. Send each run to Google Sheets, Slack or email with an integration on the task.
- Watch for changes — Turn on Remember jobs between runs: a job that comes back with a newer posting date is flagged
redated, and its age counts from the first time it was seen. - In bulk — Pick every dataset in Datasets to check in one run.
The signals
| Signal | Points | What it means |
|---|---|---|
closed | 50 | The source marks the job closed (closed: true, acceptingApplications: false) or the text says "no longer accepting applications" — but it is still in your list |
evergreen | 35 | The text says it is not one current seat: "always accepting applications", "talent pool/community/pipeline", "future opportunities", "general application", "not a current opening". The sentence is quoted |
redated | 30 | With memory on: the job was first seen with one posting date and now shows a date at least 7 days newer — the date was refreshed, the job was not |
reposted | 25 | The same company, title and place is listed more than once on the same source with different links. The same job on LinkedIn and on the career page is not a repost |
age | 15 / 30 / 40 | Open for 30 / 60 / 90 days or more — from the posting date, or from the first time it was seen (memory), whichever is older |
applicants | 10 | 500 or more applicants and still open after 30 days (from rows that carry an applicant count) |
noPay | 10 | No pay range in the pay fields or in the text |
thin | 10 | The description is under 300 characters |
60 or more is high, 30 to 59 medium, under 30 low. The score is the order in which to check jobs before you apply, count or contact them — not proof that a job is fake. A role can be open for 100 days because it is hard to fill.
What cannot be read is not scored. A row without a description gets no noPay or thin points; it lists "pay" and "description" in notChecked instead. "Applications are reviewed on an ongoing basis until the position is filled" is a real seat and is not counted as evergreen.
Measured on real data
On 11 October 2026, with rows from two of our own scrapers:
- 60 LinkedIn "customer success manager" jobs in the United States (with descriptions and applicant counts): 7 medium, 0 high. 5 had been open 90 days or more, 24 stated no pay. None used evergreen wording — the "pipeline" in their texts was the sales pipeline, which the Actor does not count.
- 1,238 Stripe postings from LinkedIn and Stripe's Greenhouse board: 3 high, 276 medium. 178 open 90 days or more; 32 listed more than once on the same source — for example one sales role listed on 2025-10-06 and again on 2026-09-22.
A scheduled check: re-dated jobs
Turn on Remember jobs between runs and run it after your scraper on a schedule. The Actor keeps, for each job, the first day it saw it and the first posting date (in your key-value store ghost-job-history, for 180 days). From the second run, a job that shows a newer posting date gets redated, and its age counts from the first day it was seen — a refreshed date no longer makes an old job look new.
What you get
Your row as it was, plus:
| Field | |
|---|---|
ghostScore, ghostLevel | 0-100, and high / medium / low |
signals | [{ signal, points, evidence }], highest first |
notChecked | signals that could not be read from the row (age, pay, description) |
daysOpen, repostCount | the numbers behind age and reposted |
Return jobs scoring at least (minScore) keeps only the jobs worth a look: 30 for medium and high, 60 for high only.
Input
jobs: rows from any scraper, as they are. Read fromtitle/jobTitle/positionName,company/companyName,location,url/jobUrl,postedAt/datePosted/postedOn(also30+ days ago),description, and when presentapplicants,closed,daysOpenand pay fields (salaryMin,salaryText,annualSalaryMin…).datasetIds: datasets from your other runs, read in full.- Up to 50,000 rows per run.
The text rules are written for English postings.
Pricing
$1 per 1,000 jobs returned, plus $0.01 per run. Jobs below your minimum score are not returned and not charged.
For AI agents
Call with {"jobs": [...rows from any job scraper...], "minScore": 30} — seconds for a few thousand rows. Each row has type: "job", ghostScore and signals with the evidence as text.
Related
Rows with applicant counts and days open, the richest input for this check: LinkedIn Jobs Scraper with Applicant Counts.