# Changelog of ATS Jobs Hiring Signals: Greenhouse, Lever & Ashby API (`optimistprime/ats-jobs-hiring-signals`) Actor

- **URL**: https://apify.com/optimistprime/ats-jobs-hiring-signals/changelog.md
- **Full Actor documentation**: https://apify.com/optimistprime/ats-jobs-hiring-signals.md

## Changelog

### 1.0 (2026-10-03, Greenhouse details)

- Greenhouse job rows now always have `department` and office `locations`, also with `descriptionFormat: "none"`. The board is always fetched with `content=true` (still one request per board; `pay_transparency=true` salaries unchanged). With `descriptionFormat: "none"` the description HTML is dropped right after download and never output.
- Compared with fetching `/departments` + `/offices` separately: that was 5x larger for Stripe (29.6 MB vs 5.5 MB) because `/offices` repeats every department under every office, and sometimes assigned a different department than the job itself, so it was not used.

### 1.0 (2026-10-03, employment type default)

- **Behaviour change:** with `employmentTypes` set, jobs whose employment type is unknown (`employmentType: null`, e.g. most Greenhouse boards) are now kept by default.
- New `includeUnknownEmploymentType` (default `true`); set it to `false` for a strict filter. Listing `unknown` in `employmentTypes` still keeps them.
- `excludeKeywords` still match the title only.
- Fix: Greenhouse returns departments and offices only together with job content. The Actor now requests it (same single request, no extra charge) whenever `departments`, `locationContains` or a company summary needs them, even with `descriptionFormat: "none"`. Before, these filters dropped all Greenhouse jobs and summaries had empty `topDepartments` in that case.

### 1.0 (2026-10-03, filters)

- New filters (all optional; defaults change nothing):
  - `departments`: case-insensitive match on department or team.
  - `employmentTypes`: `full_time`, `part_time`, `contract`, `intern`, `temporary`, `other`, `unknown`.
  - `keywordScope`: `title` (default) or `title_and_description`. Description matching works with every `descriptionFormat`, including `none`.
- `matchingJobs` in summaries reflects the new filters; other summary stats stay board-wide.
- The `job` event is still charged only for rows output after all filters.
- Greenhouse `employmentType` is now filled when a board publishes it as custom metadata (e.g. "Time Type"); previously always null.

### 1.0 (2026-10-03, update)

- Monitor mode + `outputMode: "summary_only"` no longer touches the seen-jobs list (no `job_removed` rows). Run a jobs pass to advance monitoring.
- Documented: summary stats are board-wide (except `matchingJobs`), capped new jobs stay new, the EU Lever fallback is for bare slugs only, and Greenhouse salary mapping.

### 1.0 (2026-10-03)

- First release: Greenhouse, Lever (global + EU) and Ashby official public job-board APIs.
- Bare-slug auto-detection across all three ATSs (parallel), board URL / API URL parsing.
- Normalized, typed job rows (all keys always present), salary normalized to annual (`minAnnual`/`maxAnnual`).
- Greenhouse pay ranges via `pay_input_ranges` (`min_cents`, `max_cents`, `currency_type`, `title`, `blurb`).
- Output modes: jobs, jobs + company hiring-signal summary, summary only.
- Filters: title keywords, exclude keywords, location, remote only, posted within N days; per-company and global caps.
- Monitor mode (`onlyNewJobs` + `monitorId`): only new jobs + `job_removed` rows.
- Pay-per-event: `job`, `company-summary`, `company-checked` (monitor mode) + platform `apify-actor-start`.
- Polite fetching: 2 req/s per API host (burst 4), global concurrency 10, retries with exponential backoff, Retry-After honoured.

### 1.0.9 (2026-10-03)

- README: "Ready-to-run examples" section with published example tasks (one-click Try), copy-paste JSON inputs and real output excerpts. No code or pricing changes.

### 1.0.10 (2026-10-03)

- Fix: Greenhouse `remoteShare` was always 1 (Greenhouse jobs were only ever `remote` or unknown, and the share was taken over known jobs only). Stripe showed 1.0 across 716 jobs. Greenhouse share is now clearly-remote jobs / all jobs (Stripe: 0.05).
- Fix: Greenhouse `workplaceType` is `remote` only when every location in the location name says remote (`US-Remote`, `Remote US`, `Poland - Remote OR Romania - Remote`). Office lists that also mention remote (`SF, NYC, Seattle, Remote`) are now null (unknown) and are no longer returned by `remoteOnly`. Lever and Ashby are unchanged (they publish a workplace field).
- README: new "How to" section and a comparison FAQ entry (no competitors named), copy from Product Lead.
- Tests: real Stripe board fixture (715 jobs) -> 35 remote, remoteShare 0.05; location-string cases.

### 1.0.12 (2026-10-03)

- New job field `remoteEligible` (boolean): true when the workplace field says remote OR any listed location mentions remote (Greenhouse, Lever, Ashby). `workplaceType` (strict) and `remoteShare` are unchanged.
- New input `remoteMatch` (`strict` default, `eligible`): with `remoteOnly`, `eligible` filters on `remoteEligible`. Default behaviour unchanged.
- Tests on real fixtures: Stripe 35 strict / 114 eligible of 715; Ramp 14 / 47; Palantir 0 / 0.

### 1.0.15 (2026-10-05)

- Input: `maxTotalJobs` Console prefill **11** (default for API callers stays 0 = no cap), so a first one-click run costs under $0.02 including the start fee (11 × $0.0015 + $0.002 = $0.0185).
- README: Figma and remote data example figures updated to the Oct 5 re-runs (11 rows, $0.0185 each); example JSON uses `maxTotalJobs: 11` like the published tasks.
