# Indeed Company Jobs Monitor — Hiring Signals & Alerts (`scrapersdelight/indeed-company-hiring-monitor`) Actor

From $0.005 per company snapshot + $0.0005 per job — monitor any employer's newest Indeed postings, diff runs to flag new & closed roles, and get Slack/email/webhook hiring-signal alerts. Salary, location, remote flag, dates & company rating included. No login or API key.

- **URL**: https://apify.com/scrapersdelight/indeed-company-hiring-monitor.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (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.50 / 1,000 job row scrapeds

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/platform/actors/running/actors-in-store#pay-per-event

## 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

## 📡 Indeed Company Jobs Monitor — Hiring Signals & Alerts

**Point this actor at your target companies and it watches their Indeed job postings for you: every run snapshots each employer's newest open roles (title, location, salary, dates, link), diffs them against the previous run, and emits clean NEW-posting and CLOSED-posting hiring signals — with Slack, email, and webhook alerts. A new job posting is the cleanest "this company is investing in X right now" buying signal there is, and Indeed covers the employers that never publish a Greenhouse/Lever board: retail, logistics, healthcare, manufacturing, SMBs — everyone.**

No login or API key — built on Indeed's public job-search pages.

---

### How it compares

| | **This actor** | Leading Indeed scraper | Cheapest Indeed scraper |
|---|---|---|---|
| Price per 1,000 jobs | **$0.50** (lot-scraped @ $0.0005) | $6.00 per 1,000 results | ~$0.08 per 1,000 (pay-per-event) |
| Company-watch / monitor mode | **Yes — run-over-run diff, new + verified-closed signals** | No (one-shot scrape) | No (one-shot scrape) |
| Alerts (Slack / email / webhook) | **Yes, built in** | No | No |
| Parsed salary min/max/period/currency | **Yes** | salary text | salary fields |
| Remote flag, urgently-hiring, company rating | **Yes** | partial | partial |
| Full description enrichment | Optional (+$0.002/job) | Yes | Yes |
| Raw source record kept | **Yes (`raw` sub-object)** | No | No |
| Failure handling | Per-company isolation + 4x retry with fresh proxy session — one bad company never kills the run | 27.3% of recent runs failed (store stats) | — |
| Designed for | **Recurring hiring-signal feeds (GTM/intent)** | bulk one-shot search scrapes | bulk one-shot search scrapes |

*The big scrapers are built to bulk-export search results. This actor is built to be scheduled: a cheap per-company snapshot plus a diff, so your CRM/Clay/n8n gets only the postings that actually changed.*

---

### Why hiring is an intent signal

- 🧑‍💼 A new **"Salesforce Administrator"** posting → they run Salesforce. Sell them Salesforce tooling.
- 📈 A wave of **"Account Executive"** reqs → they're scaling GTM. Sell them sales tech, data, enablement.
- 🏗️ A **"Plant Manager — 2nd shift"** in a new city → expansion, new facility, new budget.
- 📉 A posting **closing** → the role is filled (time to congratulate the new hire) or the budget moved.

GTM platforms charge thousands for this feed. Indeed already publishes it — this actor turns it into structured rows for the exact companies *you* care about. It's the perfect complement to ATS-board monitors (Greenhouse/Lever/Ashby): **most of the economy doesn't use those ATSs, but almost everyone posts to Indeed.**

---

### What you get (per posting)

- 🏷️ **Role**: `title`, `norm_title`, `snippet`, `job_types`, optional full `description_html`/`description_text` + `benefits`
- 🏢 **Employer**: `company` (exact, fuzzy matches filtered out), `company_rating`, `company_review_count`, `company_overview_url`, `advertiser_id`, `featured_employer`
- 📍 **Location**: `location`, `city`, `state`, `postal`, `remote` flag
- 💰 **Salary (parsed)**: `salary_text`, `salary_min`, `salary_max`, `salary_currency`, `salary_period`, `salary_source`
- 📅 **Dates**: `posted_at` & `pub_date` (ISO), `posted_relative`, `expired`
- 🚨 **Hiring urgency**: `urgently_hiring`, `hiring_multiple_candidates`, `new_on_indeed`, `sponsored`
- 🔗 **Links**: direct `url` (viewjob), `third_party_apply_url`, `indeed_apply_enabled`
- 📶 **Signal fields** (monitor mode): `signal` = `new-posting` / `closed-posting` / `baseline-snapshot`, `is_new`, `first_seen`, `last_seen`
- 🧾 **`raw`** — the complete source record (minus ad-tracking blobs), so nothing Indeed returns is lost

