# Changelog of Job Postings Dataset: 320k+ Open Jobs, Updated Daily (`redomic/job-postings-dataset`) Actor

- **URL**: https://apify.com/redomic/job-postings-dataset/changelog.md
- **Full Actor documentation**: https://apify.com/redomic/job-postings-dataset.md

## Changelog

### 0.1 (2026-11-08)

- Initial release: snapshot, new, and changes (stateful daily delta) modes over 328k open jobs from 11k company career sites (Greenhouse, Lever, Ashby), served from the public hiring store (no scraping, no proxy). Filters, flat CSV/Excel-ready rows, status and summary rows.

- 2026-11-09: Store listing unblocked: icon uploaded, listing fields pass `listing_ready`, and the 20-input battery passes 19/20 (95%).

- 2026-11-09: `locations` filter expands region words (EMEA, APAC, LATAM, DACH, Nordics, Benelux, Europe, North America) to common store location strings (e.g. EMEA matches "Europe", "London", "Berlin, Germany", "Remote - EU").

- 0.1 (2026-11-09): EMEA alias gap, one-way country abbreviations and role-family taxonomy drift returned 0 rows for the failing Linear EMEA battery input shape (`companies=["linear"]`, `locations=["EMEA"]`, `roleFamilies=["Engineering"]`) and related filters: EMEA missed live `EU`/`Middle East`/`Africa` postings, `countries=["United Kingdom"]`/`["United States"]` missed `UK`/`US` locations, and `roleFamilies=["Data/Analytics"]` missed `Engineering - Data`; expanded EMEA terms, made country aliases bidirectional and matched role families by substring with a Data alias, with live 2026-11-09 fixtures proving the battery inputs return rows.

- 0.1 (2026-11-09): Snapshot/new runs with 0 matching rows (no shard failures) no longer call `Actor.fail`; they exit SUCCEEDED with a clear status message and status/summary rows, so legitimate empty-filter results don't inflate platform fail rate.

- 0.1 (2026-11-09): Fixed runs that ended FAILED after producing `ok: 0 rows - no jobs match these filters` (e.g. Linear EMEA Engineering battery/canary inputs): zero-match snapshot/new paths now return early with `Actor.exit` (and only no-data shard failures call `Actor.fail`), with refreshed 2026-11-09 fixtures/tests covering the failing input shape.

- 0.1 (2026-11-10): Fixed the `roleFamily`/`seniority` labels: the store's precomputed classifier matched the bare "AI" in "AI Trainer" recruitment postings, dumping Accountants, IP Analysts, Lawyers and Designers into `Engineering - ML/AI`. The Actor now re-derives both labels locally from the title (recruitment noise stripped, department as fallback) before filtering and output; `Architect` is `Engineering - Backend/Fullstack`/`Lead/Principal`, not `Intern`.

- 0.1 (2026-11-10): Second classifier pass on the same review: VP, Head of, Director and Chief titles now count as `Lead/Principal` (were `Mid`), only "entry level" phrases count as `Junior` ("Market Entry Specialist" was `Junior`), and a bare "market" no longer drags "Market Analyst" into `Marketing` (now `Data/Analytics`); "System Operations Engineer" is `Engineering - Infrastructure`. README documents the exact labelling rules.

- 0.1 (2026-11-10): Added `outputFormat: "sheets_flat"` (fixed flat column order, flat values only, no nested JSON) and `cursor: "auto"` (append-only delta keyed by the input hash in the monitor store: only rows not delivered before are returned and billed, a quiet day returns 0 rows / $0 / SUCCEEDED). README documents the spreadsheet schedule recipe with a real output row.

- 0.1 (2026-11-11): Added stable `id` and normalized `countryCode` fields; `countries` filters now also match by normalized country code. Role-family filtering is guarded against title mismatches so Engineering queries exclude Accountant/Auditor roles. Run status/summary metadata is stored in the monitor key-value store (`STATUS`/`SUMMARY`) instead of the default dataset, so default exports contain job rows only.

