The current API is the firmware dashboard's interface, documented here for 3.10.4. Routes are not under /v1, and there is no separate API schema/version field or SDK stability guarantee. Read firmware_version, validate the fields you need, ignore unknown fields, and verify an integration when updating firmware.
| Status | Meaning and handling |
|---|---|
| 200 | Request succeeded at the handler level. Inspect the returned state; calibration/control changes may still be in progress. Firmware upload returns 200 before restart/boot validation completes. |
| 202 | Accepted for processing. For scaler/DAC actions this is not completion or persistence confirmation. |
| 303 | A settings handler is redirecting a browser to /settings. Send Accept: application/json to receive state instead. |
| 400 | Invalid or oversized input, malformed fields, unsupported values, or some transfer/precondition failures. Read the body. |
| 401 | Optional LAN access is enabled and the code/session is missing, invalid or expired. Authenticate before making another request. |
| 403 | Request guard rejected Host/Origin/header, mutations are blocked during firmware update/startup verification, or an account change supplied the wrong current password. |
| 404 | Requested resource is unavailable, for example a print thumbnail. |
| 408 | Firmware upload reception was interrupted or timed out. |
| 409 | Current device state prevents an action, or a calibration/upload guard rejected it. Read the specific response. |
| 413 | Upload size falls outside endpoint-specific bounds, including empty/undersized bodies. |
| 429 | Dashboard-password or developer-code attempts are throttled independently. Respect Retry-After in seconds. |
| 500 | Internal or persistence failure. State may have changed in RAM even if saving failed. |
| 503 | Temporary unavailability, such as factory reset, a busy password/page worker, or unavailable access storage. Wait for the active operation; do not repeatedly submit credential changes. |
Errors do not have a uniform JSON schema. The request guard returns {"error":"..."}; many control failures return plain text. Parse JSON when possible and otherwise retain response text. Do not rely on human-readable message strings as permanent error codes. Endpoint-specific status behavior is described in the relevant reference.
Example guard response:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{"error":"Missing request header"}
Example control failure:
HTTP/1.1 409 Conflict
Enable Bed in Settings before using bed control
The HAT accepts its setup address 10.0.0.1, its active LAN IP, its hostname, or that hostname with .local. Connecting through an unrelated hostname with a different Host header is rejected. HTTP accepts the host alone or port 80; WebSocket accepts the host alone or port 81.
Native HTTP clients may omit Origin. If Origin is present, it must be the HAT's matching http://host or http://host:80, without a trailing slash. WebSocket handshakes must supply this matching HTTP Origin even though the socket connects to port 81. https://..., the wiki's domain, null, or the WebSocket URL itself do not meet this check.
All HTTP mutations require X-Tyson-Request: 1. This marker is independent of optional dashboard and developer authentication. Firmware 3.10.0 separates dashboard ID/password sessions from developer API codes. API requests require an enabled developer-code header or a valid dashboard session whenever access protection is on. The older /auth routes remain absent; current account and code endpoints are under /access. Firmware 3.9.0 accepted its code for dashboard login; 3.10.0 requires the separate account. A hosted website cannot call the HAT as an ordinary cross-origin browser integration; no general CORS/OPTIONS integration is implemented. Do not expose the controller directly as the public wiki's backend.
Operations can span several workers or a restart. Compare the resulting live fields to the requested state:
ack_id, inspect chamber_setpoint, and separately inspect actual heater state.scaler_maximum, scaler_active_maximum, pending/save-error fields and the selected hotend's state.Read-back confirms the firmware's reported state; it is not a measurement that an external heater, relay or printer physically behaved as expected.
Dashboard custom-password verification takes longer than a developer-code state read. Firmware 3.10.4 measured about 9 seconds for custom login and 18–25 seconds for account changes with connected printer telemetry. The dashboard allows 300 seconds for password operations; the worker enforces a 240-second processing deadline. Keep these timeouts separate from normal API read timeouts and serialize authentication operations. See password-operation guidance.
A failed connection or lost reply leaves command outcome uncertain. Do not blindly retry heater, calibration, reset, firmware or printer-control actions. Reconnect and read current state first. A command id correlates a WebSocket reply; it is not an idempotency key or a transaction number with server-side deduplication.
Within one boot_id, state_seq lets you discard older snapshots. A new boot resets that comparison. Retire pending acknowledgements after a restart and require the calling application/user to decide whether a new command is appropriate.
There is no API lock or compare-and-swap for ordinary configuration edits. A user in the dashboard and an external client can change settings at the same time. Read before editing and send complete fields where an endpoint requires them. Printer control has a specific revision field to detect stale print-job commands; it does not provide a global settings lock.
The HTTP and WebSocket examples apply to the Bambu-connected build. Right-hotend operations require a recognized X2D; P2S cannot enable that channel through the API. Calibration and hardware availability checks remain authoritative. The Prusa CORE One Tyson HAT V2 manual provides separate Prusa setup instructions; it does not establish compatibility with this Bambu firmware/API. CORE One L documentation is still pending.
Check Configuration before implementing a generic settings editor: omitted booleans do not consistently mean “leave unchanged.”