Fleet
Fleet software updates
Create a bounded signed artifact rollout for up to 100 robots, watch per-device commands and ACKs, and request rollback only when a previous version was captured.
On this page
Start here
Track every selected robot through a staged rollout wave and device-confirmed terminal result. Legacy single-target rows remain readable but do not imply signed artifact delivery or device-confirmed rollback.
Before you begin
- Workspace operator access to /app/fleet/ota-updates
- 1-100 eligible robot IDs or one workspace cohort, desired firmware_version, and an HTTPS artifact on the deployment allowlist
- A SHA-256 digest, size, Ed25519 signature metadata, and device support for attempt-scoped commands and ACKs
Put it into practice
-
Snapshot and stage targets
POST /api/v1/operator/ota-updates/rollouts with robot_ids or cohort_id, firmware_version, artifact, and rollout_percentage 0-100. The server snapshots up to 100 eligible robots in stable UUID order. 0% stays staged; a positive first wave uses ceil(target_count × percentage / 100).
-
Watch installation progress
Read /api/v1/operator/ota-updates/:id/attempts for per-target wave, command_id, previous_version, phase, bounded result and error. A later wave promotes only after every current-wave device reports success; acceptance or dispatch alone is not installation success.
-
Require a device result
The authenticated target robot reports matching command_id and monotonic phase through /api/v1/robots/me/ota-attempts/:id/acknowledge. completed and rolled_back require verified_version. The device must verify fetched artifact bytes, digest and signature; the server only validates metadata and ACK correlation. Rollback sends a device-local command to a known previous_version and remains requested until a matching robot ACK.
Each target has a device-reported completed/failed/rolled_back outcome or an explicit unresolved state; no server-side timer fabricates success.
01 What is shipped
detailsConsole and API create one update
The signed artifact includes an allowlisted HTTPS URI without query/userinfo/fragment, 64-hex SHA-256 digest, byte size 1..2,147,483,648 and an Ed25519 signature (key ID plus base64 value). Metadata is validated server-side; device software must verify actual bytes before installation.
Device acknowledgement is authoritative
New rollouts dispatch fleet.ota.install and fleet.ota.rollback commands on the fleet queue. The preferred ACK route is /api/v1/robots/me/ota-attempts/:id/acknowledge, requiring the authenticated robot and exact command_id. The legacy /robots/me/ota-updates/:id/acknowledge remains for old single-target rows; it does not convert their partial artifact-less state into a verified rollout. Unknown previous_version is omitted, not the text "nil".
List filters are nested
GET /api/v1/operator/ota-updates validates params["filter"] only. ?status=pending is ignored; use filter[status], filter[update_type], filter[robot_id], and filter[limit] (default 100, maximum 500). A multi-target rollout appears once for each matching robot filter and in each target's history/insight; its legacy robot_id remains the representative first target. POST /api/v1/operator/ota-updates/:id/rollback may include attempt_id for any install target in that rollout. Omitting it selects the legacy representative robot; conflicting robot_id selectors are rejected. A 202 is only a request until that exact target confirms rollback.
02 Signed rollout request shape
example{
"rollout": {
"robot_ids": ["ROBOT_UUID"],
"firmware_version": "2.0.0",
"rollout_percentage": 25,
"artifact": {
"uri": "https://allowlisted-updates.example/robot-v2.bin",
"sha256": "64_HEX_DIGEST_FROM_BUILT_ARTIFACT",
"size_bytes": 1048576,
"signature": {
"algorithm": "ed25519",
"key_id": "release-key-2026",
"value": "BASE64_SIGNATURE_OF_RELEASE_METADATA"
}
}
}
}
Troubleshooting
- An attempt remains installing or interrupted
- Inspect command delivery_state and the attempt command ID. Accepted work may have reached the robot; transport loss is outcome unknown and must not trigger blind reinstallation. Ask the target to report its current version and bound result.
- Rollback is refused
- Legacy or imported rows without previous_version cannot request a physical rollback. A signed rollout with a known prior version creates a rollback attempt and rollback command; a 202 rollback_requested response is not proof of device stop or rollback completion.
- A list filter is ignored
- Use filter[status], filter[update_type], filter[robot_id], or filter[limit]. Top-level status and other keys are not read by this endpoint.