# Competitor Hiring Intelligence Scraper (`coregent/competitor-hiring-intelligence-scraper`) Actor

Monitor public competitor hiring from career pages and job listings. Returns one flat row per job with competitor name, role category, seniority, location, work mode, ATS platform, a transparent hiring-signal score, and reason tags. No login or cookies.

- **URL**: https://apify.com/coregent/competitor-hiring-intelligence-scraper.md
- **Developed by:** [Delowar Munna](https://apify.com/coregent) (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 $1.80 / 1,000 competitor-job-results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Competitor Hiring Intelligence Scraper

![Competitor Hiring Intelligence Scraper](https://raw.githubusercontent.com/coregentdevspace/competitor-hiring-intelligence-scraper-assets/main/thumbnail-competitor-hiring-intelligence-scraper.png)

Monitor **public competitor hiring** from career pages and public job listings. For each competitor you get **one flat, CSV-ready row per job posting**: title, department, role category, seniority, location, work mode, ATS platform, a transparent **hiring-signal score** (0–100), and explainable **reason tags**.

Built for **competitor research, sales intelligence, recruiting, and market research** teams who want competitor-level hiring signals — not just a raw job dump — without login, cookies, residential proxy, or expensive enrichment APIs.

- ✅ **No login, no cookies, no API keys.** Public data only, over HTTP.
- ✅ **One row per unique job posting**, with derived hiring intelligence.
- ✅ **Transparent, non-AI scoring** you can audit field-by-field.
- ✅ Reliable extraction via **public ATS JSON APIs** (Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Workable), **schema.org JSON-LD**, and a careers-page HTML fallback.

---

### What it does

For every competitor the actor:

1. **Resolves** a careers/listing source — a direct `careerUrl`, or shallow discovery from `websiteUrl` (common paths like `/careers`, `/jobs`, `/join-us`).
2. **Extracts** visible job postings (public ATS JSON first, then JSON-LD, then a conservative HTML fallback).
3. **Derives** per-job fields: role category, seniority, work mode, country/region, department.
4. **Scores** a transparent `hiring_signal_score` and tags the reasons behind it.
5. **Filters, deduplicates, and emits** one flat row per unique job, capped per competitor and globally.

It does **not** do login/session scraping, deep crawling, contact/email enrichment, AI summaries, or historical tracking (see Future Features in the PRD).

---

### Input

| Field                     | Type             | Default                     | Description                                                                                                                                |
| ------------------------- | ---------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `competitors`             | array of objects | `[]`                        | Each `{ companyName, careerUrl, websiteUrl }`. **At least one required**; each needs a `careerUrl` or `websiteUrl`.                        |
| `maxResultsPerCompetitor` | integer          | `100`                       | Saved-job cap per competitor (1–500).                                                                                                      |
| `maxTotalResults`         | integer          | `1000`                      | Global saved-row cap (1–5000).                                                                                                             |
| `discoveryMode`           | string           | `career_url_first`          | `career_url_first` or `shallow_website_discovery_only`.                                                                                    |
| `includeJobDetails`       | boolean          | `false`                     | Fetch one detail page per job (only when the card is sparse) to fill snippet/salary/date.                                                  |
| `includeKeywords`         | array of strings | `[]`                        | Keep jobs matching at least one keyword.                                                                                                   |
| `excludeKeywords`         | array of strings | `[]`                        | Remove jobs matching any blocked keyword.                                                                                                  |
| `roleCategories`          | array of strings | `[]`                        | Keep only these derived categories (engineering/sales/marketing/product/data/finance/hr/operations/customer_support/legal/security/other). |
| `locations`               | array of strings | `[]`                        | Keep only jobs whose location/region matches.                                                                                              |
| `remoteMode`              | string           | `any`                       | `any`, `remote`, `hybrid`, `onsite`, `unknown`.                                                                                            |
| `postedWithinDays`        | integer          | `0`                         | Posted-date window when visible (0 disables; 1–365).                                                                                       |
| `strictDateFilter`        | boolean          | `false`                     | Drop undated rows when the date filter is enabled.                                                                                         |
| `deduplicate`             | boolean          | `true`                      | Remove duplicate job rows so duplicates are not charged.                                                                                   |
| `proxyConfiguration`      | object           | `{ "useApifyProxy": true }` | Datacenter, no proxy, or custom proxy URLs. Apify Residential rejected at startup.                                                         |

#### Example inputs

**1. Track two competitors and filter to high-value, recent roles**

```json
{
    "competitors": [
        {
            "companyName": "Canva",
            "websiteUrl": "https://www.canva.com",
            "careerUrl": "https://www.canva.com/careers/jobs/"
        },
        {
            "companyName": "Atlassian",
            "websiteUrl": "https://www.atlassian.com",
            "careerUrl": "https://www.atlassian.com/company/careers/all-jobs"
        }
    ],
    "maxResultsPerCompetitor": 100,
    "maxTotalResults": 500,
    "discoveryMode": "career_url_first",
    "includeKeywords": ["engineer", "data", "sales"],
    "excludeKeywords": ["internship"],
    "roleCategories": ["engineering", "data", "sales"],
    "locations": ["Sydney", "Remote", "Singapore"],
    "remoteMode": "any",
    "postedWithinDays": 30,
    "proxyConfiguration": { "useApifyProxy": true }
}
````

**2. Discover careers pages from competitor websites only**

```json
{
    "competitors": [
        { "companyName": "Stripe", "websiteUrl": "https://stripe.com" },
        { "companyName": "Figma", "websiteUrl": "https://www.figma.com" }
    ],
    "discoveryMode": "shallow_website_discovery_only",
    "maxResultsPerCompetitor": 50,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

**3. Minimal run — just give it competitors with career URLs**

```json
{
    "competitors": [
        { "careerUrl": "https://boards.greenhouse.io/databricks" },
        { "careerUrl": "https://jobs.lever.co/palantir" }
    ]
}
```

***

### Output

One flat row per unique job posting. Key fields:

- **Competitor / source**: `competitor_name`, `competitor_website_url`, `career_url`, `source_type` (`direct_career_url` / `discovered_career_url` / `job_detail_page`), `source_url`, `input_index`, `ats_platform`
- **Job**: `job_title`, `job_url`, `job_id`, `department`, `role_category`, `seniority_level`, `location`, `country_or_region`, `work_mode` (`remote` / `hybrid` / `onsite` / `unknown`), `posted_date`, `salary_text`, `job_snippet`
- **Signals**: `hiring_signal_score` (0–100), `hiring_signal_label` (`low` / `medium` / `high` / `very_high`), `reason_tags`, `matched_include_keywords`
- **Runtime**: `scraped_at`

Rows without a `job_title`, or without either `job_url` or `career_url`, are invalid and never pushed.

#### Dataset — all fields (table view)

![Competitor Hiring Intelligence Scraper output — all fields, table view](https://raw.githubusercontent.com/coregentdevspace/competitor-hiring-intelligence-scraper-assets/main/competitor-hiring-intelligence-scraper-output-all-fields-table-view.png)

#### Sample record

One real row from a run on the default competitors (`Canva`, `Atlassian`):

```json
{
    "competitor_name": "Atlassian",
    "competitor_website_url": "https://atlassian.com/",
    "career_url": "https://atlassian.com/company/careers/all-jobs",
    "job_title": "Distribution Partner Manager (APAC)",
    "job_url": "https://careers-apac-atlassian.icims.com/jobs/25343/distribution-partner-manager-%28apac%29/job",
    "job_id": "25343",
    "department": "Sales",
    "role_category": "sales",
    "seniority_level": "manager",
    "location": "Bengaluru Remote",
    "country_or_region": "India",
    "work_mode": "remote",
    "posted_date": "2026-06-14",
    "salary_text": null,
    "job_snippet": "Working at Atlassian Atlassians can choose where they work – whether in an office, from home, or a combination of the two. That way, Atlassians have more control over supporting their family, personal goals, and other priorities. We can hire people in any country where we have a legal entity.",
    "ats_platform": "unknown",
    "hiring_signal_score": 90,
    "hiring_signal_label": "very_high",
    "reason_tags": "sales_role|senior_role|remote_role|new_market_location|recent_posting|has_description|keyword_match",
    "matched_include_keywords": "sales",
    "source_type": "direct_career_url",
    "source_url": "https://atlassian.com/company/careers/all-jobs",
    "input_index": 1,
    "scraped_at": "2026-06-15T04:35:59.303Z"
}
```

A **run summary** is stored in the default key-value store under `RUN_SUMMARY` with counters such as `inputs_total`, `competitors_processed`, `raw_results_found`, `results_saved`, `duplicates_removed`, `filtered_out`, and `charged_events`.

***

### Hiring-signal score

A transparent 0–100 score (PRD §7) based only on visible public fields. Each valid job starts at **20**, then:

- `+15` if role category is `engineering`, `data`, `product`, `sales`, or `security`
- `+10` if seniority is `senior`, `lead`, `manager`, `director`, or `executive`
- `+10` if work mode is `remote` or `hybrid`
- `+10` if the job is outside the competitor's primary country (location expansion)
- `+10` if posted within 14 days
- `+10` if an ATS platform is detected
- `+10` if a job snippet/description is available
- `+5` if salary text is visible
- `+5` if the title matches your include keywords

Labels: `0–39 low`, `40–64 medium`, `65–84 high`, `85–100 very_high`. `reason_tags` lists exactly which rules fired (pipe-separated).

***

### Pricing

**Pay Per Event.** One event, `competitor-job-result`, is charged **only after** a valid, unique, filtered-in job row is successfully pushed to the dataset. Duplicate jobs, filtered-out jobs, failed inputs, blocked requests, and summary records are **never** charged. The actor honours your per-run spending limit and stops cleanly when it is reached.

***

#### 🚦 Proxy policy

Use **Apify Datacenter** proxy or **no proxy** for normal runs — both work reliably for competitor career pages and public ATS APIs at this actor's conservative concurrency.

**Apify Residential proxy is not supported.** The actor fails at startup if `apifyProxyGroups` includes `RESIDENTIAL`. Reason: in pay-per-event actors, residential bandwidth (~$8/GB) is billed to the developer, not the run user, so a single bandwidth-heavy run could exceed the per-result event revenue.

If you genuinely need residential routing, supply your own residential provider via the proxy editor's **Custom proxy URLs** field — that traffic goes through your provider, not Apify, and is unaffected:

```
http://user:pass@proxy.iproyal.com:12321
http://user:pass@proxy.brightdata.com:22225
http://user:pass@proxy.oxylabs.io:7777
```

***

### How sources are found

For each competitor the actor tries, in order of reliability:

1. **Public ATS JSON APIs** when the career URL is hosted on / links to one (Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Workable).
2. **Schema.org `JobPosting` JSON-LD** embedded in the career page (server-rendered, standardized).
3. **Generic careers-page HTML** — job-detail links as a fallback.
4. **Known-site adapters** for notable companies with a custom public listings endpoint (e.g. Atlassian), and **ATS-token guessing** as a last resort when a website is supplied without a usable career URL.

### Notes & limitations

- Coverage is strongest for competitors that publish jobs on a **public ATS** — which, thanks to JSON-LD and token guessing, includes many companies whose own careers site is a custom app.
- Supplying a **direct `careerUrl`** is the most reliable mode; `shallow_website_discovery_only` probes only a few common paths and does not deep-crawl.
- A custom JavaScript-only careers page with **no** public ATS board, JSON-LD, or adapter yields no rows for that competitor (this actor is HTTP-only by design — no headless browser; browser fallback is a future feature).
- If a competitor source requires login or blocks public access, that competitor is marked failed/partial and the run continues.

# Actor input Schema

## `competitors` (type: `array`):

Competitors to monitor. Add one item per competitor. Each item needs at least a Career URL or a Website URL (Company name is recommended).

## `maxResultsPerCompetitor` (type: `integer`):

Stop saving new job rows for a competitor after this many results. Range 1-500.

## `maxTotalResults` (type: `integer`):

Global cap on saved unique job rows across all competitors. The run stops once this is reached. Range 1-5000.

## `discoveryMode` (type: `string`):

How career pages are found. "Career URL first" uses each competitor's careerUrl directly and only falls back to shallow website discovery when no careerUrl is given. "Shallow website discovery only" ignores careerUrl when a websiteUrl is present and discovers a careers page from common paths.

## `includeJobDetails` (type: `boolean`):

When on, fetch one extra detail-page request per job (only when the listing card lacks a snippet, salary, and date) to fill those fields. Off by default to keep runs fast and cheap.

## `includeKeywords` (type: `array`):

Keep only jobs matching at least one keyword (in title, department, location, snippet, role category, or reason tags). Empty means no include filter. Example: "engineer", "data", "sales".

## `excludeKeywords` (type: `array`):

Remove jobs matching any of these keywords (in title, department, location, snippet, or URL). Example: "internship".

## `roleCategories` (type: `array`):

Keep only jobs whose derived role category is in this list. Empty means all categories.

## `locations` (type: `array`):

Keep only jobs whose visible location or derived country/region matches one of these terms. Empty means all locations. Example: "Sydney", "Remote", "Singapore".

## `remoteMode` (type: `string`):

Keep only jobs with this derived work mode. "Any" applies no work-mode filter.

## `postedWithinDays` (type: `integer`):

Keep only jobs posted within this many days, when a posted date is visible. 0 disables the filter. Range 0-365.

## `strictDateFilter` (type: `boolean`):

When the posted-date filter is enabled and a job has no visible/parseable date: keep it (off) or drop it (on).

## `deduplicate` (type: `boolean`):

Remove duplicate job rows (by job id, canonical URL, or title+location) so you are not charged for duplicates.

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

Apify Proxy configuration. Defaults to Apify Proxy enabled. Apify Residential is NOT supported and will fail the run at startup; if you need residential routing, supply your own provider via Custom proxy URLs (proxyUrls).

## Actor input object example

```json
{
  "competitors": [
    {
      "companyName": "Canva",
      "websiteUrl": "https://www.canva.com",
      "careerUrl": "https://www.canva.com/careers/jobs/"
    },
    {
      "companyName": "Atlassian",
      "websiteUrl": "https://www.atlassian.com",
      "careerUrl": "https://www.atlassian.com/company/careers/all-jobs"
    }
  ],
  "maxResultsPerCompetitor": 100,
  "maxTotalResults": 1000,
  "discoveryMode": "career_url_first",
  "includeJobDetails": false,
  "includeKeywords": [
    "engineer",
    "data",
    "sales"
  ],
  "excludeKeywords": [
    "internship"
  ],
  "roleCategories": [],
  "locations": [
    "Sydney",
    "Remote",
    "Singapore"
  ],
  "remoteMode": "any",
  "postedWithinDays": 0,
  "strictDateFilter": false,
  "deduplicate": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Flat table view with one row per unique job posting: competitor identity, career/source URL, job title and URL, department, role category, seniority, location, country/region, work mode, posted date, salary, snippet, ATS platform, and the derived hiring-signal score, label, and reason tags.

# 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 = {
    "competitors": [
        {
            "companyName": "Canva",
            "websiteUrl": "https://www.canva.com",
            "careerUrl": "https://www.canva.com/careers/jobs/"
        },
        {
            "companyName": "Atlassian",
            "websiteUrl": "https://www.atlassian.com",
            "careerUrl": "https://www.atlassian.com/company/careers/all-jobs"
        }
    ],
    "includeKeywords": [
        "engineer",
        "data",
        "sales"
    ],
    "excludeKeywords": [
        "internship"
    ],
    "locations": [
        "Sydney",
        "Remote",
        "Singapore"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("coregent/competitor-hiring-intelligence-scraper").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 = {
    "competitors": [
        {
            "companyName": "Canva",
            "websiteUrl": "https://www.canva.com",
            "careerUrl": "https://www.canva.com/careers/jobs/",
        },
        {
            "companyName": "Atlassian",
            "websiteUrl": "https://www.atlassian.com",
            "careerUrl": "https://www.atlassian.com/company/careers/all-jobs",
        },
    ],
    "includeKeywords": [
        "engineer",
        "data",
        "sales",
    ],
    "excludeKeywords": ["internship"],
    "locations": [
        "Sydney",
        "Remote",
        "Singapore",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("coregent/competitor-hiring-intelligence-scraper").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 '{
  "competitors": [
    {
      "companyName": "Canva",
      "websiteUrl": "https://www.canva.com",
      "careerUrl": "https://www.canva.com/careers/jobs/"
    },
    {
      "companyName": "Atlassian",
      "websiteUrl": "https://www.atlassian.com",
      "careerUrl": "https://www.atlassian.com/company/careers/all-jobs"
    }
  ],
  "includeKeywords": [
    "engineer",
    "data",
    "sales"
  ],
  "excludeKeywords": [
    "internship"
  ],
  "locations": [
    "Sydney",
    "Remote",
    "Singapore"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call coregent/competitor-hiring-intelligence-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=coregent/competitor-hiring-intelligence-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Competitor Hiring Intelligence Scraper",
        "description": "Monitor public competitor hiring from career pages and job listings. Returns one flat row per job with competitor name, role category, seniority, location, work mode, ATS platform, a transparent hiring-signal score, and reason tags. No login or cookies.",
        "version": "1.0",
        "x-build-id": "6r0z0r8nUkTvjUeoK"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/coregent~competitor-hiring-intelligence-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-coregent-competitor-hiring-intelligence-scraper",
                "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/coregent~competitor-hiring-intelligence-scraper/runs": {
            "post": {
                "operationId": "runs-sync-coregent-competitor-hiring-intelligence-scraper",
                "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/coregent~competitor-hiring-intelligence-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-coregent-competitor-hiring-intelligence-scraper",
                "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": {
                    "competitors": {
                        "title": "Competitors",
                        "type": "array",
                        "description": "Competitors to monitor. Add one item per competitor. Each item needs at least a Career URL or a Website URL (Company name is recommended).",
                        "items": {
                            "type": "object",
                            "properties": {
                                "companyName": {
                                    "title": "Company name",
                                    "description": "Competitor name, e.g. \"Canva\". Recommended but optional; inferred from the URL when omitted.",
                                    "type": "string",
                                    "editor": "textfield"
                                },
                                "careerUrl": {
                                    "title": "Career URL",
                                    "description": "Public career/job-listing page URL (primary, most reliable mode), e.g. \"https://www.canva.com/careers/jobs/\".",
                                    "type": "string",
                                    "editor": "textfield"
                                },
                                "websiteUrl": {
                                    "title": "Website URL",
                                    "description": "Company website URL, used for shallow career-page discovery when no Career URL is given, e.g. \"https://www.canva.com\".",
                                    "type": "string",
                                    "editor": "textfield"
                                }
                            },
                            "additionalProperties": false
                        },
                        "default": []
                    },
                    "maxResultsPerCompetitor": {
                        "title": "Max results per competitor",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Stop saving new job rows for a competitor after this many results. Range 1-500.",
                        "default": 100
                    },
                    "maxTotalResults": {
                        "title": "Max total results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Global cap on saved unique job rows across all competitors. The run stops once this is reached. Range 1-5000.",
                        "default": 1000
                    },
                    "discoveryMode": {
                        "title": "Discovery mode",
                        "enum": [
                            "career_url_first",
                            "shallow_website_discovery_only"
                        ],
                        "type": "string",
                        "description": "How career pages are found. \"Career URL first\" uses each competitor's careerUrl directly and only falls back to shallow website discovery when no careerUrl is given. \"Shallow website discovery only\" ignores careerUrl when a websiteUrl is present and discovers a careers page from common paths.",
                        "default": "career_url_first"
                    },
                    "includeJobDetails": {
                        "title": "Include job details",
                        "type": "boolean",
                        "description": "When on, fetch one extra detail-page request per job (only when the listing card lacks a snippet, salary, and date) to fill those fields. Off by default to keep runs fast and cheap.",
                        "default": false
                    },
                    "includeKeywords": {
                        "title": "Include keywords",
                        "type": "array",
                        "description": "Keep only jobs matching at least one keyword (in title, department, location, snippet, role category, or reason tags). Empty means no include filter. Example: \"engineer\", \"data\", \"sales\".",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "excludeKeywords": {
                        "title": "Exclude keywords",
                        "type": "array",
                        "description": "Remove jobs matching any of these keywords (in title, department, location, snippet, or URL). Example: \"internship\".",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "roleCategories": {
                        "title": "Role categories",
                        "type": "array",
                        "description": "Keep only jobs whose derived role category is in this list. Empty means all categories.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "engineering",
                                "sales",
                                "marketing",
                                "product",
                                "data",
                                "finance",
                                "hr",
                                "operations",
                                "customer_support",
                                "legal",
                                "security",
                                "other"
                            ]
                        },
                        "default": []
                    },
                    "locations": {
                        "title": "Locations",
                        "type": "array",
                        "description": "Keep only jobs whose visible location or derived country/region matches one of these terms. Empty means all locations. Example: \"Sydney\", \"Remote\", \"Singapore\".",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "remoteMode": {
                        "title": "Work mode",
                        "enum": [
                            "any",
                            "remote",
                            "hybrid",
                            "onsite",
                            "unknown"
                        ],
                        "type": "string",
                        "description": "Keep only jobs with this derived work mode. \"Any\" applies no work-mode filter.",
                        "default": "any"
                    },
                    "postedWithinDays": {
                        "title": "Posted within days",
                        "minimum": 0,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Keep only jobs posted within this many days, when a posted date is visible. 0 disables the filter. Range 0-365.",
                        "default": 0
                    },
                    "strictDateFilter": {
                        "title": "Strict date filter",
                        "type": "boolean",
                        "description": "When the posted-date filter is enabled and a job has no visible/parseable date: keep it (off) or drop it (on).",
                        "default": false
                    },
                    "deduplicate": {
                        "title": "Deduplicate jobs",
                        "type": "boolean",
                        "description": "Remove duplicate job rows (by job id, canonical URL, or title+location) so you are not charged for duplicates.",
                        "default": true
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy configuration. Defaults to Apify Proxy enabled. Apify Residential is NOT supported and will fail the run at startup; if you need residential routing, supply your own provider via Custom proxy URLs (proxyUrls).",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
