# The HTTP API The API covers the same operations as the browser. Use it for scripts, integrations, or your own client. Set the base URL for your instance: ```sh export FLUKSIO=http://127.0.0.1:8000/api/v1 ``` Use the port printed by `fluksio serve`. For Docker, use `http://api.localhost/api/v1`, `http://:8080/api/v1` on a LAN stack, or `https://api./api/v1` for a deployment. All paths below are relative to this base. ## Authenticating `fluksio serve` signs the local CLI in automatically. To reuse its token from a project instance, with `jq` installed: ```sh export TOKEN=$(jq -r .token .fluksio/client.json) ``` Adjust the path for `--global` or `--data-dir`. For a remote instance, use its login endpoint with the administrator credentials: ```sh export TOKEN=$(curl -s -X POST "$FLUKSIO/login/access-token" \ --data-urlencode "username=admin@example.com" \ --data-urlencode "password=" | jq -r .access_token) curl "$FLUKSIO/users/me" -H "Authorization: Bearer $TOKEN" ``` Session tokens last eight days by default. `POST /login/test-token` checks a token. Password recovery uses `POST /password-recovery/{email}` and `POST /reset-password/`. [Agents over MCP](agents.md) use separate OAuth tokens. !!! tip "Interactive API reference" Outside production, open `/docs` or `/redoc` on the API host. The schema is at `/api/v1/openapi.json`. Access is limited to loopback unless `API_DOCS_ENABLED=true`; the Docker development stack enables it. Production disables these endpoints. ## Flows | Method | Path | Action | |---|---|---| | `GET` | `/flows/` | list flows and their state | | `GET` | `/flows/{name}` | read the draft when present, with status and issues | | `PUT` | `/flows/{name}` | save a draft; send the current `version` | | `POST` | `/flows/{name}/publish` | publish; send `{"version": }` | | `POST` | `/flows/{name}/discard-draft` | discard unpublished edits | | `POST` | `/flows/{name}/rename` | rename | | `DELETE` | `/flows/{name}` | delete; refused while a run is queued or running | | `GET` | `/flows/node-types` | list types and parameter schemas | | `GET` | `/flows/graph` | read the graph shown on Home | Deleting a flow keeps its run history. Delete runs separately. ### Node source ```sh curl "$FLUKSIO/flows/house/nodes/decide/source" \ -H "Authorization: Bearer $TOKEN" curl -X PUT "$FLUKSIO/flows/house/nodes/decide/source" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{"code": "def process(x):\n return {\"y\": x * 2}\n"}' ``` Writing code requires a superuser. So does adding, retyping, or repointing Function and Command nodes, changing Command settings, or changing `resources.env`. Other users can edit wiring, titles, and ordinary settings. Ordinary source edits stay in the draft until publishing. Shared library source changes affect its users immediately. `POST /flows/{name}/nodes/{id}/share` promotes a source to the library; `/unshare` makes it private again. `GET /flows/library` lists shared sources. ### Running and controlling | Method | Path | Action | |---|---|---| | `POST` | `/flows/{name}/start`, `/flows/{name}/stop` | activate or stop a live flow | | `POST` | `/flows/{name}/pause`, `/flows/{name}/resume` | hold or release incoming work | | `POST` | `/flows/{name}/step` | release one held message | | `POST` | `/flows/{name}/validate` | validate the current draft | | `POST` | `/flows/{name}/run` | run the current draft once with `{"inputs": {...}}` | | `POST` | `/flows/{name}/nodes/{id}/trigger` | feed a node with `{"values": {...}}` | | `POST` | `/flows/{name}/nodes/{id}/cancel` | stop active node code | | `POST` | `/flows/{name}/nodes/{id}/acknowledge` | clear its failure marker | A preview run can have real side effects. On a batch flow, `/run` submits a recorded run; use the run endpoints below for parameters and tracking. ## Messages ```sh curl "$FLUKSIO/messages/" -H "Authorization: Bearer $TOKEN" curl -X POST "$FLUKSIO/messages/house.setpoint" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' -d '{"value": 22.5}' curl "$FLUKSIO/messages/house.temperature/history" \ -H "Authorization: Bearer $TOKEN" ``` The catalogue contains messages declared by published flows and their last values. You can publish only to declared messages, just as dashboard controls do. ## Runs | Method | Path | Action | |---|---|---| | `POST` | `/runs/flows/{name}` | queue a run with `{"params": {...}, "seed": 7}` | | `POST` | `/runs/flows/{name}/sweep` | queue runs with a shared group | | `POST` | `/runs/import` | import up to 200 completed runs | | `GET` | `/runs` | query history | | `GET` | `/runs/overview` | summarize runs per flow | | `GET` | `/runs/{id}` | read parameters, results, nodes, and artifacts | | `POST` | `/runs/{id}/cancel`, `/runs/{id}/retry` | cancel, or create a retry | | `DELETE` | `/runs/{id}` | delete a finished run and its records | | `DELETE` | `/runs?flow={name}` | delete a flow's runs; refused while any are active | | `GET` | `/runs/{id}/metrics?name=&stride=` | read metric series | | `GET` | `/runs/metrics/names` | list metric names across a selection | | `GET` | `/runs/series/compare?ids=a,b,c&metric=&x=` | compare curves by step, time, or another metric | | `GET` | `/runs/export/metrics`, `/runs/export/runs` | stream CSV or JSONL | Submissions return a queued run immediately. Invalid or undeclared parameters return `422` before execution. Optional `draft` and `no_cache` flags select unpublished code or skip stage caching. History filters include `flow`, `status`, `group`, `digest`, `since`, `before`, `limit`, and `offset`. Rows arrive newest first; use the last row's `created_at` as `before` for stable pagination. Exports also accept `ids` and `until`, with `format=csv` or `jsonl`. The metrics export is a long table; the runs export is one row per run. Use `params` and `metrics` to choose columns, including dotted paths into record outputs. An export covers at most the newest 10 000 runs. When a selection matches more, the response carries `X-Truncated` with that cap and `X-Total-Count` with the number of runs the selection matched. Import takes `{"runs": [...]}`, records completed results without executing code, and deduplicates by `external_id`. See [Runs](../concepts/runs.md) for examples, artifacts, caching, and exports. ## Artifacts ```sh curl -X PUT "$FLUKSIO/artifacts?name=model.pt" \ -H "Authorization: Bearer $TOKEN" --data-binary @model.pt curl "$FLUKSIO/artifacts/" \ -H "Authorization: Bearer $TOKEN" -o model.pt ``` The upload returns a reference with the content digest. Identical bytes are stored once. Node code uses `save_artifact` and `load_artifact` instead. ## Dashboards and panels | Method | Path | Action | |---|---|---| | `GET` | `/dashboards/` | list dashboards | | `GET` | `/dashboards/{name}?draft=true` | read a draft; omit the query for published content | | `POST` | `/dashboards/{name}` | create | | `POST` | `/dashboards/from-flow/{flow}` | create a batch flow's results dashboard | | `PUT` | `/dashboards/{name}` | save a draft | | `POST` | `/dashboards/{name}/publish`, `/dashboards/{name}/discard`, `/dashboards/{name}/rename` | publish, discard, or rename | | `GET`, `PUT` | `/panels/` | read or update panel assignments | | `POST` | `/panels/pair` | start device pairing | | `GET` | `/panels/pair/{code}` | poll pairing with its `secret` | | `POST` | `/panels/{id}/pair` | approve the pairing | | `POST` | `/panels/{id}/unpair` | revoke the panel credential | ## Secrets, modules, and alerts | Method | Path | Action | |---|---|---| | `GET` | `/secrets/` | list names only | | `PUT` | `/secrets/{name}` | set `{"value": "..."}` | | `GET` | `/modules/` | read installed packages and the manifest | | `POST` | `/modules/apply` | replace the manifest with `{"requirements": "numpy>=2\n"}` | | `GET`, `PUT` | `/alerts/config` | read or update alert configuration | | `POST` | `/alerts/test/{channel}` | test a channel | Secrets and package changes require a superuser. Applying a manifest replaces the whole managed environment's package list. Adopted environments are read-only here; install their packages yourself. Connector state keys can also be listed and cleared by a superuser; see [the connector contract](../reference/connector-contract.md#keeping-state-across-restarts). ## Observability and workers | Method | Path | Action | |---|---|---| | `GET` | `/observability/summary` | health and engine version; always returns `200` | | `GET` | `/observability/timeseries`, `/observability/flows` | execution metrics or flow rollups | | `GET` | `/observability/runs`, `/observability/events`, `/observability/dead-letter` | cascades, events, or abandoned work | | `GET` | `/utils/health/` | deep health check; fails on loop or state-backend problems | | `GET` | `/workers`, `/workers/resources` | attached workers and resource availability | | `GET`, `POST` | `/workers/tokens` | list or mint worker credentials; superuser only | | `POST` | `/workers/tokens/{jti}/revoke` | revoke a worker | | `GET` | `/workers/runtime` | read node-runner source | | `WS` | `/workers/attach` | attach with a worker token | | `GET`, `POST` | `/flavors/` | list or create resource sizes | | `PATCH`, `DELETE` | `/flavors/{name}` | update or delete a size | Changing flavors requires a superuser. See [Remote workers](workers.md). ## Live events Connect to `ws://127.0.0.1:8000/api/v1/flows/ws` with an `Authorization: Bearer ` header. Browsers first call `POST /flows/ws-ticket`, then connect with `?ticket=`. Tickets are single-use and expire after 30 seconds. The socket sends a snapshot followed by node, value, health, and run events. ## Errors and client generation | Code | Meaning | |---|---| | `400` | malformed request or refused operation | | `401` / `403` | missing authentication or permission | | `404` | resource not found | | `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 | For a version conflict, read `current_version`, reload, merge your edits, and save again. Other `409` responses describe their own conflict. `make generate-client` regenerates the frontend SDK. To generate a client in another language, use the instance's `/api/v1/openapi.json` schema.