Export to **JSON, CSV, Excel, HTML, RSS**, or pull via the Apify API straight into your CRM, Clay, n8n, Make, or warehouse.

---

### How to use it

1. Click **Try for free**.
2. Enter your **target companies** — plain names like `Walmart`, `Netflix`, `Chewy`.
3. *(Optional)* filter by **title keyword**, **location** (server-side `locationQuery` or client-side `locationFilter`), **remote only**, or **last N days**.
4. Click **Start** → open the **Dataset** tab. That's a snapshot of each company's newest open roles.
5. **For a live hiring-signal feed:** turn on **Monitor mode**, add an Apify **Schedule** (e.g. daily), and a **Slack/email/webhook**. The first run seeds a baseline; every run after that outputs and alerts only what changed.

#### Quick start (snapshot)
```json
{ "companies": ["Walmart"], "maxJobsPerCompany": 50 }
````

#### Daily hiring-signal monitor

```json
{
  "companies": ["Netflix", "Stripe", "Chewy", "Datadog"],
  "monitorMode": true,
  "alertOnNewPosting": true,
  "slackWebhookUrl": "https://hooks.slack.com/services/…"
}
```

#### Sales-team watcher (only AE roles, remote)

```json
{ "companies": ["Snowflake", "MongoDB"], "keyword": "account executive", "remoteOnly": true, "monitorMode": true }
```

***

### Pricing (pay-per-event)

| Event | What it covers | Price |
|-------|----------------|-------|
| `monitor-run-completed` | **one company snapshot** — charged once per company per run (snapshot *and* monitor runs) | **$0.005 / company** |
| `lot-scraped` | each job/signal row in your dataset | **$0.0005 / row** ($0.50 per 1,000) |
| `new-lot-detected` | each NEW posting detected in monitor mode | **$0.02 / new posting** |
| `lot-detail-enriched` | each full-description detail fetch (opt-in) | ~$0.002 / job |
| `alert-delivered` | each Slack/email/webhook alert sent | ~$0.005 / alert |

**Example:** watching 50 target accounts daily ≈ 50 × $0.005 = $0.25/day for the snapshots, plus $0.02 per actual new posting found. A month of monitoring 50 companies costs less than a single bulk scrape elsewhere. *(Final prices are set on the actor's pricing page.)*

***

### Scope, notes & limits (honest version)

- **Newest-jobs window:** the no-login surface is each company's first results page — the **~15-20 newest postings**. That is exactly what a change-monitor needs (new postings always enter through page 1), but this is **not** a bulk exporter of a 10,000-req employer's entire backlog. For very high-volume employers, narrow with `locationQuery`/`keyword` to keep the window relevant.
- **Closed-posting detection is verified, not guessed.** Indeed rotates sponsored slots on every page load, so "missing from the page" proves nothing. When a previously-seen posting disappears, the actor checks that posting's own Indeed page and reports `closed-posting` only if it's marked expired there. Jobs that merely scrolled off the window are left alone. (Verification fetches are capped per run — `maxCloseChecksPerRun`, default 25 — and re-queued across runs.)
- **No duplicate "new" alerts ever:** the monitor keeps a cumulative per-company seen-set, so a posting that rotates out of view and back in is never re-flagged. For a tight alert feed on very high-volume employers, pair with `newWithinDays` (e.g. 3) so only freshly-posted roles enter the feed at all.
- **Fuzzy search, exact filter:** Indeed's `company:` search is fuzzy full-text ("Stripe" also returns "Stripe-A-Zone"), so the actor filters by the exact employer field — `companyMatch` = `contains` (default, catches "Walmart Supply Chain"), `exact`, or `off`.
- **First monitor run = baseline.** You get the full snapshot, but nothing is flagged/charged/alerted as "new" — diffs start on run two. No double-alerting: state lives in a **named** key-value store (`indeed-company-hiring-monitor-state`) that persists across scheduled runs.
- **ToS note (gray area):** this actor accesses only public, no-login job-listing pages and collects no personal data — but Indeed's Terms of Service restrict automated access. Review them and applicable law; you are responsible for your use.
- A failed company (network blip, challenge) is logged and skipped — it never crashes the run or your schedule.

***

### FAQ

**Which companies can I track?** Any employer with jobs on indeed.com — by far the broadest job surface there is. Use plain names (`"Walmart"`). Power users can pass an Indeed company-page slug (`"cmp:Walmart"` or the `/cmp/...` URL) for exact employer scoping; note that page embeds a Cloudflare challenge widget, so plain names are the recommended, more reliable path.

**How is this different from the big Indeed scrapers?** They bulk-export search results once. This one is a *monitor*: cheap per-company snapshots, run-over-run diffing, and only-what-changed output + alerts. Different job (and ~12x cheaper per row).

**How fresh are the signals?** Schedule it daily (or hourly for hot accounts) — a new posting is detected on the first run after it appears in the company's newest-jobs window.

**Will it double-alert?** No. Monitor state is keyed per company + filter scope and persists in a named key-value store.

**Can I get full job descriptions?** Yes — set `fetchDescriptions: true`. One extra request per posting, charged as `lot-detail-enriched`.

**Does it parse salaries?** Yes — `salary_min` / `salary_max` / `salary_period` / `salary_currency`, plus whether the figure came from the employer or Indeed's estimate (`salary_source`).

**Remote roles?** `remote` boolean on every row, plus a `remoteOnly` input filter.

**What's in `raw`?** The complete source record for each job card (minus ad-tracking blobs) — if Indeed exposes it, you have it, even fields we didn't flatten.

**What about pagination / all postings?** Page 2+ of Indeed search requires a login, so the no-login scope is the newest-jobs window per company. For monitoring that's a feature: new postings always pass through it.

**Do I need proxies?** Apify's default datacenter proxy worked reliably in testing. If you ever see challenge retries in the log, switch the proxy input to RESIDENTIAL.

**Can it feed Clay / n8n / Make / my CRM?** Yes — webhook alerts per signal, or pull the dataset via the Apify API/integrations.

**Is this legal?** It reads public, no-login pages and collects no personal data, but scraping Indeed is against their ToS preferences — see the ToS note above. You decide your own risk tolerance and compliance.

# Actor input Schema

## `companies` (type: `array`):

Company names to track, one per line (e.g. 'Walmart', 'Netflix'). Each is snapshotted via Indeed's company search (newest ~15 postings, no login). For exact employer scoping you can also pass an Indeed company-page slug as 'cmp:<Slug>' or a https://www.indeed.com/cmp/<Slug>/jobs URL (that page embeds a Cloudflare challenge widget, so it is the riskier path — plain names are recommended).

## `maxJobsPerCompany` (type: `integer`):

Cap on postings kept per company per run (0 = no cap). The no-login window is page 1 = the ~15-20 newest postings per company anyway.

## `monitorMode` (type: `boolean`):

Recurring watcher: diff each company's current postings against the prior run (state kept in a named key-value store) and output NEW-posting and CLOSED-posting signal records. The first run per company seeds a baseline (full snapshot, no 'new' flags or alerts). Pair with an Apify Schedule. Off = plain snapshot of all current postings.

## `companyMatch` (type: `string`):

Indeed's company search is fuzzy full-text ('Stripe' also matches 'Stripe-A-Zone'), so results are filtered by the exact employer field. 'contains' (default) keeps employers whose name contains your query (catches 'Walmart Supply Chain'); 'exact' requires an exact name match; 'off' keeps everything Indeed returned.

## `keyword` (type: `string`):

Optional. Keep only postings whose TITLE contains this text (case-insensitive), e.g. 'engineer', 'account executive'.

## `locationQuery` (type: `string`):

Optional. Passed to Indeed's 'where' box, e.g. 'New York, NY' or 'Remote' — narrows the search itself.

## `locationFilter` (type: `string`):

Optional. Keep only postings whose location contains this text, e.g. 'TX', 'Chicago'.

## `remoteOnly` (type: `boolean`):

Keep only postings Indeed flags as remote.

## `newWithinDays` (type: `integer`):

Optional. Keep only postings created within the last N days (0 = all). Uses Indeed's posting date.

## `fetchDescriptions` (type: `boolean`):

Opt-in enrichment: fetch each posting's detail page for the full description (HTML + text) and benefits. One extra request per posting (charged as lot-detail-enriched).

## `detectClosed` (type: `boolean`):

In monitor mode, when a previously-seen posting leaves the company's newest-jobs window, VERIFY its own Indeed page and emit a 'closed-posting' record only if it reports expired (no false closes from page rotation).

## `maxCloseChecksPerRun` (type: `integer`):

Cap on closed-posting verification fetches per run (0 = unlimited). Unchecked candidates are re-queued next run, least-recently-checked first.

## `alertOnNewPosting` (type: `boolean`):

In monitor mode, send an alert for each newly-detected posting.

## `alertOnClosedPosting` (type: `boolean`):

In monitor mode, also alert when a posting closes.

## `webhookUrl` (type: `string`):

POST endpoint for hiring-signal alerts (JSON payload per signal).

## `slackWebhookUrl` (type: `string`):

Slack incoming-webhook URL for hiring-signal alerts.

## `emailRecipients` (type: `array`):

Emails for the hiring-signal digest (via apify/send-mail).

## `requestDelaySecs` (type: `integer`):

Pause between company/detail requests. 2s is polite and worked reliably in testing; lower at your own risk.

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

Proxy settings. Datacenter rotation worked reliably on the search path in testing; switch to RESIDENTIAL if you see challenges.

## `diagnose` (type: `boolean`):

Dev only. Fetches the first target and logs the first parsed posting, then exits.

## Actor input object example

```json
{
  "companies": [
    "Walmart"
  ],
  "maxJobsPerCompany": 50,
  "companyMatch": "contains",
  "remoteOnly": false,
  "newWithinDays": 0,
  "fetchDescriptions": false,
  "detectClosed": true,
  "maxCloseChecksPerRun": 25,
  "alertOnNewPosting": true,
  "alertOnClosedPosting": false,
  "requestDelaySecs": 2,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "diagnose": false
}
```

# Actor output Schema

## `postings` (type: `string`):

The dataset of postings / new- and closed-posting signals (one item per record).

# 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 = {
    "companies": [
        "Walmart"
    ],
    "maxJobsPerCompany": 50,
    "monitorMode": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/indeed-company-hiring-monitor").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 = {
    "companies": ["Walmart"],
    "maxJobsPerCompany": 50,
    "monitorMode": False,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/indeed-company-hiring-monitor").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 '{
  "companies": [
    "Walmart"
  ],
  "maxJobsPerCompany": 50,
  "monitorMode": false
}' |
apify call scrapersdelight/indeed-company-hiring-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapersdelight/indeed-company-hiring-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Indeed Company Jobs Monitor — Hiring Signals & Alerts",
        "description": "From $0.005 per company snapshot + $0.0005 per job — monitor any employer's newest Indeed postings, diff runs to flag new & closed roles, and get Slack/email/webhook hiring-signal alerts. Salary, location, remote flag, dates & company rating included. No login or API key.",
        "version": "0.1",
        "x-build-id": "bMiWPY7mthFjEJFCf"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapersdelight~indeed-company-hiring-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapersdelight-indeed-company-hiring-monitor",
                "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/scrapersdelight~indeed-company-hiring-monitor/runs": {
            "post": {
                "operationId": "runs-sync-scrapersdelight-indeed-company-hiring-monitor",
                "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/scrapersdelight~indeed-company-hiring-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-scrapersdelight-indeed-company-hiring-monitor",
                "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",
                "properties": {
                    "companies": {
                        "title": "Target companies",
                        "type": "array",
                        "description": "Company names to track, one per line (e.g. 'Walmart', 'Netflix'). Each is snapshotted via Indeed's company search (newest ~15 postings, no login). For exact employer scoping you can also pass an Indeed company-page slug as 'cmp:<Slug>' or a https://www.indeed.com/cmp/<Slug>/jobs URL (that page embeds a Cloudflare challenge widget, so it is the riskier path — plain names are recommended).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxJobsPerCompany": {
                        "title": "Max jobs per company",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on postings kept per company per run (0 = no cap). The no-login window is page 1 = the ~15-20 newest postings per company anyway."
                    },
                    "monitorMode": {
                        "title": "Monitor mode (new/closed-posting watcher)",
                        "type": "boolean",
                        "description": "Recurring watcher: diff each company's current postings against the prior run (state kept in a named key-value store) and output NEW-posting and CLOSED-posting signal records. The first run per company seeds a baseline (full snapshot, no 'new' flags or alerts). Pair with an Apify Schedule. Off = plain snapshot of all current postings."
                    },
                    "companyMatch": {
                        "title": "Company-name matching",
                        "enum": [
                            "contains",
                            "exact",
                            "off"
                        ],
                        "type": "string",
                        "description": "Indeed's company search is fuzzy full-text ('Stripe' also matches 'Stripe-A-Zone'), so results are filtered by the exact employer field. 'contains' (default) keeps employers whose name contains your query (catches 'Walmart Supply Chain'); 'exact' requires an exact name match; 'off' keeps everything Indeed returned.",
                        "default": "contains"
                    },
                    "keyword": {
                        "title": "Title keyword filter",
                        "type": "string",
                        "description": "Optional. Keep only postings whose TITLE contains this text (case-insensitive), e.g. 'engineer', 'account executive'."
                    },
                    "locationQuery": {
                        "title": "Location (server-side)",
                        "type": "string",
                        "description": "Optional. Passed to Indeed's 'where' box, e.g. 'New York, NY' or 'Remote' — narrows the search itself."
                    },
                    "locationFilter": {
                        "title": "Location filter (client-side)",
                        "type": "string",
                        "description": "Optional. Keep only postings whose location contains this text, e.g. 'TX', 'Chicago'."
                    },
                    "remoteOnly": {
                        "title": "Remote postings only",
                        "type": "boolean",
                        "description": "Keep only postings Indeed flags as remote.",
                        "default": false
                    },
                    "newWithinDays": {
                        "title": "Only postings from the last N days",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Optional. Keep only postings created within the last N days (0 = all). Uses Indeed's posting date.",
                        "default": 0
                    },
                    "fetchDescriptions": {
                        "title": "Fetch full job descriptions",
                        "type": "boolean",
                        "description": "Opt-in enrichment: fetch each posting's detail page for the full description (HTML + text) and benefits. One extra request per posting (charged as lot-detail-enriched).",
                        "default": false
                    },
                    "detectClosed": {
                        "title": "Detect closed postings (monitor mode)",
                        "type": "boolean",
                        "description": "In monitor mode, when a previously-seen posting leaves the company's newest-jobs window, VERIFY its own Indeed page and emit a 'closed-posting' record only if it reports expired (no false closes from page rotation).",
                        "default": true
                    },
                    "maxCloseChecksPerRun": {
                        "title": "Max close-checks per run",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on closed-posting verification fetches per run (0 = unlimited). Unchecked candidates are re-queued next run, least-recently-checked first.",
                        "default": 25
                    },
                    "alertOnNewPosting": {
                        "title": "Alert on new postings",
                        "type": "boolean",
                        "description": "In monitor mode, send an alert for each newly-detected posting.",
                        "default": true
                    },
                    "alertOnClosedPosting": {
                        "title": "Alert on closed postings",
                        "type": "boolean",
                        "description": "In monitor mode, also alert when a posting closes.",
                        "default": false
                    },
                    "webhookUrl": {
                        "title": "Webhook URL",
                        "type": "string",
                        "description": "POST endpoint for hiring-signal alerts (JSON payload per signal)."
                    },
                    "slackWebhookUrl": {
                        "title": "Slack webhook URL",
                        "type": "string",
                        "description": "Slack incoming-webhook URL for hiring-signal alerts."
                    },
                    "emailRecipients": {
                        "title": "Email recipients",
                        "type": "array",
                        "description": "Emails for the hiring-signal digest (via apify/send-mail).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "requestDelaySecs": {
                        "title": "Delay between requests (seconds)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Pause between company/detail requests. 2s is polite and worked reliably in testing; lower at your own risk.",
                        "default": 2
                    },
                    "proxyConfiguration": {
                        "title": "Proxy",
                        "type": "object",
                        "description": "Proxy settings. Datacenter rotation worked reliably on the search path in testing; switch to RESIDENTIAL if you see challenges.",
                        "default": {
                            "useApifyProxy": true
                        }
                    },
                    "diagnose": {
                        "title": "Diagnostic mode (dev)",
                        "type": "boolean",
                        "description": "Dev only. Fetches the first target and logs the first parsed posting, then exits.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
