Indeed Expired Job Checker — Dead Listing Monitor avatar

Indeed Expired Job Checker — Dead Listing Monitor

Under maintenance

Pricing

from $1.00 / 1,000 job key checkeds

Go to Apify Store
Indeed Expired Job Checker — Dead Listing Monitor

Indeed Expired Job Checker — Dead Listing Monitor

Under maintenance

Check Indeed job listings for $1 per 1,000 keys — live, expired, or removed. Bulk-verify jobkeys/URLs, harvest fresh keys by keyword + city, or schedule a nightly dead-listing monitor with Slack/email/webhook alerts. Full job data (salary, company, dates) on every key. No login or API key.

Pricing

from $1.00 / 1,000 job key checkeds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 minutes ago

Last modified

Share

💼 Indeed Expired Job Checker — Dead Listing Monitor

Feed it Indeed jobkeys or job URLs and get back a clean verdict for every one — live, expired, or removed — plus the full job record (title, company, parsed salary, location, posting date) while it's still alive. Run it nightly in monitor mode and it flags only the jobs that JUST died, with Slack / email / webhook alerts, so your job board, ATS feed, or scraped database never serves a dead listing again.

There is no dedicated Indeed status checker on Apify — the usual workaround is re-running a full Indeed search scraper and diffing the results yourself, which misses direct-key lookups entirely and costs a multiple per record. This actor does one job, cheaply:

This actorGeneral Indeed search scrapers
Check a SPECIFIC jobkey / job URL✅ direct lookup, 1 request per key❌ can only re-run searches and hope the job appears
Price per 1,000 checks$1 ($0.001/key)typically several dollars per 1,000 search results, and you still have to diff
Explicit expired vs removed vs live verdict✅ three separated states, straight from Indeed's own flags❌ "absent from results" ≠ expired
Full job data on every key (salary min/max/currency, remote flag, dates, benefits, company rating)partial, varies
Newly-dead diff across runs (monitor mode)✅ named persistent state + newlyDead flag❌ DIY
Slack / email / webhook alerts on death
Failure handlingper-key retries with fresh proxy sessions, HTML + search-card fallbacks; a failed key is marked unknown (never falsely "dead") and not billeda failed page usually just crashes or silently drops rows

No login, no API key, no browser automation — the actor reads the same server-rendered JSON the Indeed page itself ships, one lightweight GET per job.


What does Indeed Expired Job Checker do?

It answers one question at scale: is this Indeed job still accepting candidates?

  • Three clean stateslive (still posted), expired (Indeed shows "This job has expired"), removed (the key 404s — listing deleted). Plus unknown when every check path fails, so you never purge a live job by mistake.
  • 📦 Bulk input — paste raw 16-hex jobkeys, viewjob?jk=… URLs, or /job/<title>-<key> URLs; mixed lists are fine, duplicates deduped, up to 5,000 keys per run.
  • 🌱 Harvest mode — no keys handy? Give it a keyword + city and it mints 25 fresh jobkeys from Indeed search page 1 and checks them (also the built-in demo).
  • 🧾 The full job record on every checked key — title, company (+ rating, review count, company page URL), formatted + geocoded location, remote flag, parsed salary min/max/currency/type plus the display text, posting date, date-on-Indeed, expiration date when present, job types, shift & schedule, benefits, skill attributes, advertiser/source employer name, recruiter phone when shown, urgent-hire and high-volume-hiring flags, apply-starts count, repost flag, full description (text + HTML), and a pruned raw object with everything else Indeed returns.
  • 🔄 Monitor mode — persistent per-key state in a named key-value store; each run flags newlyDead: true only for jobs that flipped from live to expired/removed since the last run.
  • 🔔 Alerts — Slack cards, email digests, or raw webhooks the moment a monitored listing dies.
  • 🛡️ Cloudflare-aware — Indeed spot-checks traffic; every request retries with a fresh proxy session, then falls back from JSON → HTML page → search-card data before ever giving up.

