Docs for key renames: ids and keys in the flow concepts, the rename routes, events and 503s in the API reference, hooks during a rename, sync and run metrics after one; a pinned restore refused for its recorded key names that key in the 409
Docs / docs (push) Successful in 3m11s
Playwright Tests / test-playwright (1, 2) (push) Successful in 11m42s
Playwright Tests / test-playwright (2, 2) (push) Successful in 2m22s
pre-commit / pre-commit (push) Successful in 3m12s
Test Backend / test-backend (3.12) (push) Successful in 6m19s
Test Backend / test-backend (3.14) (push) Successful in 5m59s
Compose Smoke Test / test-compose (push) Successful in 37s
Playwright Tests / merge-reports (push) Successful in 1m12s

This commit is contained in:
2026-11-03 08:09:35 +01:00
parent f9d5f510c2
commit b7f1d21712
7 changed files with 75 additions and 9 deletions
+42 -2
View File
@@ -60,6 +60,9 @@ a token. Password recovery uses `POST /password-recovery/{email}` and
| `POST` | `/flows/{id}/discard-draft` | discard unpublished edits |
| `POST` | `/flows/{id}/duplicate` | copy into an unpublished `<key>_copy` with an id of its own; code nodes need a superuser |
| `DELETE` | `/flows/{id}` | delete; refused while a run is queued or running |
| `POST` | `/flows/{id}/rename/plan` | what renaming the key to `{"new_name": ...}` would change; superuser only |
| `POST` | `/flows/{id}/rename` | rename the key as planned; superuser only |
| `DELETE` | `/flows/{id}/rename/{request_id}` | call off a rename still waiting for work to finish |
| `GET` | `/flows/node-types` | list types and parameter schemas |
| `GET` | `/flows/graph` | read the graph shown on Home |
@@ -74,7 +77,10 @@ answers 201 with the new flow. The server issues an opaque id such as
and restores do. A pinned id has to be free and cannot be a path of this API
like `graph`. If runs or metrics of a deleted flow are still filed under it,
the new flow takes that history back and has to use the key it was recorded
under. Creating a flow with code nodes needs a superuser, as saving one does.
under. Another key is refused with 409, and `key` in the answer names the
recorded one. To bring it back under another key, restore it under the
recorded key and then rename it. Creating a flow with code nodes needs a
superuser, as saving one does.
A key that still has values or queued work from an earlier flow is refused
with 409 until that is gone.
@@ -92,6 +98,35 @@ lists `flow_ids` in the order of its `flows`, a device binding has `flow_id`
and a search entry has `id`. Open things by these ids, not by the part of a
`<key>.<node>` before the dot.
### Renaming a key
A superuser renames a flow's key in two steps. `POST /flows/{id}/rename/plan`
with `{"new_name": "warmth"}` changes nothing. It lists the flows and
dashboards the rename would rewrite, counts the history, live state, queued
work and alert channels that would move, and gives warnings and `refusals`,
`allowed`, the flow's `name` and `version` and a `fingerprint`.
`POST /flows/{id}/rename` then sends the plan's `name` as `expected_name`, its
`version` as `expected_version`, `new_name` and `fingerprint`, plus a
`request_id` of your own of up to 64 characters. It answers with the new versions of the rewritten documents. Sending the same
`request_id` again gets the same answer.
The whole engine pauses for a flow rename. The request first waits for running
work to finish, however long that takes, and `GET /observability/summary` shows
the rename under `rename`, with what it waits for in `busy`. Until it starts
changing things, `DELETE /flows/{id}/rename/{request_id}` or closing the
connection calls it off, and the request answers 409 `aborted`. Meanwhile other
changes get 503 with code `renaming` and `Retry-After`, and so do the hooks of
the flows being rewritten. Reads keep working.
A refusal answers 409 with its `code` and the fresh `plan`, and so does
`plan_changed`, when something the rename would rewrite changed since the plan.
409 `stale` means the flow itself changed. A key that is no valid key answers
422.
`POST /dashboards/{id}/rename/plan` and `POST /dashboards/{id}/rename` work the
same way for a dashboard. Only its own documents change, and the engine keeps
running.
### Node source
```sh
@@ -238,6 +273,7 @@ reclaiming space sooner.
| `PUT` | `/dashboards/{id}` | save a draft of an existing dashboard |
| `POST` | `/dashboards/{id}/publish`, `/dashboards/{id}/discard` | publish or discard |
| `POST` | `/dashboards/{id}/duplicate` | copy into an unpublished `<key>_copy` with an id of its own |
| `POST` | `/dashboards/{id}/rename/plan`, `/dashboards/{id}/rename` | plan or rename the key, see [Renaming a key](#renaming-a-key); superuser only |
| `GET` | `/devices/` | list devices, with `online`, `last_seen`, `report` and `reported_at` |
| `POST`, `GET`, `PUT`, `DELETE` | `/devices/{id}` | create, read, save or delete one; a save sends the `version` it read and gets 409 when someone saved first. A read adds `io` and `bindings`, its ports as the device nodes of published flows wire them |
| `POST` | `/devices/pair` | start device pairing, optionally with `{name, board, firmware}`; answers `code`, `secret` and the two-character `check` the device shows beside its code; unauthenticated, five a minute per address (the portal limits its own), the oldest of 50 waiting requests from the same side gives way |
@@ -317,6 +353,10 @@ messages are named, and by id in `flow_id`, which is empty for the engine as
a whole. `dashboard_changed` names the dashboard by id, or nothing when a
device's own wiring moved.
A key rename sends `rename_waiting` with `busy` while it waits for work to
finish, and `renamed` with `kind`, `id`, `old` and `new` once it is done. A
client then reads again what it shows, at the same ids.
A client asks for the bytes of the media it shows with
`{"type": "media", "names": [...]}`, which replaces what it asked for before,
for at most 8 messages, the last 8 it names when it names more. Each frame held in memory then arrives as a binary
@@ -398,7 +438,7 @@ offer and candidates are not queued behind frames.
| `409` | version conflict, duplicate, or resource still in use |
| `413` | artifact upload exceeds the configured limit |
| `422` | invalid parameters, ports, or bindings |
| `503` | subsystem unavailable |
| `503` | subsystem unavailable, or a key rename in progress, retry after `Retry-After` |
For a version conflict, read `current_version`, reload, merge your edits, and
save again. Other `409` responses describe their own conflict.