# Job Search & Match Analyzer (`feeng/job-search-match-analyzer`) Actor

💼 Find remote, hybrid, and on-site jobs across public company career boards. Deduplicate vacancies, rank candidate fit, analyze salary and skills, and export direct application links plus a PDF report.

- **URL**: https://apify.com/feeng/job-search-match-analyzer.md
- **Developed by:** [Daniel S.](https://apify.com/feeng) (community)
- **Categories:** Jobs, Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 exported matched jobs

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## Job Search & Match Analyzer 💼

Search public company career boards and remote-job sources from one Apify Actor. Filter jobs by keyword, location, remote/hybrid/on-site arrangement, age, employment type, experience, salary, and skills. Get one deduplicated list ranked by candidate match, with direct links to the original job pages.

This is more than a raw job scraper. Every result includes:

- a transparent `matchScore` from 0 to 100,
- evidence explaining why the role matches,
- matched and missing preferred skills,
- normalized workplace arrangement and salary when available,
- freshness and source metadata,
- conservative scam-risk signals,
- the original job page and application URL,
- JSON and CSV exports,
- a printable HTML/PDF job-search report.

### Quick Start 🚀

1. Enter one or more **Job keywords**, such as `software engineer`, `marketing manager`, or `customer success`. Use one role per row; pasted comma-separated roles are split automatically.
2. Enter a **Location**, such as `Prague`, `London`, or `Germany`. Leave it empty for any location.
3. Choose **Any**, **Remote**, **Hybrid**, or **On-site**.
4. Start with 20–50 results and leave advanced filters unchanged.
5. Add preferred skills or a short candidate profile to improve ranking.
6. Click **Save & Start**.
7. Open the **Best matches** dataset view and click `applicationUrl` to view the exact original job page.

For the widest useful first run, keep **Broad search** selected. To search only remote roles, choose **Remote jobs**. To inspect specific employers, paste their career or ATS URLs into **Additional company career or ATS URLs**.

### Why Use It? ✨

| Typical job search problem | Job Search & Match Analyzer |
| --- | --- |
| Switching between many company sites | Searches multiple public sources in one run |
| Seeing the same vacancy several times | Deduplicates company + title + location combinations |
| Manually checking every description | Ranks jobs by title, skills, location, arrangement, and freshness |
| Unclear remote eligibility | Separates remote, hybrid, on-site, and remote-region data |
| No easy export | Produces Apify dataset views, JSON, CSV, HTML, and PDF |
| Losing the original application page | Preserves `sourceUrl` and clickable `applicationUrl` |
| Suspicious remote offers | Flags observable warning phrases without declaring a job fraudulent |

### Search Coverage 🌐

The Actor is self-contained and does **not** call another Apify Actor.

#### Broad search

Combines:

- **Jobicy:** curated remote vacancies with required source attribution and direct Jobicy links.
- **Public Greenhouse boards:** a maintained employer catalog including Stripe, Airbnb, Datadog, Cloudflare, Discord, Figma, Reddit, Lyft, Roblox, Duolingo, GitLab, Elastic, MongoDB, Affirm, Okta, Twilio, HubSpot, and Coinbase.
- **Public Ashby and Lever boards:** a maintained international catalog plus Czech-focused employers such as Rohlik, Kiwi.com, Apify, Rossum, Pipedrive, Myriad AI, Duvo, Revel Robotics, OAK'S LAB, Synhawk, and Draslovka.

#### Custom career URLs

Paste up to 30 URLs. The Actor automatically recognizes:

- Greenhouse
- Lever and Lever EU
- Ashby
- SmartRecruiters
- Recruitee
- ordinary career pages exposing schema.org `JobPosting` structured data

For ordinary pages, the Actor follows a bounded number of same-site job/career links. Use the page-limit control to avoid unexpectedly large crawls.

### Recommended Setups 🎯

| Goal | Source coverage | Arrangement | Helpful settings |
| --- | --- | --- | --- |
| Global remote work | Remote jobs | Remote | Add preferred skills and keep location empty |
| Jobs near a city plus remote options | Broad | Any | Enter city and keep “remote outside selected city” enabled |
| Strict local office search | Broad | On-site or Hybrid | Enter city and disable remote-outside-location |
| Search selected employers | Custom only | Any | Paste their ATS/career URLs |
| Salary-transparent roles | Broad | Any | Disable “Keep jobs without published salary” |
| Recent opportunities | Broad | Any | Set posted-within to 7 or 14 days |
| Internship or senior search | Broad | Any | Add the desired experience level |

### Match Scoring 🧠

`matchScore` is deterministic and capped at 100. It uses only evidence found in the input and listing:

- direct or partial title match,
- search keywords in the available description,
- preferred skills found,
- selected location,
- selected workplace arrangement,
- posting freshness,
- published salary information.

The Actor does not claim a candidate will be interviewed or hired. `matchReasons` explains added score; `matchConcerns` records missing salary, date, description, or skill gaps.

When `candidateProfile` is provided, common skills found in that text are used for ranking. Avoid pasting names, addresses, phone numbers, or other unnecessary personal identifiers.

### Remote, Hybrid, and Location Filtering 🏠

The Actor normalizes provider-specific values into:

- `remote`
- `hybrid`
- `onsite`

When a location is entered and **Include remote jobs outside selected city** is enabled, remote roles can remain even if their listed region does not match the city. Always read `remoteRegion` and the original description because “remote” often means remote only within a specific country or time zone.

### Salary Handling 💰

The Actor preserves structured salaries from sources and can detect clearly labeled ranges from descriptions. Text parsing requires an explicit currency or salary context to avoid treating unrelated numbers as compensation.

Output fields include:

- `salaryMin`
- `salaryMax`
- `salaryCurrency`
- `salaryPeriod`
- `salaryText`

For minimum-salary filtering, monthly, weekly, daily, and hourly values are annualized. Currency conversion is not performed, so use `salaryCurrency` when comparisons must be currency-specific.

### Risk Signals 🛡️

The Actor records visible warning signals such as:

- upfront or training-fee language,
- requests for gift cards or cryptocurrency payments,
- reliance on consumer messaging apps,
- unrealistic guaranteed-income language,
- missing employer identity,
- a non-HTTPS application link.

`scamRiskScore` is a screening aid, not a fraud verdict. A low score is not a guarantee that a job or employer is legitimate. Verify the employer domain and never send money to apply.

### Structured Dataset Views 📊

- **Best matches:** score, role, company, location, salary, skills, freshness, risk, and application link.
- **Remote & hybrid jobs:** remote eligibility and work-from-home-focused fields.
- **Jobs with salary:** compensation comparison.
- **All job data:** complete fields for APIs and automation.

The default key-value store also contains:

- `OUTPUT.json`
- `OUTPUT.csv`
- `SEARCH_SUMMARY.json`
- `JOB_SEARCH_REPORT.html`
- `JOB_SEARCH_REPORT.pdf`

### Example Input ⚙️

```json
{
  "keywords": ["software engineer", "backend developer"],
  "location": "Prague",
  "workArrangement": "any",
  "includeRemoteOutsideLocation": true,
  "sourcePreset": "broad",
  "maxResults": 30,
  "datePostedDays": 30,
  "preferredSkills": ["TypeScript", "Node.js", "PostgreSQL", "AWS"],
  "candidateProfile": "Backend engineer experienced with TypeScript, Node.js, SQL, Docker, and cloud infrastructure.",
  "minimumMatchScore": 40,
  "sortBy": "matchScore",
  "includeFullDescription": true,
  "generateJobSearchReport": true
}
````

### Example Output 📦

```json
{
  "jobTitle": "Senior Backend Software Engineer",
  "companyName": "Example Cloud",
  "location": "Europe",
  "workArrangement": "remote",
  "employmentType": "Full-time",
  "experienceLevel": "Senior",
  "matchScore": 87,
  "fitSummary": "Strong match for Senior Backend Software Engineer at Example Cloud. Matched skills: TypeScript, Node.js, PostgreSQL, AWS.",
  "matchReasons": [
    "Job title directly matches: software engineer",
    "Preferred skills found: TypeScript, Node.js, PostgreSQL, AWS",
    "Remote role can be relevant outside the selected city",
    "Posted within the last week"
  ],
  "matchConcerns": [],
  "matchedPreferredSkills": ["TypeScript", "Node.js", "PostgreSQL", "AWS"],
  "missingPreferredSkills": [],
  "salaryMin": 80000,
  "salaryMax": 100000,
  "salaryCurrency": "EUR",
  "salaryPeriod": "year",
  "datePosted": "2026-07-24T09:00:00.000Z",
  "freshnessDays": 2,
  "applicationUrl": "https://company.example/jobs/backend-engineer/apply",
  "sourceUrl": "https://company.example/jobs/backend-engineer",
  "sourceName": "Example Cloud careers",
  "sourceType": "greenhouse",
  "scamRiskScore": 0,
  "scamRiskLevel": "low",
  "scamRiskSignals": []
}
```

### Pricing 💵

Suggested pay-per-event pricing:

| Event | Price |
| --- | ---: |
| Actor start | $0.00005 per GB allocated |
| Exported matched job | $0.003 |
| 1,000 exported jobs | $3.00 |

Pricing uses Apify's synthetic `apify-actor-start` and `apify-default-dataset-item` events. Only rows actually exported to the default dataset are charged as results. Raw jobs removed by keyword, location, date, salary, arrangement, deduplication, or score filters are not charged as results.

This price is intended to cover serverless runtime, source requests, data processing, and optional PDF rendering while remaining inexpensive for personal job searches.

### Run Locally 💻

```bash
npm install
npx playwright install chromium
npx apify-cli run --input-file examples/input-smoke.json
```

Inspect:

- `storage/datasets/default/`
- `storage/key_value_stores/default/`

### Run on Apify ☁️

```bash
npx apify-cli login
npx apify-cli push
```

After deployment, select a sample input, run the Actor, and open the dataset or report links shown on the Output tab.

### Reliability and Limitations ℹ️

- Job availability can change between collection and opening the link.
- No single public source covers every vacancy on the internet.
- The Actor does not claim to scrape LinkedIn, Indeed, Glassdoor, or Google Jobs.
- Source providers can change schemas, rate limits, or terms.
- Some ATS list dates represent updates rather than first publication.
- Remote eligibility is provider-supplied or inferred from explicit public text and should be verified.
- Salaries are not converted between currencies.
- Custom pages without `JobPosting` structured data may return no records.
- Jobicy listings are attributed and link back to Jobicy in accordance with its public API guidance.
- Users are responsible for complying with source terms and local laws when adding custom URLs or using exported data.

### Store SEO Tags 🔍

job search scraper, job finder, remote jobs, work from home jobs, hybrid jobs, career page scraper, Greenhouse jobs scraper, Lever jobs scraper, Ashby jobs scraper, SmartRecruiters scraper, job aggregator, job matching, resume job matcher, salary jobs, software engineer jobs, marketing jobs, job alerts, employment data, vacancy scraper, direct apply jobs

# Actor input Schema

## `keywords` (type: `array`):

Required. Add up to 10 roles, titles, or important skill phrases. Use one role per row. Comma- or semicolon-separated values are also recognized automatically. Multiple keywords are combined into one deduplicated result list.

## `location` (type: `string`):

City, region, or country, for example Prague, Czechia; London; Germany; or United States. Leave empty to search every location.

## `workArrangement` (type: `string`):

Keep all jobs or only remote, hybrid, or on-site roles.

## `includeRemoteOutsideLocation` (type: `boolean`):

When a location is provided, also keep remote roles that may be available from that location. Always verify regional eligibility in the original description.

## `sourcePreset` (type: `string`):

Broad combines remote jobs and the maintained employer catalog. Remote searches Jobicy. Curated searches public company ATS boards. Custom only searches URLs you provide.

## `customCareerUrls` (type: `array`):

Optional. Paste Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, or career-page URLs. Ordinary pages are inspected for schema.org JobPosting data and job links.

## `maxResults` (type: `integer`):

Whole-run result limit after filtering, deduplication, and scoring. Start with 20–50.

## `maxJobsPerSource` (type: `integer`):

Safety limit applied before final cross-source filtering.

## `datePostedDays` (type: `integer`):

Use 0 to disable the date filter. Listings without a source date are retained and clearly marked.

## `jobTypes` (type: `array`):

Optional text values such as Full-time, Part-time, Contract, Internship, Temporary, or Permanent.

## `experienceLevels` (type: `array`):

Optional values such as Entry level, Senior, Internship, Associate, or Leadership.

## `minimumSalary` (type: `number`):

Optional annual threshold in the listing's published currency. Monthly, weekly, daily, and hourly ranges are annualized for comparison. Use 0 to disable.

## `salaryCurrency` (type: `string`):

Optional ISO code such as USD, EUR, GBP, or CZK. Jobs without a published currency are not rejected by this field.

## `includeJobsWithoutSalary` (type: `boolean`):

Disable to create a salary-transparent result list only.

## `mustHaveKeywords` (type: `array`):

Every phrase entered here must appear in the title, category, team, or available description.

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

Remove jobs containing any of these phrases, for example internship, commission only, or security clearance.

## `preferredSkills` (type: `array`):

Optional skills used for ranking, not strict filtering. The output shows matched and missing preferred skills.

## `candidateProfile` (type: `string`):

Optional. Paste a short plain-text summary of skills, tools, seniority, and target role. Do not include sensitive personal identifiers.

## `minimumMatchScore` (type: `integer`):

Use 0 on the first run. Raise after reviewing how scores behave for your niche.

## `sortBy` (type: `string`):

Choose whether the first rows prioritize candidate fit, posting freshness, published salary, or company name.

## `includeFullDescription` (type: `boolean`):

Fetch relevant detail pages when supported. Disable for a faster title-and-link-only run.

## `generateJobSearchReport` (type: `boolean`):

Save a printable report with up to 50 top jobs and clickable original application links in the key-value store.

## `customPageLimit` (type: `integer`):

Safety limit for ordinary non-ATS career websites.

## `requestConcurrency` (type: `integer`):

Number of source or detail requests processed in parallel.

## `requestTimeoutSecs` (type: `integer`):

Maximum time to wait for one public source or job-detail request before retrying.

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

Optional Apify Proxy settings used for ordinary custom career websites. Public ATS APIs normally do not need a proxy.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "location": "Prague",
  "workArrangement": "any",
  "includeRemoteOutsideLocation": true,
  "sourcePreset": "broad",
  "customCareerUrls": [],
  "maxResults": 50,
  "maxJobsPerSource": 100,
  "datePostedDays": 30,
  "jobTypes": [],
  "experienceLevels": [],
  "minimumSalary": 0,
  "salaryCurrency": "",
  "includeJobsWithoutSalary": true,
  "mustHaveKeywords": [],
  "excludeKeywords": [],
  "preferredSkills": [],
  "candidateProfile": "",
  "minimumMatchScore": 0,
  "sortBy": "matchScore",
  "includeFullDescription": true,
  "generateJobSearchReport": true,
  "customPageLimit": 8,
  "requestConcurrency": 5,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `bestMatches` (type: `string`):

Ranked jobs with fit, salary, freshness, and direct application links.

## `remoteJobs` (type: `string`):

Work-from-home opportunities and eligibility regions.

## `salaryView` (type: `string`):

Jobs with published or detected salary ranges.

## `allData` (type: `string`):

Complete structured dataset for automation and API use.

## `csvExport` (type: `string`):

No description

## `jsonExport` (type: `string`):

No description

## `jobSearchPdf` (type: `string`):

No description

## `jobSearchHtml` (type: `string`):

No description

## `searchSummary` (type: `string`):

No description

# 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 = {
    "keywords": [
        "software engineer"
    ],
    "location": "Prague"
};

// Run the Actor and wait for it to finish
const run = await client.actor("feeng/job-search-match-analyzer").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 = {
    "keywords": ["software engineer"],
    "location": "Prague",
}

# Run the Actor and wait for it to finish
run = client.actor("feeng/job-search-match-analyzer").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 '{
  "keywords": [
    "software engineer"
  ],
  "location": "Prague"
}' |
apify call feeng/job-search-match-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=feeng/job-search-match-analyzer",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Job Search & Match Analyzer",
        "description": "💼 Find remote, hybrid, and on-site jobs across public company career boards. Deduplicate vacancies, rank candidate fit, analyze salary and skills, and export direct application links plus a PDF report.",
        "version": "0.1",
        "x-build-id": "OBs04JubUI6Nno6wi"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/feeng~job-search-match-analyzer/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-feeng-job-search-match-analyzer",
                "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/feeng~job-search-match-analyzer/runs": {
            "post": {
                "operationId": "runs-sync-feeng-job-search-match-analyzer",
                "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/feeng~job-search-match-analyzer/run-sync": {
            "post": {
                "operationId": "run-sync-feeng-job-search-match-analyzer",
                "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": {
                    "keywords": {
                        "title": "🔎 Job keyword(s) or title(s)",
                        "minItems": 1,
                        "maxItems": 10,
                        "type": "array",
                        "description": "Required. Add up to 10 roles, titles, or important skill phrases. Use one role per row. Comma- or semicolon-separated values are also recognized automatically. Multiple keywords are combined into one deduplicated result list.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "software engineer"
                        ]
                    },
                    "location": {
                        "title": "📍 Preferred location",
                        "type": "string",
                        "description": "City, region, or country, for example Prague, Czechia; London; Germany; or United States. Leave empty to search every location.",
                        "default": ""
                    },
                    "workArrangement": {
                        "title": "🏠 Workplace arrangement",
                        "enum": [
                            "any",
                            "remote",
                            "hybrid",
                            "onsite"
                        ],
                        "type": "string",
                        "description": "Keep all jobs or only remote, hybrid, or on-site roles.",
                        "default": "any"
                    },
                    "includeRemoteOutsideLocation": {
                        "title": "Include remote jobs outside selected city",
                        "type": "boolean",
                        "description": "When a location is provided, also keep remote roles that may be available from that location. Always verify regional eligibility in the original description.",
                        "default": true
                    },
                    "sourcePreset": {
                        "title": "🌐 Search coverage",
                        "enum": [
                            "broad",
                            "remote",
                            "curated",
                            "custom"
                        ],
                        "type": "string",
                        "description": "Broad combines remote jobs and the maintained employer catalog. Remote searches Jobicy. Curated searches public company ATS boards. Custom only searches URLs you provide.",
                        "default": "broad"
                    },
                    "customCareerUrls": {
                        "title": "🔗 Additional company career or ATS URLs",
                        "maxItems": 30,
                        "type": "array",
                        "description": "Optional. Paste Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, or career-page URLs. Ordinary pages are inspected for schema.org JobPosting data and job links.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "maxResults": {
                        "title": "💯 Maximum exported jobs",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Whole-run result limit after filtering, deduplication, and scoring. Start with 20–50.",
                        "default": 50
                    },
                    "maxJobsPerSource": {
                        "title": "Maximum candidates per source",
                        "minimum": 10,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Safety limit applied before final cross-source filtering.",
                        "default": 100
                    },
                    "datePostedDays": {
                        "title": "🗓️ Posted within the last N days",
                        "minimum": 0,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Use 0 to disable the date filter. Listings without a source date are retained and clearly marked.",
                        "default": 30
                    },
                    "jobTypes": {
                        "title": "Employment types",
                        "type": "array",
                        "description": "Optional text values such as Full-time, Part-time, Contract, Internship, Temporary, or Permanent.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "experienceLevels": {
                        "title": "Experience levels",
                        "type": "array",
                        "description": "Optional values such as Entry level, Senior, Internship, Associate, or Leadership.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "minimumSalary": {
                        "title": "💰 Minimum comparable annual salary",
                        "minimum": 0,
                        "maximum": 100000000,
                        "type": "number",
                        "description": "Optional annual threshold in the listing's published currency. Monthly, weekly, daily, and hourly ranges are annualized for comparison. Use 0 to disable.",
                        "default": 0
                    },
                    "salaryCurrency": {
                        "title": "Salary currency",
                        "type": "string",
                        "description": "Optional ISO code such as USD, EUR, GBP, or CZK. Jobs without a published currency are not rejected by this field.",
                        "default": ""
                    },
                    "includeJobsWithoutSalary": {
                        "title": "Keep jobs without published salary",
                        "type": "boolean",
                        "description": "Disable to create a salary-transparent result list only.",
                        "default": true
                    },
                    "mustHaveKeywords": {
                        "title": "✅ Required words or skills",
                        "type": "array",
                        "description": "Every phrase entered here must appear in the title, category, team, or available description.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "excludeKeywords": {
                        "title": "🚫 Excluded words",
                        "type": "array",
                        "description": "Remove jobs containing any of these phrases, for example internship, commission only, or security clearance.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "preferredSkills": {
                        "title": "🧩 Preferred skills",
                        "type": "array",
                        "description": "Optional skills used for ranking, not strict filtering. The output shows matched and missing preferred skills.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "candidateProfile": {
                        "title": "Candidate profile or resume summary",
                        "type": "string",
                        "description": "Optional. Paste a short plain-text summary of skills, tools, seniority, and target role. Do not include sensitive personal identifiers.",
                        "default": ""
                    },
                    "minimumMatchScore": {
                        "title": "Minimum match score",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Use 0 on the first run. Raise after reviewing how scores behave for your niche.",
                        "default": 0
                    },
                    "sortBy": {
                        "title": "Sort final jobs by",
                        "enum": [
                            "matchScore",
                            "datePosted",
                            "salaryMax",
                            "company"
                        ],
                        "type": "string",
                        "description": "Choose whether the first rows prioritize candidate fit, posting freshness, published salary, or company name.",
                        "default": "matchScore"
                    },
                    "includeFullDescription": {
                        "title": "📄 Include available full descriptions",
                        "type": "boolean",
                        "description": "Fetch relevant detail pages when supported. Disable for a faster title-and-link-only run.",
                        "default": true
                    },
                    "generateJobSearchReport": {
                        "title": "Generate HTML & PDF job report",
                        "type": "boolean",
                        "description": "Save a printable report with up to 50 top jobs and clickable original application links in the key-value store.",
                        "default": true
                    },
                    "customPageLimit": {
                        "title": "Pages inspected per custom website",
                        "minimum": 1,
                        "maximum": 30,
                        "type": "integer",
                        "description": "Safety limit for ordinary non-ATS career websites.",
                        "default": 8
                    },
                    "requestConcurrency": {
                        "title": "Concurrent source requests",
                        "minimum": 1,
                        "maximum": 15,
                        "type": "integer",
                        "description": "Number of source or detail requests processed in parallel.",
                        "default": 5
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout in seconds",
                        "minimum": 5,
                        "maximum": 90,
                        "type": "integer",
                        "description": "Maximum time to wait for one public source or job-detail request before retrying.",
                        "default": 30
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional Apify Proxy settings used for ordinary custom career websites. Public ATS APIs normally do not need a proxy.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