Who is it for?

  • 🗂️ Job-board operators purging dead Indeed-sourced listings nightly (the #1 user complaint on any job board is applying to a dead job).
  • 🔁 ATS / job-feed vendors keeping syndicated feeds clean for clients.
  • 📊 Labor-market & recruiting analysts measuring real time-to-fill — the expiry date IS the signal.
  • 🤖 Scraped-database owners re-validating Indeed records before resale or display.
  • 🎯 Sales teams timing outreach to companies whose postings just closed (they hired — or gave up).

How to use it (step by step)

  1. Click Try for free.
  2. Paste your Job keys or URLs (one per line) — or leave it empty and set a Harvest keyword + location to demo on 25 fresh keys.
  3. (Optional) set Max keys per run to bound cost.
  4. Click Start, open the Dataset tab, filter status != "live" — that's your purge list.
  5. (Recurring) turn on monitorMode, attach an Apify Schedule (e.g. nightly), add a Slack/webhook/email channel — you'll only hear about jobs that just died.

Quick start (bulk check)

{
"jobKeys": [
"ddb19acf24fc4188",
"https://www.indeed.com/viewjob?jk=cfc9d259e17574cb",
"https://www.indeed.com/job/warehouse-associate-0a27464dd26940cf"
]
}

Nightly purge monitor

{
"jobKeys": ["…your feed's jobkeys…"],
"monitorMode": true,
"alertOnDead": true,
"slackWebhookUrl": "https://hooks.slack.com/services/…"
}

Demo / harvest mode

{ "keyword": "warehouse", "location": "Dallas, TX", "maxKeys": 10 }

Input

FieldWhat it does
jobKeysjobkeys and/or Indeed job URLs to check (deduped; max 5,000/run)
keyword + locationharvest mode when jobKeys is empty — check 25 fresh keys from search page 1
maxKeyshard cap per run (0 = all provided keys)
monitorModepersist per-key status across runs; flag newlyDead transitions
alertOnDeadin monitor mode, alert on each newly expired/removed job
webhookUrl / slackWebhookUrl / emailRecipientsalert channels
proxyConfigurationdefault Apify proxy; switch to RESIDENTIAL for large batches
requestConcurrencyparallel checks, 1–5 (default 2)

Output

One record per checked key. The essentials:

{
"jobKey": "0a27464dd26940cf",
"status": "live",
"url": "https://www.indeed.com/viewjob?jk=0a27464dd26940cf",
"checkedAt": "2026-06-12T21:04:11.000Z",
"checkSource": "spa",
"title": "Warehouse Associate",
"company": "Recycle 2 Support",
"companyUrl": "https://www.indeed.com/cmp/Recycle-2-Support-4",
"companyRating": 4,
"companyReviewCount": 2,
"location": "Flower Mound, TX 75028",
"city": "Flower Mound",
"state": "TX",
"postalCode": "75028",
"latitude": 33.033405,
"longitude": -97.06766,
"remote": false,
"salaryMin": 15.5,
"salaryMax": 15.5,
"salaryCurrency": "USD",
"salaryType": "HOURLY",
"salaryText": "$15.50 an hour",
"datePublished": "2026-05-03T05:23:18.413Z",
"jobTypes": ["Full-time"],
"benefits": ["Health insurance", "Dental insurance"],
"sourceEmployerName": "Recycle 2 Support",
"isRepost": true,
"descriptionText": "…full text…",
"raw": { "…everything else Indeed returned…": "…" }
}

Dead keys come back as "status": "expired" (Indeed's own expired flag, usually still with title/company) or "status": "removed" (HTTP 404 — listing deleted). In monitor mode each record also carries previousStatus and newlyDead.

Export to JSON, CSV, Excel, or HTML, or pull via the Apify API straight into your purge pipeline.

How much does it cost?

Pay-per-event — you pay per check, no subscription:

EventWhat it coversPrice
lot-scrapedeach jobkey checked (live, expired, or removed — unknown is FREE)$0.001 / key
new-lot-detectedeach NEWLY-expired/removed job found in monitor mode$0.005 / job
monitor-run-completedeach scheduled monitor run~$0.01 / run
alert-deliveredeach Slack/email/webhook push~$0.002 / alert

(Final per-event prices are set on the actor's pricing page.)

$1 per 1,000 keys checked. A 10,000-listing feed verified nightly costs about $10/month plus a half-cent for each dead listing it catches.

The actor reads publicly available listing data — the same pages anyone can open without an account. The records are job/employer data, not personal data (the only person-adjacent field is a recruiter phone number when Indeed itself displays one publicly). Note: Indeed's Terms of Service restrict automated access; this is a ToS-gray area like all Indeed scraping. Use it on listings you have a legitimate operational need to verify (e.g. your own syndicated feed), respect rate limits, and consult your counsel for commercial use. You are responsible for your use of the data.

FAQ

What is an Indeed jobkey? The 16-character hex id in every Indeed job URL (viewjob?jk=ddb19acf24fc4188). It's the stable identifier for a listing — paste either the key or any URL containing it.

What's the difference between expired and removed? expired = the page still exists and Indeed marks it "This job has expired" (title/company usually still returned). removed = the key returns 404 — the listing was deleted outright. Both are dead for purge purposes.

Can it tell me WHEN a job expired? It returns Indeed's expirationDate when the page exposes one, plus the posting date and the check timestamp. For exact death timing, run monitor mode on a schedule — the newlyDead flag brackets death to the run interval.

Do I need an Indeed account, login, or API key? No. Every check is a plain GET to a public page.

Does a live result include the job details? Yes — full title, company, parsed salary (min/max/currency/type), location with coordinates, remote flag, job types, benefits, description, and more, with the rest preserved under raw.

How does monitor mode work? State lives in a named key-value store (indeed-job-status-monitor-state), scoped per input list or search. Each run compares current status to the last known status; only live→dead transitions (and first sightings of already-dead keys) are flagged newlyDead and alerted. All checked keys are still output with their current status.

What happens when Indeed blocks a request? Indeed's Cloudflare layer occasionally spot-checks. The actor retries up to 5× with a fresh proxy session, then falls back to the HTML page, then to same-run search-card data. If everything fails, the key is marked unknown — never falsely "dead" — and you are not charged for it.

Can it check thousands of keys? Yes — up to 5,000 per run (batch larger feeds across runs). At the default concurrency a 1,000-key batch takes roughly 15–20 minutes. For large batches, switch the proxy to RESIDENTIAL.

Can it find jobkeys for me? Harvest mode pulls the 25 fresh keys from page 1 of any keyword+location search. It deliberately does not paginate deeper (Indeed login-walls page 2) — split by city/keyword for volume.

Why did some keys come back unknown? All three check paths failed (usually sustained Cloudflare challenges on datacenter IPs). Re-run those keys with residential proxies. Unknowns are free.

Does it work outside the US? This version targets indeed.com (US). International Indeed domains (indeed.co.uk, ca.indeed.com, …) use the same key format — open an issue if you want them supported.

How do I plug it into my pipeline? Webhook alerts for push, or pull the dataset via the Apify API (status, newlyDead fields are made for WHERE clauses). Make/Zapier/n8n all work.

You might also like

  • 📈 Job-posting intent & hiring-signal monitors
  • 🏢 Company review and employer-data scrapers
  • 🧹 Other dead-link and listing-status checkers

Feedback

Found an edge case or want international Indeed domains? Open an issue on the actor — fast fixes and feature requests welcome.