Log in Create workspace
Skip to content

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.

API docs
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

  1. 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).

  2. 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.

  3. 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.

What success looks like

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

details

Console 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
json
{
  "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.

Where to go next

see also