# Company Jobs Scraper | $1/1K Starter | Careers & Hiring Monitor (`x_guru/company-careers-jobs-scraper`) Actor

Collect company jobs from websites, career links or verified collections across six ATS platforms. Filter roles, dates and published pay, export flat CSV, resume batches and monitor hiring changes with employer coverage reports.

- **URL**: https://apify.com/x_guru/company-careers-jobs-scraper.md
- **Developed by:** [Hundevmode Labs](https://apify.com/x_guru) (community)
- **Categories:** Jobs, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 94.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Company Careers Jobs Scraper — Greenhouse, Lever, Ashby, Workable, Recruitee & Personio

**Export company jobs for $1 per 1,000 results on Starter. Enter company websites, filter roles and locations, and monitor hiring changes on a schedule.**

Collect published vacancies directly from Greenhouse, Lever, Ashby, Workable, Recruitee and Personio career boards. Get job descriptions, application links, locations and available structured salary data in one dataset. No extra job-data subscription or API key is needed for the supported publicly accessible feeds. Recruitee access is verified on public hosted career sites; private or access-restricted feeds are reported unavailable.

Use it for company hiring research, recruitment workflows, a job feed for selected employers or alerts when their published openings change. Search your own company list or one of the small verified collections below. Coverage is limited to selected supported employer boards.

### Start collecting jobs

1. Fill **Company websites or career pages** with your employer list. Mix domains, career pages and direct ATS board URLs; use **Bulk edit** to paste several entries.
2. In **What would you like to collect?**, choose **Current jobs** or **Hiring changes**. Set **Maximum results**.
3. Optionally open **Job filters** to narrow roles, locations, countries or source-confirmed work arrangements. Countries show readable names; JSON/API inputs keep two-letter codes.
4. Run, then open **Run report** for employer coverage, exclusions, delivered/pending rows and next steps. Download **Flat CSV for imports**, or export JSON/Excel from the dataset.

For an explicit preview, open **Example companies** and choose **Example: 5 companies** or **Example: 3 AI companies**. These are small fixed examples charged at the same published rates. The normal form starts with no employers selected. It never adds a demo employer automatically. For **Hiring changes**, use a saved Task or stable Monitor ID; setup is in **Monitoring and continuation**.

```json
{
  "companies": [
    "greenhouse.com",
    "Ashby",
    "https://jobs.lever.co/applydigital"
  ],
  "maxResults": 100
}
```

A direct ATS board URL is the most reliable input. A supported job detail URL containing an employer board token selects its entire board. Workable links shaped `/j/<shortcode>` do not identify an employer; supply `https://apply.workable.com/<company>` or the company website instead. For employers outside the verified directory, company-domain discovery checks a bounded number of public pages for supported links, including some embedded boards. JavaScript-only or unrelated career systems can require a direct board URL. Unrecognized names are reported with a request for the company's website; the Actor does not guess ATS identifiers from names. Resolved inputs continue collecting when other names are unresolved, and coverage is marked incomplete.

### Verified employer collections

Employer websites were checked for links to live public boards on **October 6, 2026**. That date verifies the source mapping; every collection run reads vacancies live. These are bounded employer lists, not a complete industry or worldwide jobs database.

| Selection | Employers | JSON value |
|---|---|---|
| None — use my company list | Your own domains and public career URLs | `none` (default) |
| Example: 5 companies | Greenhouse, Ashby, ENTITY X, OpenAI, Anthropic | `starter-5-v1` |
| Example: 3 AI companies | OpenAI, Anthropic, Cohere | `ai-3-v1` |

These six distinct employers also support name input. For other employers, enter a website or career URL. Root domains in the verified directory resolve directly to their boards. Explicit career paths retain normal discovery. Employer identity added by the directory is marked `companyNameSource: "verified_catalog"` when it is not supplied by the job feed itself.

```json
{
  "companyCollection": "ai-3-v1",
  "titleKeywords": ["engineer"],
  "locationKeywords": ["London"],
  "maxResults": 100
}
```

You can add `companies` alongside a collection. Sources share one global result limit and duplicate boards are collected once. Free accounts retain the five-source limit; adding a sixth distinct source to Example: 5 companies requires a paid account. Requested result counts are ceilings: filters and source availability can yield fewer jobs. Large boards may be read in full before filtering even when you request a small output.

Each collection version keeps a fixed employer list for saved Tasks and schedules. Adding employers requires selecting another collection/version or editing your own list, which starts a separate monitor baseline. A closed or failing board is reported as unavailable; it does not silently disappear from the collection or create false job removals. Continuations restore the original source list and employer context.

**Existing API inputs and Tasks:** `startUrls` and `companyDomains` remain accepted JSON aliases and merge with the new `companies` list and collection. They are shown in the collapsed **Existing Task inputs** section. The Run report warns when they are active. When editing an old Task, remove any old example sources you no longer want. For a fresh setup, use `companies` or `companyCollection`.

Recruitee example: `"companies": ["https://channable.recruitee.com"]`. Custom Recruitee domains need a discoverable hosted-board link; use the public board URL if website discovery cannot find it.

Workable example: `"companies": ["https://apply.workable.com/huggingface"]`. Employer identity comes from the public feed, and complete descriptions are included without a per-job detail request. Unsupported or unavailable accounts are reported explicitly.

Personio example: `"companies": ["https://entityx.jobs.personio.de"], "personioLanguage": "en"`. Matching `.jobs.personio.de` and `.jobs.personio.com` company tokens are collected once. The employer must enable its public XML feed. Choose English, German, French, Spanish, Dutch, Italian or Portuguese; available translations depend on the employer. This option controls XML requests even when an input URL includes a language query.

### Find the jobs you want

| Input | Behavior |
|---|---|
| `titleKeywords` / `titleMatchMode` | Literal case-insensitive phrases in the title. Multiple entries match ANY by default; ALL requires every entry. Quotes and Boolean operators have no special syntax. |
| `descriptionKeywords` | ANY literal phrase in the published description, in addition to title filters. The query is never broadened silently. |
| `excludeTitleKeywords` | Exclude titles containing any term. |
| `locationKeywords` | Match ANY published main or additional location label. A phrase must occur within one label, not across separate offices. |
| `countries` | Match ANY structured source country, including additional Ashby/Workable offices. Readable country selection in the form; JSON/API keeps two-letter codes such as US or GB. |
| `workplaceTypes` | ANY selected remote, hybrid or onsite classification from the source. Legacy `remoteOnly` remains accepted. |
| `employmentTypes` | Full-time, part-time, contract, temporary, internship or freelance, normalized from published classifications. Personio uses both contract kind and schedule: a full-time internship can match either selection. Permanent alone does not establish hours. |
| `departmentKeywords` | ANY phrase in the published department. |
| `postedWithinDays` | Source publication within the last N days; 0 means any date. Missing dates are excluded unless explicitly included. |
| `minSalary`, `salaryCurrency`, `salaryPeriod` | At least one published pay tier has a lower bound at or above the minimum in the exact selected currency and period. Currency and period are required; no conversion or annualization. |

Unknown country, work arrangement and publication date can be included explicitly with `includeUnknownCountry`, `includeUnknownWorkplace` and `includeUnknownPublicationDate`. The underlying fields remain unknown. Greenhouse location text is preserved without guessing a country or remote flag. Remote classification does not establish permission to work from any country; a salary tier is not evidence of location eligibility. `remoteOnly` and an incompatible `workplaceTypes` selection are rejected.

Different filter fields must all match (AND); multiple values within one field match ANY, except titles when ALL is selected. Entries containing only whitespace are rejected before requests. Pay totals covering multiple units, such as `2 YEAR`, are incomparable with a single-year filter and are excluded rather than converted.

The **Run report** explains exclusions, including unknown fields and incomparable salaries. Reason counts can overlap, so their sum can exceed the number of excluded jobs. Monitor board checks still have a fee when filters produce no changes.

```json
{
  "companies": ["https://jobs.ashbyhq.com/openai"],
  "titleKeywords": ["engineer"],
  "workplaceTypes": ["remote", "hybrid"],
  "minSalary": 100000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "maxResults": 100
}
```

### Sample several employers

Results normally follow employer input order. A large first employer can fill the global limit; results are not the globally newest jobs. For a bounded export sample, set `maxResultsPerCompany`, for example 20 per employer and 100 total across five employers. The cap is applied **after filters**, per employer board, across continuations. Set it to 0 for no per-company cap.

This cap intentionally omits additional matches. The Run report shows those omissions, delivered/pending counts and source inputs not visited yet. `coverageComplete` describes completion of source checks and requested delivery; `inventoryComplete` is false when matching inventory was omitted by company caps. Start a new collection without the per-company cap for full inventory. Monitor rejects nonzero per-company caps: it uses complete snapshots and saves every undelivered change for continuation.

### What you get

| Fields | Meaning |
|---|---|
| `jobKey`, `jobId`, `provider`, `boardId` | Stable source identity and board reference. |
| `title`, `companyName`, `companyDomain` | Published title and employer identity when verified. |
| `url`, `applyUrl`, `boardUrl` | Posting, application and employer board links. |
| `location`, `locations`, `country`, `countries`, `countryLabel` | Published locations, primary/all structured country codes and original primary label. |
| `department`, `employmentType`, `workplaceType`, `isRemote` | Available source classifications. |
| `employmentSchedule` | Personio's source-published full-time/part-time hours, separate from its contract kind. Other providers leave this absent or null. |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | A single unambiguous structured salary range, when available. |
| `salaryRanges` | Separate published pay ranges, preserving geographical tiers. |
| `description`, `descriptionHtml` | Plain text description; optional original HTML. |
| `sourcePublishedAt`, `sourceUpdatedAt`, `checkedAt`, `firstSeenAt` | Source dates and Actor observation dates. |
| `changeType`, `changedFields`, `previousValues`, `matchesFilter` | Monitoring event, changed values and current filtered-inventory membership. |

Missing scalar fields remain null; absent ranges and locations use empty arrays. Flat salary fields remain null when there are multiple pay tiers. Greenhouse bulk collection retains salaries written in descriptions but does not fetch individual pay-transparency endpoints. Recruitee descriptions include the requirements section; available salary strings are normalized to numbers, and published multi-location labels are retained. Personio descriptions retain all published sections and additional offices; `subcompany` supplies employer identity when present. Personio XML does not establish structured salary, country, remote status or publication time; these fields remain null rather than being inferred from office text or `createdAt`. Lever creation dates are not presented as publication dates; Ashby publication time means the last publication. `firstSeenAt` is the first observation in this Monitor baseline, not the opening date. A fresh export uses its current observation time. Workable uses `published_on`, never `created_at`; date-only values are interpreted as midnight UTC for date filtering. Workable salaries are not extracted or guessed from descriptions. A false Workable telecommuting flag does not classify a role as on-site rather than hybrid.

Each row represents a published source posting, not a headcount estimate; separate postings may describe the same role in different locations. A board slug is not a verified company name. Direct Lever/Ashby boards may lack employer names and domains; discovery can add identity from the company's own linked site. This Actor does not collect applicant records or employee contact data.

#### Tables, CSV and integration

The Output tab offers **Jobs**, **Salaries**, **Hiring changes** and **CSV / import fields** views. Views change the displayed columns; they do not change the underlying dataset or add charges. **Download flat CSV for imports** explicitly selects flat fields: stable key, employer, all location/country labels, salary amounts plus currency/period, readable separate pay tiers, dates, application link and plain-text description. Full JSON retains `locations`, `countries`, `salaryRanges`, `changedFields` and `previousValues`.

A salary with several geographic tiers keeps scalar min/max/currency null. `salaryText` displays the individual published tiers and periods; it never merges different currencies into a fabricated range. Use `jobKey` for upserts within a source board. A migration between ATS platforms can change that key; no cross-platform duplicate identity is promised.

### Continue a capped or interrupted collection

Open **Next batch input** (`PAGINATION`) and copy `nextInput` into a new run after the previous run finishes. It supplies `continueFromRunId` and a batch size. In **Example companies**, leave **None — use my company list** selected and omit `companies`, `startUrls` and `companyDomains`: the Actor restores the previous sources, filters and remaining jobs. Already delivered rows are not copied into the new dataset. Cached remaining rows can be delivered without refetching their board. Completed Lever pages survive request limits and temporary export failures such as timeouts, 403, 429 and server errors. Before continuing, the Actor rechecks the last committed page. If its IDs shifted, that source starts again and already delivered export rows are deduplicated. This detects observed offset drift; it cannot guarantee an atomic view of a continuously changing board. If IDs repeat across offsets on a changing Lever board, the Actor attempts one complete public API response with the same bounded download/job/time limits. If that response cannot validate, coverage stays incomplete instead of guessing past missing jobs. Continuation finishes the original observations; start a fresh collection for a new live check.

Each batch has its own dataset and spending limit. The previous run must belong to this Actor and your account. Check `RUN_SUMMARY.coverageComplete`, `stopReason` and `ERRORS` even when the run status is successful: request limits, source errors or unavailable career pages can produce partial coverage. Slow or oversized Lever pages are reduced without advancing past undelivered postings. Smaller pages require more requests; saved page progress can continue in the next batch if the request limit is reached. Fresh sources are processed before failed-source retries. Temporary failures use increasing delays; persistent problems such as missing boards, repeated pages or oversized responses wait an hour before continuation retries. Inspect `RUN_SUMMARY.retryNotBefore` (UTC) and `deferredSourceCount` before retrying. A new export collection makes a fresh check of the supplied sources. Repeated checks of the same Monitor keep source-specific retry pauses, including long server Retry-After delays. Starting another run cannot guarantee recovery from a persistent 403, 429 or unavailable source.

Free accounts have a collection-wide trial cap; continuing does not reset it. `nextInput` is unavailable after that cap is reached. Unsupported-domain discovery needs a corrected input or a direct supported board URL.

### Monitor hiring changes automatically

Select **Hiring changes** under **What would you like to collect?**. Save an Apify Task and add an Apify schedule, or provide a stable `monitorId` for repeated manual/API runs. Saved Tasks use their Task ID automatically. No explicit previous snapshot is needed.

- `CURRENT`: matching jobs in the first successful baseline, unless `emitInitialResults` is false.
- `NEW`: a job first appearing after the baseline.
- `CHANGED`: substantive published fields differ from the last delivered snapshot. Source publication/update dates remain in results but timestamp-only updates do not create paid change rows by default. Enable `monitorSourceDateChanges` to include them.
- `REMOVED`: a posting disappeared from a successfully checked board.
- `REOPENED`: the same source posting ID returns after an observed removal retained within 90 days.

For a filtered monitor, `ENTERED` means an existing posting now matches your filters; `EXITED` means it no longer matches, although it can still be open. Publication-date filters can produce EXITED when a posting ages out. `REMOVED` means it disappeared from a complete successful source check after belonging to your filtered inventory. No duplicate removal is emitted for a posting that already exited. `NEW`/`REOPENED` describe source appearance/observed reopening; `CHANGED` describes changes while still matching.

To maintain a filtered job feed, upsert CURRENT, NEW, REOPENED, ENTERED and CHANGED by `jobKey`; delete that key on EXITED or REMOVED (`matchesFilter: false`). Events carry `previouslyMatchedFilter`, `changeReason`, changed fields and observation time. Internal matching state is never included in the dataset. Failed/incomplete checks never emit false exits or removals. Continuation keeps the original observation and queued events; start a fresh poll for a new check.

Removal does not establish that a person was hired. Source errors and malformed postings preserve the previous successful board snapshot and do not emit false removals. Export mode can return the valid postings from a board with malformed records; skipped records are counted separately and coverage remains incomplete. Monitor requires the whole board to validate before charging a successful check or replacing its snapshot. A board's new snapshot is committed after its inventory-change events have been delivered; capped work is saved. Repeated runs of the same Task/monitor finish capped, undelivered work before starting a fresh poll. If only failed-board retries remain, the next scheduled poll checks healthy sources again while unavailable sources wait until their saved retry time; manual continuation can retry just the failed boards. Paused sources have status `deferred` in `SOURCE_CHECKS`, with `retryNotBefore`; failed checks include their code and any saved export page offset. Neither a skipped source nor a failed check incurs a successful board-check fee. Use `PAGINATION.nextInput` when manually finishing a batch.

Use separate monitor IDs for independent collections. Overlapping runs are rejected, and an old continuation cannot replace a newer committed snapshot. Changing sources, filters or other monitor options creates a separate baseline. Keep your selected order/options stable between checks. Versioned collections preserve their employer membership; their live vacancy counts may change.

### Pricing

Native Apify PPE rates are configured as follows:

| Apify plan | Per 1,000 delivered job/change rows | Per 1,000 successful monitor board checks |
|---|---:|---:|
| Free | $2.00 | $10.00 |
| Starter | $1.00 | $5.00 |
| Scale | $0.90 | $5.00 |
| Business and higher | $0.80 | $5.00 |

Export mode charges job rows only. Changes mode charges one successful complete check per board, plus each delivered inventory-change row, including ENTERED and EXITED. Removed rows use the same existing job-result rate. An unchanged check or silent baseline still incurs the board-check fee. A cached continuation does not charge that check again. Errors, discovery reports and summaries incur no job-result fee.

Apify additionally applies a **$0.00005 fee per execution start**, including resurrection of an existing run, at this Actor's supported 256–1,024 MB memory settings. There is no extra description, salary-enrichment or duplicate dataset-item fee.

Starter examples: 1,000 export rows cost $1.00 plus startup. One unchanged board check costs $0.00505 including startup. Ten board checks and 25 returned changes cost $0.07505 including startup. A Free-plan preview of 100 export rows costs $0.20005 from available credits. The minimum run spending limit is $0.00505; this is a cap setting, not a fixed additional fee. Confirm your plan's prices and run spending limit in Apify before running.

### Result limits and spending protection

`maxResults` is the global delivered-row limit, not a guaranteed number of available jobs. Paid accounts can request up to 50,000 rows per run and 200 source inputs. Free accounts receive a preview of at most 5 source inputs and 100 delivered rows per collection, shared across continuations. Payment status comes from Apify, not user input. Free request/time caps also apply.

For a large collection, set your sources and use the following limits in the initial run. Above 50,000 rows, finish each batch and use **Next batch input** to continue. Each batch has a separate dataset; combine the exports by `jobKey`. For long batches, also increase the Apify run timeout; `maxRunSeconds` bounds source work and does not override the platform execution timeout. Source availability, request limits and your spending cap can produce fewer rows.

```json
{
  "maxResults": 50000,
  "advanced": { "maxRequests": 2000, "maxRunSeconds": 1800 }
}
```

Apify's run spending limit can stop output before `maxResults`. Remaining work is checkpointed when the Actor can shut down normally. Platform-enforced account limits and hard termination can interrupt a run; use the saved checkpoint and inspect coverage rather than assuming a complete collection.

### Advanced settings

Defaults: 20-second request timeout, up to 2 retries for temporary connection errors/429/5xx, 250 requests, 600 seconds of source work, 6 discovery pages per input and 20,000 jobs per board. Free accounts cap source work at 40 requests and 180 seconds. Paid request/time limits can be increased within the runtime schema; source work remains bounded.

```json
{
  "advanced": {
    "requestTimeoutSeconds": 20,
    "maxRetries": 2,
    "maxRequests": 250,
    "maxRunSeconds": 600,
    "maxDiscoveryPages": 6,
    "maxJobsPerBoard": 20000
  }
}
```

A supported board exceeding `maxJobsPerBoard` is reported incomplete instead of being used as a partial monitor snapshot. Arbitrary ATS, Workday sites and generic HTML vacancy extraction are outside current coverage.

Greenhouse, Ashby, Workable and Recruitee JSON responses are downloaded to a temporary file and parsed one posting at a time, with a 256 MiB decoded-download ceiling. Personio XML uses the same disk-backed 256 MiB ceiling and an incremental parser that rejects DTDs and entity declarations. In-memory pages and discovery responses have a 32 MiB ceiling. Exceeding the relevant limit is reported as `response_too_large`; other sources can finish and Monitor preserves the failed board's last successful snapshot. Large saved collections use encrypted parts rather than one oversized checkpoint.

For HTTP 429 responses, the Actor respects the server's `Retry-After` delay. If that delay exceeds the bounded wait or remaining run time, it saves an incomplete result for later continuation and retains the server delay in `RUN_SUMMARY.retryNotBefore`. No repeat-run guarantee is made for persistent blocking or unavailable sources.

### Output reports

**Run report** (`REPORT`) is a readable HTML summary of companies, source checks, applied filters, exclusions, delivered/pending counts, billing units and continuation. `COVERAGE` provides the structured equivalent. `RUN_SUMMARY` contains coverage, inventory completeness, stop reason, result counts and request metrics. `ERRORS` records source/input problems. `DISCOVERY` shows board discovery. `SOURCE_CHECKS` documents checked sources, including `partial` exports with counts of valid and skipped postings. `successfulSourceChecks` counts only complete source checks. `PAGINATION` supplies the next batch input. These reports are stored separately from the paid jobs dataset.

### Public source documentation

- [Greenhouse Job Board API](https://docs.greenhouse.io/job-board.html)
- [Lever Postings API](https://github.com/lever/postings-api)
- [Ashby Job Postings API](https://developers.ashbyhq.com/docs/public-job-posting-api)
- [Recruitee public offers endpoint](https://docs.recruitee.com/reference/offers)
- [Workable public career endpoints](https://help.workable.com/hc/en-us/articles/115012771647-Using-the-Workable-API-to-create-a-careers-page)
- [Personio public XML jobs](https://developer.personio.de/v1.0/reference/get_xml)
- [Apify PPE and spending limits](https://docs.apify.com/actors/publishing/monetize/pay-per-event)

# Actor input Schema

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

One company per entry. Accepts domains such as greenhouse.com, full career-page links and direct Greenhouse, Lever, Ashby, Workable, Recruitee or Personio board URLs. Paste a list with Bulk edit. Discovery is bounded; a direct board URL is most reliable. Names work only for the six employers listed under Example companies. Duplicate boards are collected once.

## `mode` (type: `string`):

Current jobs exports matching published openings. Hiring changes compares complete board snapshots and returns new, changed, removed, reopened and filter-entry/exit events. Use a saved Task or stable Monitor ID for repeat checks. Each successful Monitor board check has a fee, including unchanged checks; delivered rows have the published job-result price. Setup is under Monitoring and continuation.

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

Total rows delivered in this run, across all employers. Results follow source order, not a global newest-first ranking. Use the optional per-company cap for a broader export sample and inspect the Run report for employers not checked yet. Paid: up to 50,000; Free: 100 per collection, shared across continuations. Spending/request/time limits may stop earlier.

## `titleKeywords` (type: `array`):

Literal case-insensitive text in the title. One entry is one phrase: software engineer requires those adjacent words. Multiple entries match ANY by default; choose ALL below to require every entry. Quotes and Boolean operators have no special syntax. Queries are never broadened silently.

## `titleMatchMode` (type: `string`):

ANY = engineer OR sales. ALL = every entry must occur in the title. Each entry is a literal phrase.

## `excludeTitleKeywords` (type: `array`):

Exclude titles containing any of these terms.

## `descriptionKeywords` (type: `array`):

ANY literal entry must occur in the published description. Applied in addition to title/location filters; does not expand a title search. Unknown descriptions do not match.

## `locationKeywords` (type: `array`):

Optional: match published location labels, for example London, California or Remote. Leave empty for all locations. Matching Remote does not establish eligibility to work from every country.

## `countries` (type: `array`):

Choose one or more countries; any selected source-published country matches, including structured additional offices. Leave empty for all countries. JSON/API uses two-letter codes such as US and GB; existing lowercase codes still work. Unknown countries are excluded unless enabled below. Remote status does not establish work eligibility.

## `includeUnknownCountry` (type: `boolean`):

Applies only when a country filter is active. Unknown stays null; this does not establish geography or work eligibility.

## `workplaceTypes` (type: `array`):

Leave empty for any arrangement. Multiple selections match ANY. Uses structured source fields only; unknowns are excluded when a selection is active unless included below.

## `includeUnknownWorkplace` (type: `boolean`):

Applies only when a work-arrangement filter is active. Unknown is preserved in output; it is not classified as remote or on-site.

## `employmentTypes` (type: `array`):

ANY selected type, normalized from published source values. Personio uses both contract kind and full-time/part-time schedule; a full-time internship can match either selection. Unknown classifications are excluded when active. Internship does not guarantee zero experience.

## `departmentKeywords` (type: `array`):

Match ANY literal phrase in the published department. Unknown departments do not match.

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

0 = any date. Uses source publication time, not source update time or our observation date. Ashby publishes the last publication date. Some providers do not expose publication dates. In Monitor, aging out generates EXITED and never claims the job closed.

## `includeUnknownPublicationDate` (type: `boolean`):

When a publication-date filter is active, include jobs whose publication date is not supplied. Unknown remains null.

## `minSalary` (type: `number`):

Optional. At least one published pay tier must have its lower bound at or above this amount in the chosen currency and period. Currency and period are required. No conversion or pay estimation. Missing/incomparable ranges are excluded. A matching tier does not establish location eligibility.

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

Required with minimum salary. Three-letter currency, e.g. USD, GBP or EUR. No currency conversion.

## `salaryPeriod` (type: `string`):

Required with minimum salary. Only comparable source-published periods match; no annualization.

## `maxResultsPerCompany` (type: `integer`):

0 = no per-company cap. For a sample across 5 employers, try 20 here and 100 total. Applied after filters, per employer board, across continuations. Omitted matches are not collected later; start a new collection without the cap for full inventory. Monitor rejects nonzero values so no change events are lost.

## `companyCollection` (type: `string`):

Example: 5 companies = Greenhouse, Ashby, ENTITY X, OpenAI and Anthropic. Example: 3 AI companies = OpenAI, Anthropic and Cohere. Jobs are read live. Any companies entered above are added to the selected example and duplicate boards are collected once. Free accounts allow five sources per collection. JSON values stay none, starter-5-v1 and ai-3-v1 for existing Tasks/API.

## `monitorId` (type: `string`):

Use the same ID for repeated checks. Saved Apify Tasks use their Task ID automatically. Separate IDs isolate monitors. Do not overlap runs of the same monitor. Changing sources or filters creates a new baseline. Failed sources keep their retry pauses between checks; healthy sources continue updating. Versioned collections keep a fixed employer list between scheduled checks.

## `emitInitialResults` (type: `boolean`):

Disable to create a silent baseline. Successful board checks still have a cost in monitor mode. Subsequent checks return changes.

## `monitorSourceDateChanges` (type: `boolean`):

Also return CHANGED when only source publication/update dates change. Disabled by default to avoid timestamp-only alerts and job-result fees. Available dates remain in all returned rows.

## `continueFromRunId` (type: `string`):

Use PAGINATION.nextInput after the previous run finishes. Sources and filters are restored. Completed Lever pages survive limits and temporary network errors; the last saved page is rechecked and a shifted source restarts with deduplication. Fresh sources run before failed retries. Check retryNotBefore before retrying. Previously delivered rows are not copied.

## `includeDescriptionHtml` (type: `boolean`):

Plain text descriptions are always included when published. Enable HTML for your own rendering.

## `personioLanguage` (type: `string`):

Language requested from Personio XML only, including URLs that have their own language query. Available translations depend on the employer. Other providers retain their published language. Changing this option creates a new monitor baseline.

## `advanced` (type: `object`):

Optional request and time caps. Defaults: 250 requests and 600 seconds; paid maxima: 2000 requests and 1800 seconds. For large collections, increase these in the initial run. Free accounts have lower limits. These settings can produce a partial collection; inspect the coverage summary and Next batch input.

## `startUrls` (type: `array`):

Existing URL inputs are still collected and merged with Companies. Check this list when editing an older Task; remove old examples you no longer want. New setups should use the Companies field above.

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

These existing inputs are still collected and merged with Companies. Leave empty for a new setup. Remove unwanted old examples here.

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

Legacy shortcut for Remote. Uses source facts; unknowns are excluded unless explicitly included below. Greenhouse often has no structured remote flag. This does not establish worldwide eligibility.

## Actor input object example

```json
{
  "companies": [
    "https://jobs.ashbyhq.com/openai",
    "https://apply.workable.com/huggingface"
  ],
  "mode": "export",
  "maxResults": 5,
  "titleMatchMode": "any",
  "includeUnknownCountry": false,
  "includeUnknownWorkplace": false,
  "postedWithinDays": 0,
  "includeUnknownPublicationDate": false,
  "maxResultsPerCompany": 0,
  "companyCollection": "none",
  "emitInitialResults": true,
  "monitorSourceDateChanges": false,
  "includeDescriptionHtml": false,
  "personioLanguage": "en",
  "remoteOnly": false
}
```

# Actor output Schema

## `report` (type: `string`):

No description

## `dataset` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `pagination` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `discovery` (type: `string`):

No description

## `sourceChecks` (type: `string`):

No description

## `sourceSelection` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `coverage` (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 = {
    "companies": [
        "https://job-boards.greenhouse.io/greenhouse"
    ],
    "maxResults": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("x_guru/company-careers-jobs-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 = {
    "companies": ["https://job-boards.greenhouse.io/greenhouse"],
    "maxResults": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("x_guru/company-careers-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "companies": [
    "https://job-boards.greenhouse.io/greenhouse"
  ],
  "maxResults": 5
}' |
apify call x_guru/company-careers-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,x_guru/company-careers-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tk0BbeZJLtbIfjxl1/builds/6sh0AvMo5hWZW3cpA/openapi.json
