forked from viewit/KX-Bridge-Release
API.md documents the full HTTP/WebSocket surface (Moonraker-compatible endpoints for Mainsail/Fluidd/OrcaSlicer/moonraker-obico compatibility, plus the bridge-specific /api and /kx routes) for integrators and plugin authors. MANUAL.md is a task-oriented end-user guide covering day-to-day usage: dashboard, printing, filament/AMS management, multi-printer setup, the power-switch feature, settings reference, and basic troubleshooting.
257 lines
15 KiB
Markdown
257 lines
15 KiB
Markdown
# KX-Bridge HTTP API Reference
|
||
|
||
This document lists the HTTP and WebSocket surface exposed by
|
||
`kobrax_moonraker_bridge.py`. It is a reference for integrators and
|
||
plugin authors, not a tutorial — for day-to-day usage of the bridge see
|
||
[MANUAL.md](MANUAL.md), and for setup see [README.md](README.md).
|
||
|
||
The API has two distinct parts:
|
||
|
||
1. **Moonraker-compatible surface** — a subset of the real
|
||
[Moonraker](https://moonraker.readthedocs.io/) HTTP + WebSocket API,
|
||
implemented just far enough to make Mainsail, Fluidd, OrcaSlicer, and
|
||
`moonraker-obico` work against the Kobra X. **This is not a full
|
||
Moonraker implementation** — many real Moonraker endpoints/methods do
|
||
not exist here, and some responses are static stubs that exist only
|
||
to stop a client from erroring/looping (noted below).
|
||
2. **Bridge-specific surface** — `/api/...` and `/kx/...` endpoints for
|
||
things Moonraker has no concept of: multi-printer management, AMS/ACE
|
||
filament control, the GCode store, custom filament profile import,
|
||
Spoolman, and the smart-plug power switch.
|
||
|
||
## Security
|
||
|
||
**There is no authentication on any endpoint.** The bridge is designed
|
||
to be run on a trusted local network only. Do not expose port `7125`
|
||
(or any additional per-printer port) to the internet — anyone who can
|
||
reach the port can control the printer, read/delete files, and read
|
||
`/kx/printers` credentials indirectly through bridge behavior. `/access/api_key`
|
||
returns a hardcoded dummy value purely so `moonraker-obico` doesn't warn;
|
||
it is not a real credential.
|
||
|
||
CORS is enabled (`_json_cors` / `handle_kx_options` add
|
||
`Access-Control-Allow-*` headers and answer `OPTIONS` with 204) so the
|
||
Web UI can call sibling bridge instances directly in multi-printer setups.
|
||
|
||
---
|
||
|
||
## Moonraker-compatible endpoints (HTTP)
|
||
|
||
All responses follow Moonraker's `{"result": {...}}` envelope unless noted.
|
||
|
||
| Method | Path | Purpose | Notes |
|
||
|---|---|---|---|
|
||
| GET | `/server/info` | Server/klippy status | Always reports `klippy_connected: true`, `klippy_state: "ready"` |
|
||
| GET | `/printer/info` | Printer identity | Static hostname/paths; `software_version` from `KLIPPER_VERSION` |
|
||
| GET | `/machine/system_info` | System info stub | Mostly static/placeholder fields |
|
||
| GET | `/printer/objects/list` | List available printer objects | Keys of `_build_printer_objects()` |
|
||
| GET | `/printer/objects/query?objects=...` | Query object status | Comma-separated `objects` query param, or bare query keys |
|
||
| GET`/POST` | `/printer/objects/subscribe` | Subscribe (HTTP polling variant) | Returns full status snapshot immediately |
|
||
| GET | `/server/files/list` | List gcode files | Only returns the single currently-tracked file (if any) |
|
||
| GET | `/server/files/metadata?filename=...` | File metadata (layers, est. time, etc.) | Shared logic with WS `server.files.metadata`; falls back to GCode store / buried-report cache |
|
||
| POST | `/server/files/upload` | Upload a gcode file (multipart) | Same handler as `/api/files/local` |
|
||
| POST | `/printer/print/start?filename=...` | Start a print | Body may include `filament_assignments`, `excluded_objects`, `auto_leveling` |
|
||
| POST | `/printer/print/pause` | Pause current print | |
|
||
| POST | `/printer/print/resume` | Resume current print | |
|
||
| POST | `/printer/print/cancel` | Cancel current print | |
|
||
| GET | `/access/api_key` | Dummy API key | No real auth exists |
|
||
| GET | `/machine/update/status` | Update-manager stub | Always `busy: false`, empty `version_info` |
|
||
| GET | `/server/history/list?limit=` | Print job history | Backed by the bridge's own GCodeStore/job DB |
|
||
| GET | `/server/webcams/list` | Webcam descriptor | Rewrites `localhost`/`127.0.0.1` Host header to the bridge's LAN IP so remote Obico/Mainsail instances get a reachable URL |
|
||
| POST | `/printer/gcode/script` | Execute a (very limited) gcode command | See `_exec_gcode_script`; not a general gcode interpreter |
|
||
| GET | `/server/database/item?namespace=&key=` | Moonraker "database" KV read | Real payload only for `lane_data` (AMS/filament sync for OrcaSlicer); stub/empty responses for `AFC`, `afc-install`, `happy_hare`, `mainsail`; in-memory KV for `obico` |
|
||
| POST | `/server/database/item` | Moonraker "database" KV write | In-memory only (not persisted across restarts); used by `moonraker-obico` for its own settings |
|
||
| GET | `/server/database/list` | List KV namespaces | Static: `["lane_data", "mainsail", "obico"]` |
|
||
|
||
### OctoPrint-compatibility shim
|
||
|
||
| Method | Path | Purpose |
|
||
|---|---|---|
|
||
| GET | `/api/version` | OctoPrint-style version probe (some tools check this instead of Moonraker) |
|
||
| POST | `/api/files/local`, `/api/files/{path}` | Alias for the same multipart upload handler as `/server/files/upload` |
|
||
|
||
### WebSocket JSON-RPC (`/websocket`)
|
||
|
||
Moonraker's JSON-RPC 2.0 protocol over a single `/websocket` endpoint. On
|
||
connect the bridge immediately pushes `notify_klippy_ready` and then
|
||
periodic `notify_status_update` notifications. Supported `method` values:
|
||
|
||
| Method | Purpose |
|
||
|---|---|
|
||
| `printer.info` / `printer_info` | Same payload as `/printer/info` |
|
||
| `server.info` / `server_info` | Same payload as `/server/info` |
|
||
| `printer.objects.list` | Same as HTTP equivalent |
|
||
| `printer.objects.query` / `printer.objects.get` | Object status by requested keys |
|
||
| `printer.objects.subscribe` | Returns a status snapshot (no real push subscription semantics — status pushes happen automatically via `notify_status_update`) |
|
||
| `printer.print.start` | `params.filename` |
|
||
| `printer.print.pause` / `.resume` / `.cancel` | |
|
||
| `machine.system_info` | Minimal stub |
|
||
| `server.files.list` | Always returns `[]` over WS (unlike the HTTP version) |
|
||
| `printer.gcode.script` | `params.script`, same limited executor as the HTTP endpoint |
|
||
| `server.connection.identify` | Returns a dummy `connection_id` for Obico's handshake |
|
||
| `connection.register_remote_method` | Accepted and ignored (Obico registers a remote-event callback) |
|
||
| `server.webcams.list` | Same shape as HTTP, using the bridge's own LAN IP |
|
||
| `server.history.list` | Job history, same source as `/server/history/list` |
|
||
| `machine.update.status` | Stub |
|
||
| `server.files.metadata` | Same logic as `/server/files/metadata` |
|
||
|
||
Any other method is logged and answered with an empty `result: {}` — it
|
||
does not error, to avoid breaking clients that probe for optional
|
||
methods.
|
||
|
||
---
|
||
|
||
## Bridge-specific endpoints
|
||
|
||
All `/kx/...` (and most `/api/...`) responses use `{"result": ...}` on
|
||
success and `{"error": "..."}` with a 4xx/5xx status on failure, except
|
||
where noted.
|
||
|
||
### Printer control (`/api/...`)
|
||
|
||
| Method | Path | Purpose | Body / Query |
|
||
|---|---|---|---|
|
||
| POST | `/api/light` | Toggle chamber light | `{on, brightness}` |
|
||
| POST | `/api/fan` | Set part-cooling fan speed | `{speed}` (0–100) |
|
||
| POST | `/api/connect` | Manually (re)connect the MQTT client | — |
|
||
| POST | `/api/disconnect` | Manually disconnect | — |
|
||
| POST | `/api/restart` | Restart the bridge process | — |
|
||
| POST | `/api/speed` | Set print speed mode | `{mode}` (int) |
|
||
| POST | `/api/axis` | Jog an axis, or `{"action":"turnoff"}` to disable steppers | `{axis, move_type, distance}` |
|
||
| POST | `/api/temperature` | Set nozzle/bed target temps | `{nozzle?, bed?}`; uses a different MQTT path mid-print vs. idle |
|
||
| GET | `/api/state` | Full dashboard status snapshot | Primary polling endpoint used by the Web UI |
|
||
| GET | `/api/camera` | Current camera stream URL | |
|
||
| GET | `/api/camera/stream` | MJPEG live view | `multipart/x-mixed-replace`, fed from a shared ffmpeg fanout |
|
||
| GET | `/api/camera/h264` | Raw H.264 stream (for Obico) | |
|
||
| GET | `/api/camera/snapshot` | Last cached JPEG frame | Instant, served from RAM |
|
||
| POST | `/api/camera/start` / `/api/camera/stop` / `/api/camera/reset` | Camera lifecycle control | `reset` clears the 429 backoff and restarts ffmpeg |
|
||
| GET | `/api/settings` | Read current config.ini-backed settings | |
|
||
| POST | `/api/settings` | Write settings, then restart the bridge | See config fields below |
|
||
| GET | `/api/update/check` | Check Gitea releases for a newer version | Branches on nightly/dev/stable channel |
|
||
| POST | `/api/update/apply` | Self-update (non-Docker builds only) | `{tag}` |
|
||
| POST | `/api/file_ready/clear` | Dismiss the "file ready to print" banner/dialog state | |
|
||
| GET | `/api/log/stream` | Server-Sent Events log tail | |
|
||
| GET | `/api/log/download` | Download buffered log as plaintext | |
|
||
| GET | `/serve/{filename}` | Internal file server used to hand the printer a URL to fetch gcode from | Not meant for direct browser use |
|
||
|
||
**`/api/settings` fields** (POST body, all optional — merges into
|
||
existing config.ini): `printer_ip`, `mqtt_port`, `username`, `password`,
|
||
`mode_id`, `device_id`, `power_on_url`, `power_off_url`,
|
||
`power_status_url`, `default_ams_slot`, `auto_leveling`,
|
||
`vibration_compensation`, `camera_on_print`, `web_upload_warning`,
|
||
`print_start_dialog`, `poll_interval`, `verbose_http_log`,
|
||
`printer_name`, `spoolman_server`, `spoolman_sync_rate`,
|
||
`ace_dry_presets`.
|
||
|
||
### AMS / ACE filament control (`/api/...`)
|
||
|
||
| Method | Path | Purpose | Body |
|
||
|---|---|---|---|
|
||
| POST | `/api/ams/set_slot` | Set material type + color for a slot | `{index, type, color:[r,g,b]}` |
|
||
| POST | `/api/ams/feed` | Feed filament in/out | `{slot_index, type}` (1=feed in, 2=feed out) |
|
||
| POST | `/api/ace/auto_feed` | Toggle auto-feed for an ACE unit | `{ace_id, on}` |
|
||
| POST | `/api/ace/dry` | Start/stop the ACE dryer | `{action: "start"|"stop", ace_id?, target_temp?, duration?}` |
|
||
|
||
### GCode store (bridge-managed uploads) (`/kx/files...`)
|
||
|
||
| Method | Path | Purpose |
|
||
|---|---|---|
|
||
| GET | `/kx/files` | List files the bridge has stored, with last-print status/duration |
|
||
| DELETE | `/kx/files/{file_id}` | Delete a stored file |
|
||
| GET | `/kx/files/{file_id}/download` | Download a stored file |
|
||
| POST | `/kx/files/{file_id}/verify` | Clear the "web upload, unverified" flag |
|
||
| GET | `/kx/files/{id}/objects` | Print-object list + SVG preview (for the pre-print skip feature) |
|
||
| GET | `/kx/history?limit=&offset=` | Paginated print job history |
|
||
|
||
### Files on the printer's own storage (`/kx/printer-files...`)
|
||
|
||
Distinct from the GCode store above — these list/manage files that live
|
||
on the printer's internal storage (e.g. printed directly from Anycubic
|
||
Slicer Next, bypassing the bridge).
|
||
|
||
| Method | Path | Purpose |
|
||
|---|---|---|
|
||
| GET | `/kx/printer-files` | List files via the printer's `file/listLocal` MQTT action |
|
||
| POST | `/kx/printer-files/delete` | Delete one or more files: `{"filenames": [...]}` (single endpoint for single + bulk delete) |
|
||
| GET | `/kx/printer-files/{filename}/thumbnail` | Fetch (and cache) a file's embedded gcode thumbnail via `file/fileDetails` |
|
||
|
||
### Printing (`/kx/print`)
|
||
|
||
| Method | Path | Purpose | Body |
|
||
|---|---|---|---|
|
||
| POST | `/kx/print` | Start a print from a stored GCode-store file | `{file_id, filament_assignments?, excluded_objects?, auto_leveling?}` |
|
||
|
||
`filament_assignments` is `[{slot_index, material, color_hex}, ...]`; if
|
||
omitted, all currently-occupied AMS slots are auto-mapped.
|
||
|
||
### Pre-print / mid-print object skip (`/kx/skip...`)
|
||
|
||
| Method | Path | Purpose |
|
||
|---|---|---|
|
||
| POST | `/kx/skip` | Skip named objects mid-print: `{"names": [...]}` |
|
||
| POST | `/kx/skip/query` | Re-request the object list from the printer and return merged skip state |
|
||
| GET | `/kx/skip/state` | Current skip state (object list, already-skipped names, SVG, filename) |
|
||
|
||
### Filament profiles (`/kx/filament/...`)
|
||
|
||
| Method | Path | Purpose | Body / Query |
|
||
|---|---|---|---|
|
||
| GET | `/kx/filament/slots` | Current AMS slot contents + any user profile override | |
|
||
| GET | `/kx/filament/profiles?type=&vendor=` | Curated OrcaSlicer filament profile catalog (system + user-imported) | Optional filters |
|
||
| GET | `/kx/filament/profiles/user` | User-imported profiles only (for the settings management list) | |
|
||
| POST | `/kx/filament/profiles/user` | Import profiles from a ZIP or `.json` file(s) (multipart) | Multipart field `file`/`files`/`upload`; ZIP entries or bare `.json`, parsed via `orca_filaments.parse_profile_bytes` |
|
||
| DELETE | `/kx/filament/profiles/user?vendor=&name=` | Delete one user profile (both params) or all (no params) | |
|
||
| POST | `/kx/filament/slots/{idx}/profile` | Assign (or clear) a fixed profile override for one AMS slot | `{vendor, name}`; empty strings clear the mapping. Selector is `(vendor, name)`, not `id` — IDs are not unique across the Orca profile catalog |
|
||
| GET`/POST` | `/kx/filament/visible_vendors` | Get/set the vendor visibility filter for the slot profile dropdown | POST body `{"vendors": [...]}`; empty list = show all |
|
||
|
||
### Spoolman integration (`/kx/spoolman/...`)
|
||
|
||
| Method | Path | Purpose |
|
||
|---|---|---|
|
||
| GET | `/kx/spoolman/status` | Whether Spoolman is configured/reachable, server URL, sync rate, current slot→spool map |
|
||
| GET | `/kx/spoolman/spools` | Proxied list of spools from the configured Spoolman server |
|
||
| POST | `/kx/spoolman/active-spool` | Assign spool IDs to AMS slots: `{"slot_map": {"0": 42, "2": 17}}` (AMS slot index → Spoolman spool ID) |
|
||
|
||
### Multi-printer management (`/kx/printers...`)
|
||
|
||
| Method | Path | Purpose | Body |
|
||
|---|---|---|---|
|
||
| GET | `/kx/printers` | List all configured printers with online-ish metadata | |
|
||
| POST | `/kx/printers/add` | Add a printer by IP (credentials auto-fetched from the printer) | `{printer_ip, name?}` — triggers a bridge restart |
|
||
| DELETE | `/kx/printers/{pid}` | Remove a printer from config; renumbers remaining `[printer_N]` sections | — triggers a bridge restart |
|
||
| POST | `/kx/printers/{pid}/power` | Toggle an external smart plug (Tasmota-style) for a printer | `{"action": "on"|"off"}` |
|
||
| GET | `/kx/printers/{pid}/power-status` | Query the smart plug's current on/off state | |
|
||
|
||
**Power switch is not the printer's own power state** — it's a plain
|
||
`GET` fired at a user-configured `power_on_url` / `power_off_url` /
|
||
`power_status_url` (e.g. a Tasmota `cmnd=Power%20on` URL). See
|
||
[MANUAL.md](MANUAL.md#power-switch-feature) for details.
|
||
It only exists for printers where `power_on_url` or `power_off_url` is
|
||
set in config; `/kx/printers` exposes this as `has_power_control`.
|
||
|
||
### Misc
|
||
|
||
| Method | Path | Purpose |
|
||
|---|---|---|
|
||
| GET | `/kx/ui/{name}` | Serves theme assets (JS/CSS/vendored libs) and translation JSON files under the active UI theme |
|
||
| GET | `/` , `/printer{N}` | Serves the Web UI (index.html with CSS/JS inlined for embedded-webview compatibility, e.g. OrcaSlicer's device tab) |
|
||
| GET | `/favicon.ico` | Favicon |
|
||
|
||
---
|
||
|
||
## Response conventions
|
||
|
||
- Moonraker-compatible endpoints wrap results as `{"result": {...}}` (or
|
||
`{"error": {"code": ..., "message": ...}}` for the `/server/database/*`
|
||
404 case) to match the real Moonraker schema.
|
||
- Bridge-specific `/api/...` and `/kx/...` endpoints generally return
|
||
`{"result": ...}` on success and `{"error": "message"}` with a
|
||
non-2xx HTTP status on failure — but this is not universal; check the
|
||
handler in `kobrax_moonraker_bridge.py` if exact shape matters (route
|
||
registrations are near the end of the file, search for
|
||
`r.add_get(`/`r.add_post(`/`r.add_delete(`).
|
||
- Endpoints that trigger a config write (`/api/settings`,
|
||
`/kx/printers/add`, `/kx/printers/{pid}` DELETE) restart the whole
|
||
bridge process shortly after responding — clients should expect a
|
||
brief connection drop.
|