# Changelog of Jobicy Jobs Scraper: Remote Job Listings (`mrbridge/jobicy-jobs-scraper`) Actor

- **URL**: https://apify.com/mrbridge/jobicy-jobs-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/mrbridge/jobicy-jobs-scraper.md

## Changelog

### 0.1.7 (2026-11-02)

- `jobsCharged` in `OUTPUT` now matches the billed jobs after a reboot.
- Input, dataset rows and billing are unchanged.
- Pinned `follow-redirects` 1.16.2 and `minimatch` 11.0.3 through `overrides` to clear the `npm audit` alerts. No code change.

### 0.1.6 (2026-10-28)

- Removed `datasetRows` from `OUTPUT` and the warning that went with it, the dataset count lags the writes. The count of the platform was behind the rows already pushed by 10 to 180 rows, so the field was wrong and the warning fired for nothing at the end of a normal run. The check of the dataset when a restarted run starts is unchanged: it is the one that prevents duplicates.
- Input and dataset rows are unchanged.

### 0.1.5 (2026-10-27)

- No duplicate after a restart without warning. A restart asked through the API, or a server failure, stops the run without telling it first, so the progress it had not saved yet was lost and up to one page of jobs could be returned and billed a second time. Now the dataset is the reference: on a restart the run reads the jobs already in its dataset after the last saved point, and skips them. The billed count starts from the events the platform already billed.
- The progress is saved before the first request, after every page and at the end of every walk. After a restart at most the page being applied is read again, none when the run stopped between two pages. If Jobicy refuses the saved cursor, the walk starts again from its first page and the pages it had read are read again.
- If the saved progress or the dataset cannot be read when a restarted run starts, the run fails with an error in the log and writes no `OUTPUT`, rather than risk returning or billing a job twice.
- `OUTPUT`: new field `datasetRows`, the number of rows in the dataset at the end of the run (read again once after 2 seconds when it differs from `jobsEmitted`, with a warning in the log if it still differs). New field `pagesRereadAfterResume`, the pages read again after a restart, also counted in `pagesRead`.
- Page size: each walk asks Jobicy for `maxItems` rounded up to the next ten, at least 20 and at most 200 listings per page, the same for the whole walk. The prefill (10 jobs) now asks for 20 listings instead of 200.
- If the run stops in the instant between saving a job and billing it, that job is delivered once and never billed.
- Input and dataset rows are unchanged.

### 0.1.4 (2026-10-27)

- Resume after a migration: the page read again after the migration is now counted once in the page budget of the run, so a migration in the middle of the very last page of a full run no longer loses that page (`stoppedBy` `pageBudget`).

### 0.1.3 (2026-10-27)

- Resume after a migration: when the platform moves a run to another server, the run goes on where it was. The walks that were already finished are not read again, the walk in progress restarts at the page it was applying (the cursor Jobicy gave is valid for 24 hours), and a job already returned is not returned twice and not billed twice. If Jobicy refuses that cursor (HTTP 400), the walk starts again once from its first request, still without returning a job twice. `maxItems` counts the jobs of the whole run, and the `OUTPUT` counters add up over the whole run.
- An abort of the run by the platform now stops the returns before the state is saved, exactly like a migration, so a row is either returned and recorded or not returned at all.
- The key-value store holds a new internal record, `RUN_STATE`, with the job IDs already returned, the finished walks and the counters so far. It is for the run itself, its shape may change in any version.
- Default memory is now 512 MB (256 MB is still allowed).
- Input, dataset rows and the fields of `OUTPUT` are unchanged.

### 0.1.2 (2026-10-27)

- Bounded attempts: every HTTP attempt is cut off after 45 seconds, body included, so a response body that never ends can no longer hold the run. A network error, a timeout, a truncated answer, a server error or a 429 is retried up to 3 times in total. The retry starts after the longer of Retry-After (or the backoff) and the 2 second limiter interval, counted from the start of the failed attempt. The `OUTPUT` record and the final log line are written in a `finally` block, so they exist even after an unexpected error or when the run hits its time limit.
- `OUTPUT`: `stoppedBy` can be `fetchFailed` (the last walk executed ended on a failed fetch, a failed walk before the last one does not set it and an earlier stop reason is kept) or `badInput` (see below). New fields `lastPageRead` (restarted at each walk), `pagesPlanned`, `walksFailed` and `failedWalks` (walks that ended on a `FETCH_FAILED`, 20 entries at most, each with `walk` as the first-page request, `lastPageRead`, `kind` and `httpStatus` when there is one). The `coverageNote` says how many of the planned walks ended on an error.
- A request that Jobicy refuses as invalid (HTTP 400 on a first page) writes one `BAD_INPUT` row with the HTTP status and the message of the API and ends the run with `stoppedBy` set to `badInput`. A 400 on a later page (expired cursor) still only ends that walk.
- Contacts: only e-mail addresses and phone numbers are masked. Links are kept, and `descriptionHtml` keeps its anchors (0.1.1 wrote `href="[link removed]"`). In `descriptionHtml` only the text nodes are masked and a `mailto:` or `tel:` link is replaced by its masked text.
- Rows: `location` has single spaces (0.1.1 kept `Canada,  USA`). `salaryCurrency` and `salaryPeriod` are null when the job states no salary amount.
- Schemas: the descriptions of `descriptionText`, `descriptionHtml` and `includeDescription` say that links are kept.

### 0.1.1 (2026-10-26)

- First usable version. The Actor reads the Jobicy remote jobs API and returns one row per job, newest first, with the canonical Jobicy URL on every row.
- Input: `searchTerms` (one request per term), `categories` (Jobicy industries), `locations` (Jobicy locations), `jobTypes`, `postedWithinDays`, `maxItems` (default 100), `includeDescription` (default true). More than 20 planned requests is refused with a `BAD_INPUT` row.
- Output: job fields, salary when stated, description as text and HTML with e-mail addresses, phone numbers and links masked. Errors go to a separate `errors` dataset and are never billed.
- Billing: one `job` event per delivered job. No price is stated here, see the Pricing tab.
- The `OUTPUT` record summarizes the run (requests, listings read, filtered out, duplicates, jobs returned and billed, errors by kind, `stoppedBy`) and carries the Jobicy attribution.
- Limits: Jobicy serves the last 7 days with a 3 hour delay. Requests are spaced by 2 seconds and retried up to 3 times, a run sends 200 requests at most, and the run stops cleanly after 3 blocked responses in a row.
- README: data source and terms, input and output tables, a sample row and a sample input checked by a test.