- 0.1 (2026-11-11): Added company hiring-state signal (companyState: hiring_freeze/rehire/active) derived from daily open/closed deltas, with stateSince, priorOpenCount, openNow, evidenceDays, confidence and asOf; emitted only after >=2 consecutive collection days.

- 0.1 (2026-11-11): Added `newlyHiringCompanies` output mode (optional `newlyHiringWithinDays`, default 7) returning one company row per firm with >=1 role first seen in the window: openRoleCount, topRoleTitles, locations, salaryCoveragePct, dataAsOf, sampleSize and newRoleEvidence (`firstSeen` per role), computed from daily open/closed shards.

- 0.1 (2026-11-12): Default fresh-first: postedWithinDays defaults to 30; evergreen postings (generalApplication or posted 180+ days) are excluded by default with counts disclosed (evergreenRows/excludedEvergreenRows); rows deduped before billing and \_status rows are never billed; stable ids retained.

- 0.1 (2026-11-12): Added job `description` to every exported row (from source `description`/`descriptionText`/`descriptionPlain` when present, else null) in default rows and `sheets_flat` output, with fixture-backed tests covering snapshot and changes rows.

- 0.1 (2026-11-13): Added `search` keyword filter: matches jobs where all search words appear in the title, description, company or department (case-insensitive), with README example and tests.

- 0.1 (2026-11-13): Added `titleContains` (any-of include) and `excludeTitleKeywords` (exclude) title/description keyword filters, with input schema, README example, and tests covering snapshot, `sheets_flat`, `cursor=auto`, and `changes`.

- 0.1 (2026-11-13): Added `minSalary` and `maxSalary` numeric filters (inclusive overlap against posted `salaryMin`/`salaryMax`, excluding rows without salary), with input schema, README example, and tests covering overlap, missing bounds, and `sheets_flat`/cursor/changes output.

- 0.1 (2026-11-13): Added `daysOpen` on job rows (firstSeen to closedOn) for closed results, null for open rows and when tracking started at/after firstSeen (openSinceBeforeTracking). Days-open exposed in default/sheets output and dataset view; closed changes fixture rows carry `daysOpen` with `closedOn`, and recency/evergreen filters remain configurable and affect counts as documented.

- 0.1 (2026-11-13): Agent-ready input defaults: `minSalary`/`maxSalary` default `0` (no bound), `search` default `""`, and `cursor` default `""` with an explicit Off option, so agents sending `{}` get the same full snapshot.

- 0.1 (2026-11-14): Provable bulk/change story verified end to end: job rows carry `changeType`/`evergreen`/`daysOpen`/`dataAsOf` and flat `sheets_flat` columns, evergreen (180d+ or talent-pool) excluded and counted by default, STATUS/SUMMARY report `historyDays`/`trackingCoverage`/coverage from the store META/INDEX, and README counts/date aligned to the META/INDEX snapshot (no overstated history claims), with a fixture-backed test that export rows match index coverage.

- 2026-11-14: Added `output=events` daily delta mode returning new/changed/closed job events with asOf, source board/ATS and salary/location diffs; stable event_id and no-change SUCCEEDED semantics.

- 0.1 (2026-11-14): Cut default `maxItems` from 1000 to 100 (Try $2.00 -> $0.20) and kept status/summary metadata in run KV only (`STATUS`/`SUMMARY`), so the dataset stays job rows only with no `_status`/summary preview rows. Added fixture-backed tests for default cap and job-only output/billing bounds.

- 0.1 (2026-11-15): README rewritten as a buyer-facing sales page: clearer first screen (who it's for, what you get, real output, price per 1,000), plain reliability statement, and removed internal test-log terminology while keeping snapshot/history/coverage facts aligned to the data.

- 0.1 (2026-11-15): Default snapshot orders newest first (postedAt, then firstSeen), maps US state, Canadian province and UK nation locations to countryCode, and falls back to the board display name when company is a raw UUID.

- 0.1 (2026-11-16): Added `excludeCompanies` (string list) to drop jobs whose company name or board token matches a listed value (case-insensitive), applied before `companies` include so excluded jobs are never returned.
