# Multi-ATS Jobs Scraper & Hiring Signal Monitor (`harvestlab/ats-hiring-signal-monitor`) Actor

Scans public Greenhouse, Lever, and Ashby job boards, returning normalized jobs, hiring velocity, new/changed/closed deltas, webhook alerts, and optional AI hiring briefs for sales, recruiting, and market teams.

- **URL**: https://apify.com/harvestlab/ats-hiring-signal-monitor.md
- **Developed by:** [Nick](https://apify.com/harvestlab) (community)
- **Categories:** Jobs, AI, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 job 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

## Multi-ATS Jobs Scraper & Hiring Signal Monitor

Multi-ATS jobs scraper for sales, recruiting, market intelligence, and RevOps teams that need public hiring signals from Greenhouse, Lever, and Ashby boards. It returns normalized job rows, company-level hiring velocity, new/changed/closed deltas, webhook-ready summaries, diagnostics, and an optional AI hiring brief.

Use it when a hiring page is more useful as structured data than as a tab in a browser. The actor is built for account prioritization, competitor monitoring, recruiting market maps, partner intelligence, and scheduled alerts from public ATS boards. Direct board URLs are the best input, while company domains and names are supported as best-effort discovery helpers.

### Best First Run

Start with one direct public ATS board and a small job limit. This validates the output shape, pricing, and any downstream webhook before you monitor a larger account list.

```json
{
  "atsBoardUrls": ["https://boards.greenhouse.io/stripe"],
  "companyNames": ["Stripe"],
  "companyDomains": ["stripe.com"],
  "maxCompanies": 1,
  "maxJobsPerCompany": 25,
  "includeDescriptions": true,
  "watchMode": false,
  "enableAiAnalysis": false
}
````

For a second run, pass the first run's dataset ID as `previousJobsDatasetId` and set `watchMode` to `true`. The actor will classify rows as `new`, `existing`, `changed`, or `closed` and emit a company summary you can send to Slack, Zapier, Make, n8n, Discord, or your own endpoint.

### Multi-ATS Jobs Scraper Data You Get

The dataset contains four row types.

- `job`: one normalized public job posting with `url`, `source_url`, `source_ats`, `company`, `company_domain`, `ats_slug`, `job_id`, `title`, `department`, `team`, `location`, `remote_status`, `country`, `employment_type`, `seniority`, salary fields, `currency`, optional `description_text`, detected skills, detected functions, posting timestamps, `first_seen`, `last_seen`, `content_hash`, and `change_type`.
- `hiring_summary`: one company-level rollup with sources scanned, open jobs, new jobs, changed jobs, closed jobs, department counts, top locations, remote roles, AI-role count, engineering and sales counts, hiring velocity, and a short deterministic recommendation.
- `diagnostic`: a user-actionable row for unsupported inputs, missing ATS links, fetch failures, previous dataset issues, invalid webhook URLs, or AI analysis warnings.
- `ai_hiring_brief`: an optional narrative brief with provider and model metadata when `enableAiAnalysis` is true and a provider is configured.

Typical users join `job` rows to CRM accounts, use `hiring_summary` rows for prioritization, route `diagnostic` rows into QA queues, and save `ai_hiring_brief` rows for weekly account notes.

### Agent Workflows

Hiring activity is a strong buying and timing signal. This actor turns public ATS boards into structured events that are easy to route into account-based workflows.

- Sales teams can watch target accounts for sales, solutions, security, data, and engineering hiring spikes.
- Recruiting teams can map which competitors are expanding in specific locations or functions.
- Market intelligence teams can compare hiring velocity across private companies that do not publish revenue metrics.
- Customer success teams can spot expansion, implementation, support, or operations hiring at existing accounts.
- Workflow automations can post summaries to Slack, create CRM tasks, update account fields, or trigger research tasks when new roles appear.

The actor does not need login credentials or cookies. It only reads public ATS boards and public company pages used for best-effort discovery.

### Inputs

| Input | Type | Default | Notes |
| --- | --- | --- | --- |
| `companyNames` | string list | empty | Optional display labels and discovery hints. |
| `companyDomains` | string list | empty | Optional domains for best-effort public ATS discovery. |
| `atsBoardUrls` | string list | empty | Recommended input. Supports public Greenhouse, Lever, and Ashby URLs. |
| `atsSlugs` | string list | empty | Use `greenhouse:stripe`, `lever:mistral`, `ashby:openai`, or a raw slug. |
| `maxCompanies` | integer | 25 | Limits company or board targets scanned. Minimum 1, maximum 500. |
| `maxJobsPerCompany` | integer | 100 | Limits jobs returned per company. Minimum 1, maximum 1000. |
| `includeDescriptions` | boolean | true | Include cleaned job descriptions when available. Turn off for smaller output. |
| `watchMode` | boolean | false | Enables previous-dataset comparison when `previousJobsDatasetId` is set. |
| `previousJobsDatasetId` | string | empty | Prior run dataset used for new, changed, existing, and closed job classification. |
| `alertWebhookUrl` | string | empty | Optional HTTP endpoint for hiring signal summaries. |
| `enableAiAnalysis` | boolean | false | Generates an optional AI hiring brief. |
| `llmProvider` | select | openrouter | One of openrouter, anthropic, google, openai, or ollama. |
| `llmModel` | string | provider default | Optional model override. |
| `openrouterApiKey` | secret string | empty | Optional input key, or use `OPENROUTER_API_KEY`. |
| `anthropicApiKey` | secret string | empty | Optional input key, or use `ANTHROPIC_API_KEY`. |
| `googleApiKey` | secret string | empty | Optional input key, or use `GOOGLE_API_KEY`. |
| `openaiApiKey` | secret string | empty | Optional input key, or use `OPENAI_API_KEY`. |
| `ollamaBaseUrl` | string | `http://localhost:11434` | Self-hosted Ollama endpoint. |
| `proxyConfiguration` | object | Apify Proxy off | Optional network routing; most public ATS boards do not require it. |

Hidden aliases are available for CLI and agent callers: `urls` for `atsBoardUrls`, `domains` for `companyDomains`, `companies` for `companyNames`, `maxItems` for `maxJobsPerCompany`, and `query` for one company, domain, ATS URL, or source slug.

### Output Examples

Job row:

```json
{
  "record_type": "job",
  "url": "https://boards.greenhouse.io/example/jobs/123456",
  "source_url": "https://boards.greenhouse.io/example",
  "source_ats": "greenhouse",
  "company": "Example",
  "company_domain": "example.com",
  "ats_slug": "example",
  "job_id": "123456",
  "title": "Senior Platform Engineer",
  "department": "Engineering",
  "team": "Infrastructure",
  "location": "Remote - United States",
  "remote_status": "remote",
  "country": "US",
  "employment_type": "Full-time",
  "seniority": "senior",
  "salary_min": 140000,
  "salary_max": 180000,
  "currency": "USD",
  "detected_skills": ["Python", "Kubernetes"],
  "detected_functions": ["engineering"],
  "change_type": "new"
}
```

Hiring summary row:

```json
{
  "record_type": "hiring_summary",
  "company": "Example",
  "company_domain": "example.com",
  "sources_scanned": ["greenhouse"],
  "total_open_jobs": 42,
  "new_jobs": 7,
  "changed_jobs": 3,
  "closed_jobs": 2,
  "remote_count": 12,
  "ai_roles_count": 4,
  "engineering_roles_count": 18,
  "sales_roles_count": 9,
  "hiring_velocity_label": "expanding",
  "agent_recommendation": "Prioritize outreach this week."
}
```

Diagnostic row:

```json
{
  "record_type": "diagnostic",
  "diagnostic": "ats_not_found",
  "input": "example.com",
  "source_ats": "",
  "status": "skipped",
  "error": "No supported ATS link found.",
  "next_step": "Provide a Greenhouse, Lever, or Ashby jobs URL."
}
```

### Pricing Examples

Pay-per-event pricing keeps small monitoring runs inexpensive and makes large runs predictable.

| Event | Price | When charged |
| --- | ---: | --- |
| `company-scanned` | $0.01 | A supported public ATS source is checked. |
| `job-scraped` | $0.0025 | A normalized public job row is pushed. |
| `hiring-summary-generated` | $0.03 | A company summary is generated. |
| `ai-analysis-completed` | $0.05 | Optional AI hiring brief succeeds. |
| `skyfire-bundle-500-companies` | $5.00 | Bundle event for up to 500 company scans in one invocation. |

Example: scanning 5 companies with 100 total jobs and 5 summaries costs about $0.45 before optional AI analysis: $0.05 for company scans, $0.25 for job rows, and $0.15 for summaries.

Example: scanning 25 companies with 1,000 total jobs and 25 summaries costs about $3.50 before optional AI analysis: $0.25 for company scans, $2.50 for job rows, and $0.75 for summaries.

Diagnostic rows are not job rows. AI analysis is off by default and only charged when a non-empty brief is pushed.

### Scheduling and Webhooks

For monitoring, schedule the actor daily or weekly with the same target list. Keep the first run as your baseline, then pass that dataset ID into the next run as `previousJobsDatasetId` with `watchMode: true`.

Set `alertWebhookUrl` when you want push alerts instead of polling a dataset. The webhook payload summarizes company count, open jobs, new jobs, changed jobs, closed jobs, and company-level velocity labels. Webhook failures are reported as diagnostics so you can fix the endpoint without losing the scraped dataset.

Common schedules:

- Daily for high-value target accounts and active competitors.
- Weekly for broader market maps.
- Monthly for account enrichment fields that do not need immediate alerts.

### MCP/AI Agent Quickstart

When using Apify through an MCP server or another agent runner, pass the same JSON you would use in the Apify Console. The lowest-friction agent input is a direct ATS board URL plus a small job cap:

```json
{
  "atsBoardUrls": ["https://jobs.lever.co/mistral"],
  "companyNames": ["Mistral AI"],
  "companyDomains": ["mistral.ai"],
  "maxCompanies": 1,
  "maxJobsPerCompany": 50,
  "watchMode": true,
  "previousJobsDatasetId": "YOUR_PREVIOUS_DATASET_ID",
  "alertWebhookUrl": "https://hooks.slack.com/services/...",
  "enableAiAnalysis": true,
  "llmProvider": "openrouter"
}
```

For AI briefs, provide the selected provider key as an actor input or environment variable. Ollama users can point `ollamaBaseUrl` at a reachable self-hosted endpoint.

### Limitations

This actor monitors public Greenhouse, Lever, and Ashby boards only. It does not log in, use cookies, bypass private portals, or extract applicant data.

Company-domain discovery is best effort. Some companies use custom careers pages, regional subdomains, agency boards, or ATS vendors outside the supported set. For the highest hit rate, provide direct `atsBoardUrls` or explicit `atsSlugs`.

Public boards can change field names, remove descriptions, hide compensation, or use different location formats. The actor normalizes what is available and emits diagnostics when an input cannot be resolved or a source cannot be read.

Delta classification depends on a previous dataset. Without `previousJobsDatasetId`, current jobs are treated as new for the run and closed jobs cannot be detected.

Optional AI analysis summarizes the data returned by the run. It should be reviewed before using it for high-stakes hiring, investment, or compliance decisions.

### Legal and Compliance

You are responsible for making sure your use of this actor complies with the target websites' terms, applicable laws, and your internal data policies.

The actor is intended for public job postings and company-level hiring signals. Do not use the output to infer sensitive personal data, make unlawful employment decisions, or contact individuals in ways that violate privacy, anti-spam, or data protection rules.

If you process the data in the EU, UK, California, or another regulated jurisdiction, evaluate your lawful basis, retention policy, access controls, and deletion process. Store only what you need, keep it current, and remove data when it is no longer necessary for your stated purpose.

Webhooks send data to the endpoint you provide. Make sure that endpoint is controlled by you or your organization and that any downstream tools are approved for the type of job-market data you route there.

### FAQ

**Which ATS platforms are supported?** Greenhouse, Lever, and Ashby public boards are supported in this version.

**Can I provide company domains instead of board URLs?** Yes, but direct board URLs are more reliable. Domain discovery is best effort and may miss custom careers pages.

**Does it detect closed jobs?** Yes, when `watchMode` is true and `previousJobsDatasetId` points to a prior dataset containing job rows from the same targets.

**Does it require a proxy?** Usually no. Public ATS boards normally work without Apify Proxy, but the proxy input is available for run environments that need outbound routing.

**Can I turn off job descriptions?** Yes. Set `includeDescriptions` to false to reduce dataset size while keeping titles, departments, locations, deltas, and summaries.

**When should I enable AI analysis?** Enable it when you want a concise narrative brief over the hiring signal rows. Leave it off for lowest-cost structured exports.

**Will it scrape private applicant tracking data?** No. It reads public job boards only and does not access applicant systems or private recruiter dashboards.

# Actor input Schema

## `companyNames` (type: `array`):

Optional company names used as output labels and for best-effort discovery when paired with domains or slugs.

## `companyDomains` (type: `array`):

Optional company domains to search for public Greenhouse, Lever, or Ashby careers links.

## `atsBoardUrls` (type: `array`):

Public Greenhouse, Lever, or Ashby board URLs. This is the most reliable input for a first run.

## `atsSlugs` (type: `array`):

Optional slugs in source:slug form, such as greenhouse:stripe, lever:mistral, or ashby:openai. Raw slugs are expanded across supported ATS sources.

## `maxCompanies` (type: `integer`):

Maximum number of companies or board targets to scan.

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

Maximum number of jobs returned per company or ATS board.

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

Include cleaned job description text when available. Turn off for smaller datasets.

## `watchMode` (type: `boolean`):

Classify jobs as new, existing, changed, or closed when previousJobsDatasetId is supplied.

## `previousJobsDatasetId` (type: `string`):

Optional Apify dataset ID from a prior run. Used to classify new, changed, existing, and closed jobs.

## `alertWebhookUrl` (type: `string`):

Optional Slack, Zapier, Make, n8n, Discord, or custom HTTP endpoint for hiring signal summaries.

## `enableAiAnalysis` (type: `boolean`):

Generate an optional AI brief over the hiring summaries and changed jobs. Requires the selected provider key or Ollama URL.

## `llmProvider` (type: `string`):

Provider for optional AI hiring briefs.

## `llmModel` (type: `string`):

Optional model override. Leave empty to use the actor default for the selected provider.

## `openrouterApiKey` (type: `string`):

Get one at https://openrouter.ai/keys. Or set OPENROUTER\_API\_KEY env var.

## `anthropicApiKey` (type: `string`):

Get one at https://console.anthropic.com/settings/keys. Or set ANTHROPIC\_API\_KEY env var.

## `googleApiKey` (type: `string`):

Get one at https://aistudio.google.com/app/apikey. Or set GOOGLE\_API\_KEY env var.

## `openaiApiKey` (type: `string`):

Get one at https://platform.openai.com/api-keys. Or set OPENAI\_API\_KEY env var.

## `ollamaBaseUrl` (type: `string`):

URL of a self-hosted Ollama instance. Default: http://localhost:11434. Install at https://ollama.com/download.

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

Optional proxy settings. Public ATS boards usually work without Apify Proxy; enable only when your run environment needs outbound routing.

## `urls` (type: `string`):

Hidden alias for atsBoardUrls.

## `domains` (type: `string`):

Hidden alias for companyDomains.

## `companies` (type: `string`):

Hidden alias for companyNames.

## `maxItems` (type: `integer`):

Hidden alias for maxJobsPerCompany.

## `query` (type: `string`):

Hidden alias for a single company, domain, ATS URL, or source:slug input.

## Actor input object example

```json
{
  "companyNames": [],
  "companyDomains": [],
  "atsBoardUrls": [],
  "atsSlugs": [],
  "maxCompanies": 25,
  "maxJobsPerCompany": 100,
  "includeDescriptions": true,
  "watchMode": false,
  "enableAiAnalysis": false,
  "llmProvider": "openrouter",
  "ollamaBaseUrl": "http://localhost:11434",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `datasetOutput` (type: `string`):

Dataset containing normalized public ATS jobs, company hiring summaries, diagnostics, and optional AI hiring briefs.

# 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("harvestlab/ats-hiring-signal-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("harvestlab/ats-hiring-signal-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 '{}' |
apify call harvestlab/ats-hiring-signal-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Multi-ATS Jobs Scraper & Hiring Signal Monitor",
        "description": "Scans public Greenhouse, Lever, and Ashby job boards, returning normalized jobs, hiring velocity, new/changed/closed deltas, webhook alerts, and optional AI hiring briefs for sales, recruiting, and market teams.",
        "version": "0.1",
        "x-build-id": "yncJXKTUssEfGLCpg"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/harvestlab~ats-hiring-signal-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-harvestlab-ats-hiring-signal-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/harvestlab~ats-hiring-signal-monitor/runs": {
            "post": {
                "operationId": "runs-sync-harvestlab-ats-hiring-signal-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/harvestlab~ats-hiring-signal-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-harvestlab-ats-hiring-signal-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": {
                    "companyNames": {
                        "title": "Company names",
                        "type": "array",
                        "description": "Optional company names used as output labels and for best-effort discovery when paired with domains or slugs.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "companyDomains": {
                        "title": "Company domains",
                        "type": "array",
                        "description": "Optional company domains to search for public Greenhouse, Lever, or Ashby careers links.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "atsBoardUrls": {
                        "title": "ATS board URLs",
                        "type": "array",
                        "description": "Public Greenhouse, Lever, or Ashby board URLs. This is the most reliable input for a first run.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "atsSlugs": {
                        "title": "ATS slugs",
                        "type": "array",
                        "description": "Optional slugs in source:slug form, such as greenhouse:stripe, lever:mistral, or ashby:openai. Raw slugs are expanded across supported ATS sources.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "maxCompanies": {
                        "title": "Max companies",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of companies or board targets to scan.",
                        "default": 25
                    },
                    "maxJobsPerCompany": {
                        "title": "Max jobs per company",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of jobs returned per company or ATS board.",
                        "default": 100
                    },
                    "includeDescriptions": {
                        "title": "Include descriptions",
                        "type": "boolean",
                        "description": "Include cleaned job description text when available. Turn off for smaller datasets.",
                        "default": true
                    },
                    "watchMode": {
                        "title": "Watch mode",
                        "type": "boolean",
                        "description": "Classify jobs as new, existing, changed, or closed when previousJobsDatasetId is supplied.",
                        "default": false
                    },
                    "previousJobsDatasetId": {
                        "title": "Previous jobs dataset ID",
                        "type": "string",
                        "description": "Optional Apify dataset ID from a prior run. Used to classify new, changed, existing, and closed jobs."
                    },
                    "alertWebhookUrl": {
                        "title": "Alert webhook URL",
                        "type": "string",
                        "description": "Optional Slack, Zapier, Make, n8n, Discord, or custom HTTP endpoint for hiring signal summaries."
                    },
                    "enableAiAnalysis": {
                        "title": "Enable AI hiring brief",
                        "type": "boolean",
                        "description": "Generate an optional AI brief over the hiring summaries and changed jobs. Requires the selected provider key or Ollama URL.",
                        "default": false
                    },
                    "llmProvider": {
                        "title": "LLM provider",
                        "enum": [
                            "openrouter",
                            "anthropic",
                            "google",
                            "openai",
                            "ollama"
                        ],
                        "type": "string",
                        "description": "Provider for optional AI hiring briefs.",
                        "default": "openrouter"
                    },
                    "llmModel": {
                        "title": "LLM model override",
                        "type": "string",
                        "description": "Optional model override. Leave empty to use the actor default for the selected provider."
                    },
                    "openrouterApiKey": {
                        "title": "OpenRouter API key",
                        "type": "string",
                        "description": "Get one at https://openrouter.ai/keys. Or set OPENROUTER_API_KEY env var."
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API key",
                        "type": "string",
                        "description": "Get one at https://console.anthropic.com/settings/keys. Or set ANTHROPIC_API_KEY env var."
                    },
                    "googleApiKey": {
                        "title": "Google AI API key",
                        "type": "string",
                        "description": "Get one at https://aistudio.google.com/app/apikey. Or set GOOGLE_API_KEY env var."
                    },
                    "openaiApiKey": {
                        "title": "OpenAI API key",
                        "type": "string",
                        "description": "Get one at https://platform.openai.com/api-keys. Or set OPENAI_API_KEY env var."
                    },
                    "ollamaBaseUrl": {
                        "title": "Ollama base URL",
                        "type": "string",
                        "description": "URL of a self-hosted Ollama instance. Default: http://localhost:11434. Install at https://ollama.com/download.",
                        "default": "http://localhost:11434"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional proxy settings. Public ATS boards usually work without Apify Proxy; enable only when your run environment needs outbound routing.",
                        "default": {
                            "useApifyProxy": false
                        }
                    },
                    "urls": {
                        "title": "ATS board URLs (CLI alias)",
                        "type": "string",
                        "description": "Hidden alias for atsBoardUrls."
                    },
                    "domains": {
                        "title": "Company domains (CLI alias)",
                        "type": "string",
                        "description": "Hidden alias for companyDomains."
                    },
                    "companies": {
                        "title": "Company names (CLI alias)",
                        "type": "string",
                        "description": "Hidden alias for companyNames."
                    },
                    "maxItems": {
                        "title": "Max items (CLI alias)",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Hidden alias for maxJobsPerCompany."
                    },
                    "query": {
                        "title": "Single query (CLI alias)",
                        "type": "string",
                        "description": "Hidden alias for a single company, domain, ATS URL, or source:slug input."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
