# 2026-10-24: API 1.38

Safer side effects, lists that never skip a row, idempotency per mode, and two new warnings.

## Added

- **api:** `GET /v1/jobs/{id}?since_status=<status>` with `Prefer: wait` answers as soon as the job's status differs from the one you name, so a wait right after answering an input is not held.
- **api:** Step records (`GET /v1/jobs/{id}/steps`) carry `iteration`: a step that runs more than once in a job, in a loop or after a resume, keeps one record per run instead of overwriting the last.
- **api:** The warning `pagination_incomplete`: a `paginate` step that cannot move on after reading some pages returns the pages it read, with `count` and `detail`.
- **api:** The schedule skip reason `fire_failed`: a fire that keeps failing past the missed window is recorded as skipped, and the schedule moves on.
- **dsl:** Lint warning `W009`: a top-level `extract` next to an `extract` step that writes `data`.

## Fixed

- **api:** A `side_effect: true` step that fails after its action was sent is never retried, healed, refreshed or escalated in the same run: the job parks `side_effect_ambiguous` and a person decides.
- **api:** Every list is ordered by creation time, then id, so rows created in the same millisecond are no longer skipped at a page boundary. `GET /v1/batches/{id}/jobs` returns every page.
- **api:** An `Idempotency-Key` is scoped to the organisation and the mode, so a test key and a live key never replay each other's job. A replay spends no credits, test-mode quota or rate limit, and a keyed `POST /v1/jobs/batch` is replayed instead of created twice.
- **api:** `PATCH /v1/schedules/{id}` keeps the `secret` inputs you leave out of `inputs`; `null` removes one.
- **api:** **Breaking:** A job's `webhook_url` that is malformed or does not resolve answers `422 validation_failed` with `details.reason`, as a webhook endpoint's `url` does, instead of `ssrf_blocked`.
- **api:** A job whose worker is lost three times fails with `internal` and `details.reason: "worker_lost"`, and its credits are released, instead of being retried without end.
- **dsl:** A program with a top-level `extract` and `extract` steps `into: "vars"` returns its `data` again.
