# Changelog

> Every change to the API, dated — what shipped, what it covers, what is coming.

Source: https://developers.processcart.com/changelog

Changes are listed newest first. Additive changes ship inside `/v1`; a breaking change would arrive as `/v2` with the overlap described in [Versioning & deprecation](https://developers.processcart.com/guides/versioning). **Entries dated before the public launch describe pre-release builds:** until the launch date is announced here, a breaking change may still ship inside `/v1` with a changelog entry and no `/v2` — the 2026-10-12 concurrency header is the one such change — and the versioning policy applies in full from launch.

## 2026-10-13 — MCP server

`@processcart/mcp`, a Model Context Protocol server for Claude Desktop, Claude Code, Cursor and other MCP clients, is on npm: `npx -y @processcart/mcp` with your API key in `PROCESSCART_API_KEY` ([MCP server](https://developers.processcart.com/guides/mcp)). No API change.

- **Fourteen task-shaped tools:** `whoami`, `list_workflows`, `get_workflow_schema`, `start_run`, `find_runs`, `get_run`, `set_fields`, `complete_task`, `reopen_task`, `decide_approval`, `add_comment`, `get_activity`, `update_run` and `list_people`. Each answers Markdown for the assistant plus JSON as `structuredContent`: a run answer is the whole run with its `revision` (the API's Run resource), `find_runs` carries one summary per run (no tasks or fields), and `list_people` and `whoami` reshape theirs too ([MCP server](https://developers.processcart.com/guides/mcp#tools)).
- **Scoped to the key:** the server reads `GET /v1/me` at startup and offers only the tools the key's scopes allow; a read-only key, or `--read-only`, gets the read tools only.
- **Safe by construction:** no admin tools and no tool that deletes a run, workflow or comment; `set_fields`, `update_run`, `reopen_task` and `decide_approval` (which can overwrite, clear or send work back) carry the MCP `destructiveHint`; the server tells the assistant that run content is data, never instructions; a plain-`http` base URL is accepted only for a server on the same machine; every write carries an `Idempotency-Key`; the write tools take `expectedRevision` (sent as `Expected-Revision`); errors come back as tool results with every field problem, `currentRevision` on a `409` and the wait on a `429`.
- **Registry:** the package ships its MCP Registry metadata as `com.processcart/mcp`; the listing is pending.

## 2026-10-12 — Configuration events, Expected-Revision, partial view queries

Additive inside `/v1`, except for the concurrency header (the first item), which replaces `If-Match` and `ETag` — a breaking change made before the public launch, so it ships inside `/v1` without a `/v2` (see the note above).

- **`Expected-Revision` replaces `If-Match`; the API sends no `ETag`.** Every Run body carries `revision`, the one version field (a new run starts at `1`; a finalized upload answers `run.revision`). The writes that change an existing run — `PATCH /v1/runs/{id}`, `PATCH /v1/runs/{id}/fields`, the four task actions, trash and restore, finalizing and removing a file — take `Expected-Revision: <revision>`: a bare integer (`7`) or the same quoted (`"7"`); `*` or no header means no precondition; anything else (a list, a weak `W/"7"`, text, a negative or fractional number) is a 422 `validation_failed` with `errors[].field: "Expected-Revision"`. A stale value is refused with 409 `revision_mismatch`, whose problem body names the run's current revision in the new extension member `currentRevision`. No response carries an `ETag` header — reads and `201`s included. A request that carries `If-Match` is refused with 422 `validation_failed` (`errors[].field: "If-Match"`) on every authenticated operation; some hosting layers answer it with `412 Precondition Failed` first — both mean "send `Expected-Revision` instead". `Expected-Revision` takes `If-Match`'s place in the `Idempotency-Key` request fingerprint. Why: CDN layers evaluate `If-Match` against the response and turn a successful write into a 412 ([Concurrency](https://developers.processcart.com/guides/concurrency)). This supersedes the `ETag` / `If-Match` wording of the earlier entries below.
- **Nine configuration events:** `webhook.created` / `.updated` / `.deleted`, `schedule.created` / `.updated` / `.deleted`, `rule.created` / `.updated` / `.deleted`. `data.webhook`, `data.schedule` or `data.rule` is the resource as `GET` returns it (never a secret; a `*.deleted` event carries the last state), and every `*.updated` names what happened in `data.change` — `settings`, `enabled` / `disabled` or `paused` / `resumed`, `secret_rotated` (webhooks), or `auto_disabled` when Process Cart switched it off (a webhook after a `410` or repeated failures, a rule after repeated failures, a schedule that ended, could not start its runs, or whose workflow was moved to Trash, archived or unpublished). They are included in `*` and never trigger an automation rule ([Configuration events](https://developers.processcart.com/webhooks#configuration-events)).
- **`POST /v1/views` takes a partial `query`:** omitted members take the board's defaults, `sort.key` without `dir` takes the key's natural direction, and the 201 carries the complete query. On `PATCH /v1/views/{id}`, a `query` changes only the members it sends (`null` clears `workflowId`, `assignee` or `due`). An unknown member of `query` or `query.sort` is now a 422 `unrecognized_keys` instead of being dropped ([Views & exports](https://developers.processcart.com/guides/views-exports)).
- **`GET /v1/me` lists the workspace's status labels** in `org.labels` (`[{ id, name, color }]`, empty when there are none) — the ids `labels` and the label filters take ([Authentication](https://developers.processcart.com/guides/authentication)).
- **`finalize.url`** in an upload ticket is now an absolute URL, like every `Location`. On a host without a configured app URL, `Run.url`, a comment's `url` and a webhook's `data.run.url` now follow the request's origin rather than a local address.
- **Idempotency:** answers that read the run or its setup at that moment are no longer stored for replay — 422 `required_fields_unsatisfied` and `field_not_writable`, 403 `approver_only`, `workflow_not_runnable` and `not_allowed_for_key` — so a retry with the same `Idempotency-Key` re-executes once the state is fixed ([Idempotency](https://developers.processcart.com/guides/idempotency)).
- **Field errors:** text that a number, currency or percent field cannot parse is `errors[].code` `unparseable` (it was `not_finite`); `not_finite` now means only a non-finite JSON number.
- **Read-only keys:** the 403 for a write now names the methods such a key may use (`GET`, `HEAD`).
- **Docs:** the RateLimit headers are described as they are sent — on every response to an authenticated request; a 401, a 405 or an unknown-path 404 carries none ([Rate limits](https://developers.processcart.com/guides/rate-limits)).
- **TypeScript SDK:** the `ifMatch` option is now `expectedRevision` (a number, sent as `Expected-Revision`); `$meta.etag` and the `etagOf` helper are gone; `$meta.revision` is set on every response that returns a run (from the body), and `ProcessCartError.currentRevision` comes from the 409's body — so a write chains from the last one: `expectedRevision: updated.revision` ([TypeScript SDK](https://developers.processcart.com/guides/sdk)).

## 2026-10-12 — Schedules and automation rules

Two new resources, both additive inside `/v1` ([Schedules](https://developers.processcart.com/guides/schedules) · [Automation rules](https://developers.processcart.com/guides/automation-rules)).

- **Schedules** (scope `schedules:manage`): `GET` / `POST /v1/schedules`, `GET` / `PATCH` / `DELETE /v1/schedules/{id}`, `POST /v1/schedules/{id}/pause`, `POST /v1/schedules/{id}/resume`, `POST /v1/schedules/{id}/run` (start a run now) and `GET /v1/schedules/{id}/preview` (the next occurrences).
- **Automation rules** (scope `rules:manage`): `GET` / `POST /v1/automation-rules`, `GET` / `PATCH` / `DELETE /v1/automation-rules/{id}`, `POST /v1/automation-rules/{id}/enable`, `POST /v1/automation-rules/{id}/disable` and `GET /v1/automation-rules/{id}/executions`.
- **The Run resource** gains `schedule` (`{ id, name }` of the schedule that created the run, or `null`) and `scheduledFor` (the occurrence it was created for; `null` for every other run, including a schedule's run now). Runs a schedule creates have `startedBy: "schedule"`.
- **Actors:** activity entries and event payloads can name a schedule (`{ "kind": "schedule", "scheduleId", "name" }`) or an automation rule (`{ "kind": "rule", "ruleId", "name" }`).
- **Errors:** the new code `schedule_ended` (409); the `errors[].code` `unknown_webhook`; `limit_reached` now also covers schedules and rules that are on per workspace; `unknown_key` on `enabled` in a schedule or rule body points at pause / resume and enable / disable, as on webhooks.
- **OpenAPI:** the request body of `POST /v1/runs/{id}/tasks/{key}/approve` is now marked optional, as the endpoint always treated it (send none, or `{}`); generated clients make the argument optional.

## 2026-10-09 — TypeScript SDK

The official TypeScript client covers every operation with a typed method, plus cursor pagination, automatic idempotency keys, safe retries, `If-Match` helpers and Standard Webhooks signature verification, with request and response types generated from the OpenAPI document. Install it from npm as `@processcart/sdk` ([TypeScript SDK](https://developers.processcart.com/guides/sdk)).

## 2026-10-08 — v1, first complete build (pre-release)

The first public version of the Process Cart API.

**Covered**

- **Workflows:** list, read (summary + the published version's sections, tasks, fields and rules), per-workflow JSON Schema for starting runs and writing fields, the portable template (export), create from a template (import, published by default), update name / description / folder / key-date field / status.
- **Runs:** list with filters and incremental sync, start (with field values, priority, labels and due date in one transaction), read with `ETag`, update the header, move to Trash and restore, the task list.
- **Tasks:** complete, reopen, approve and reject under the engine's gates.
- **Field values:** set 1–200 fields in one all-or-nothing transaction; canonical + formatted on read.
- **Comments and activity:** list and post comments (text or rich document); the activity trail with cursor tailing.
- **Files:** two-phase upload to File fields, list, download URLs, remove.
- **Saved views:** list and read shared views, run a view's query, create, update and delete.
- **Webhooks:** create (secret shown once), read, update, enable, disable, rotate the secret, test, delete; the delivery log and redelivery.
- **Directory:** members (without email addresses) and groups.
- **Exports:** CSV of a workflow's runs.
- **Conventions:** API keys with scopes, read-only keys and allowlists; 600 requests per minute per key; RFC 9457 errors; `Idempotency-Key`; `ETag` / `If-Match`; `{ data, nextCursor, hasMore }` pagination; `updatedSince`; Standard Webhooks signatures with retries.
- **Docs:** this site, the OpenAPI 3.1 document, `llms.txt` / `llms-full.txt` and a `.md` twin of every page.

**Coming**

- Recurrence schedules and automation rules — since shipped ([2026-10-12 — Schedules and automation rules](#2026-10-12-schedules-and-automation-rules)).
- Editing and deleting comments through the API (available in the app today).
