Robots Center Agents Network
Log in Create workspace
Skip to content

API reference

Operator - Fleet

One tag: method, path, summary, auth, and scopes. Request and response fields ship in this page — expand a row to read the contract.

Endpoints

48
GET
/api/v1/operator/robots Web Session

List robots

Description

Returns all robots in the current workspace, with optional status and type filters.

Auth

Web Session
Parameters
Name In Type Required Description
status query string No Filter by robot status. Decommissioned robots are hidden unless `status=decommissioned` is requested explicitly.
robot_type query string No Filter by robot type
cohort_id query string No Restrict to entities whose robot belongs to this cohort, statically or by rule
tag query string No Restrict to entities whose robot carries this tag (lowercased and trimmed). Exactly one tag; a value that does not resolve to a single tag matches nothing rather than being ignored.
Responses
200

List of robots

Returns: RobotList

Example
{
  "robots": [
    {
      "battery_level": 82,
      "capabilities": [
        "navigate",
        "pickup",
        "delivery"
      ],
      "firmware_version": "3.2.1",
      "id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "inserted_at": "2026-03-25T08:00:00Z",
      "last_seen_at": "2026-03-27T09:12:10Z",
      "location": {
        "lat": 41.717,
        "lng": 44.793,
        "zone": "A3"
      },
      "manufacturer": "RoboWorks",
      "metadata": {
        "shift": "day"
      },
      "model": "AX-7",
      "name": "Aisle Runner 7",
      "robot_type": "amr",
      "serial_number": "AMR-AX7-0042",
      "service_agent_id": "f4d49601-3477-4c9d-b896-ac08a26a3147",
      "status": "online",
      "tags": [
        "night-shift",
        "warehouse-b"
      ],
      "updated_at": "2026-03-27T09:12:10Z",
      "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
    }
  ]
}
POST
/api/v1/operator/robots Web Session

Register robot

Description

Registers a new robot in the current workspace.

Auth

Web Session
Request Body
Field Type Required Description
robot object Yes Robot attributes
robot.name string Yes Robot name (2-120 characters)
robot.metadata object No Arbitrary metadata key-value pairs
robot.location object No Current location (lat, lng, floor, zone)
robot.tags array<object> No Free-form tags (lowercased and trimmed, max 32 tags of 64 characters)
robot.service_agent_id string Yes Canonical service-agent UUID linked to this robot
robot.capabilities array<object> No List of robot capabilities
robot.firmware_version string No Current firmware version
robot.serial_number string Yes Globally unique serial number
robot.battery_level integer No Battery level (0-100)
robot.manufacturer string No Manufacturer name
robot.model string No Model name
robot.robot_type string (amr, drone, manipulator, humanoid) No Robot type
Responses
201

Robot registered

Returns: Robot

Example
{
  "battery_level": 82,
  "capabilities": [
    "navigate",
    "pickup",
    "delivery"
  ],
  "firmware_version": "3.2.1",
  "id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "inserted_at": "2026-03-25T08:00:00Z",
  "last_seen_at": "2026-03-27T09:12:10Z",
  "location": {
    "lat": 41.717,
    "lng": 44.793,
    "zone": "A3"
  },
  "manufacturer": "RoboWorks",
  "metadata": {
    "shift": "day"
  },
  "model": "AX-7",
  "name": "Aisle Runner 7",
  "robot_type": "amr",
  "serial_number": "AMR-AX7-0042",
  "service_agent_id": "f4d49601-3477-4c9d-b896-ac08a26a3147",
  "status": "online",
  "tags": [
    "night-shift",
    "warehouse-b"
  ],
  "updated_at": "2026-03-27T09:12:10Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
422

Validation error

POST
/api/v1/operator/robots/batch Web Session

Pre-register robots in bulk

Description

Creates one `pending` robot per serial number, with no service agent linked. Rows are independent: a duplicate serial, an invalid row, an unknown cohort name or a row past the plan's robot quota is reported against its own row number while the rest of the batch still lands. Maximum 1000 rows per request.

Auth

Web Session
Request Body
Field Type Required Description
robots array<object> Yes Rows to pre-register. Each row needs `serial_number`; `name`, `model`, `manufacturer`, `robot_type`, `cohort` (an existing cohort name) and `tags` are optional. The name defaults to the serial number.
Responses
201

Batch processed; per-row results returned

Returns: RobotBatchResult

Example
{
  "results": [
    {
      "row": 1,
      "serial_number": "AMR-AX7-0042",
      "status": "created"
    },
    {
      "row": 2,
      "serial_number": "AMR-AX7-0043",
      "status": "created"
    },
    {
      "errors": {},
      "reason": "duplicate_in_batch",
      "row": 3,
      "serial_number": "AMR-AX7-0042",
      "status": "skipped"
    }
  ],
  "robots": [
    {
      "battery_level": 82,
      "capabilities": [
        "navigate",
        "pickup",
        "delivery"
      ],
      "firmware_version": "3.2.1",
      "id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "inserted_at": "2026-03-25T08:00:00Z",
      "last_seen_at": "2026-03-27T09:12:10Z",
      "location": {
        "lat": 41.717,
        "lng": 44.793,
        "zone": "A3"
      },
      "manufacturer": "RoboWorks",
      "metadata": {
        "shift": "day"
      },
      "model": "AX-7",
      "name": "Aisle Runner 7",
      "robot_type": "amr",
      "serial_number": "AMR-AX7-0042",
      "service_agent_id": "f4d49601-3477-4c9d-b896-ac08a26a3147",
      "status": "online",
      "tags": [
        "night-shift",
        "warehouse-b"
      ],
      "updated_at": "2026-03-27T09:12:10Z",
      "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
    }
  ],
  "summary": {
    "created": 2,
    "skipped": 1,
    "total": 3
  }
}
400

Empty batch, more than 1000 rows, or a malformed payload

GET
/api/v1/operator/robots/:id Web Session

Get robot details

Description

Returns details of a specific robot.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Robot UUID
Responses
200

Robot details

Returns: Robot

Example
{
  "battery_level": 82,
  "capabilities": [
    "navigate",
    "pickup",
    "delivery"
  ],
  "firmware_version": "3.2.1",
  "id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "inserted_at": "2026-03-25T08:00:00Z",
  "last_seen_at": "2026-03-27T09:12:10Z",
  "location": {
    "lat": 41.717,
    "lng": 44.793,
    "zone": "A3"
  },
  "manufacturer": "RoboWorks",
  "metadata": {
    "shift": "day"
  },
  "model": "AX-7",
  "name": "Aisle Runner 7",
  "robot_type": "amr",
  "serial_number": "AMR-AX7-0042",
  "service_agent_id": "f4d49601-3477-4c9d-b896-ac08a26a3147",
  "status": "online",
  "tags": [
    "night-shift",
    "warehouse-b"
  ],
  "updated_at": "2026-03-27T09:12:10Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Robot not found

PUT
/api/v1/operator/robots/:id Web Session

Update robot

Description

Updates an existing robot's attributes.

Auth

Web Session
Request Body
Field Type Required Description
robot object Yes Robot attributes to update
robot.name string No Robot name
robot.metadata object No Metadata
robot.location object No Location
robot.tags array<object> No Free-form tags (lowercased and trimmed, max 32 tags of 64 characters)
robot.capabilities array<object> No Capabilities
robot.firmware_version string No Firmware version
robot.battery_level integer No Battery level (0-100)
robot.manufacturer string No Manufacturer name
robot.model string No Model name
Parameters
Name In Type Required Description
id path string Yes Robot UUID
Responses
200

Robot updated

Returns: Robot

Example
{
  "battery_level": 82,
  "capabilities": [
    "navigate",
    "pickup",
    "delivery"
  ],
  "firmware_version": "3.2.1",
  "id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "inserted_at": "2026-03-25T08:00:00Z",
  "last_seen_at": "2026-03-27T09:12:10Z",
  "location": {
    "lat": 41.717,
    "lng": 44.793,
    "zone": "A3"
  },
  "manufacturer": "RoboWorks",
  "metadata": {
    "shift": "day"
  },
  "model": "AX-7",
  "name": "Aisle Runner 7",
  "robot_type": "amr",
  "serial_number": "AMR-AX7-0042",
  "service_agent_id": "f4d49601-3477-4c9d-b896-ac08a26a3147",
  "status": "online",
  "tags": [
    "night-shift",
    "warehouse-b"
  ],
  "updated_at": "2026-03-27T09:12:10Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Robot not found

422

Validation error

DELETE
/api/v1/operator/robots/:id Web Session

Decommission robot

Description

Retires a robot permanently by setting its status to `decommissioned` and revoking the robot identity's credentials (the `agk_` key and any outstanding bearer token stop authenticating immediately, so a still-powered unit cannot report its way back onto the roster). The row is never deleted — mission, diagnostic and alert history stay intact and the robot is still readable by id — but it disappears from robot listings (unless `status=decommissioned` is requested), from mission auto-assignment and alert evaluation, and it stops counting against the plan's robot quota. This is distinct from `maintenance`, which is an in-service state.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Robot UUID
Responses
204

Robot decommissioned

404

Robot not found

POST
/api/v1/operator/robots/:id/heartbeat Web Session

Record robot heartbeat

Description

Records a robot heartbeat. Only `battery_level` (0-100), `location`, `firmware_version`, and `metadata` are cast. `last_seen_at` is set by the server. Claimed robots are moved to `online`; unclaimed `pending` pre-registrations stay `pending` so a heartbeat cannot take them off that state. The body may be wrapped in `heartbeat` or sent flat.

Auth

Web Session
Request Body
Field Type Required Description
heartbeat object No Optional wrapper. The same fields are accepted at the top level when the wrapper is omitted.
heartbeat.metadata object No Arbitrary metadata
heartbeat.location object No Current location
heartbeat.firmware_version string No Current firmware version
heartbeat.battery_level integer No Current battery level (0-100). Values outside that range return 422.
Parameters
Name In Type Required Description
id path string Yes Robot UUID
Responses
200

Heartbeat recorded

Returns: Robot

Example
{
  "battery_level": 82,
  "capabilities": [
    "navigate",
    "pickup",
    "delivery"
  ],
  "firmware_version": "3.2.1",
  "id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "inserted_at": "2026-03-25T08:00:00Z",
  "last_seen_at": "2026-03-27T09:12:10Z",
  "location": {
    "lat": 41.717,
    "lng": 44.793,
    "zone": "A3"
  },
  "manufacturer": "RoboWorks",
  "metadata": {
    "shift": "day"
  },
  "model": "AX-7",
  "name": "Aisle Runner 7",
  "robot_type": "amr",
  "serial_number": "AMR-AX7-0042",
  "service_agent_id": "f4d49601-3477-4c9d-b896-ac08a26a3147",
  "status": "online",
  "tags": [
    "night-shift",
    "warehouse-b"
  ],
  "updated_at": "2026-03-27T09:12:10Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Robot not found

410

The robot has been decommissioned and can no longer report

422

Validation error (invalid battery_level or other changeset errors)

GET
/api/v1/operator/missions Web Session

List missions

Description

Returns all missions in the current workspace, with optional status and robot filters.

Auth

Web Session
Parameters
Name In Type Required Description
status query string No Filter by mission status
robot_id query string No Filter by robot UUID
cohort_id query string No Restrict to entities whose robot belongs to this cohort, statically or by rule
tag query string No Restrict to entities whose robot carries this tag (lowercased and trimmed). Exactly one tag; a value that does not resolve to a single tag matches nothing rather than being ignored.
Responses
200

List of missions

Returns: MissionList

Example
{
  "missions": [
    {
      "completed_at": null,
      "description": "Collect 3 bins from aisle A and deliver to packing.",
      "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
      "inserted_at": "2026-03-27T09:10:00Z",
      "name": "Pick order #4821",
      "payload": {
        "order_id": "4821"
      },
      "priority": "high",
      "result": {},
      "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "scheduled_at": "2026-03-27T09:20:00Z",
      "started_at": null,
      "status": "assigned",
      "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
      "updated_at": "2026-03-27T09:12:00Z",
      "waypoints": {
        "waypoints": [
          {
            "lat": 41.717,
            "lng": 44.793,
            "order": 0
          }
        ]
      },
      "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
    }
  ]
}
POST
/api/v1/operator/missions Web Session

Create mission

Description

Creates a new mission in the current workspace.

Auth

Web Session
Request Body
Field Type Required Description
mission object Yes Mission attributes
mission.name string Yes Mission name (2-200 characters)
mission.priority string (low, normal, high, critical) No Priority level
mission.description string No Mission description
mission.payload object No Mission-specific payload. Auto-assign reads `payload.required_capabilities` (an array of strings) and prefers online robots whose capabilities overlap.
mission.scheduled_at datetime (ISO 8601) No Scheduled start time. ScheduledMissionWorker starts the mission when this timestamp has arrived and status is still pending.
mission.robot_id string No Robot UUID to assign
mission.waypoints object No Mission waypoints
Responses
201

Mission created

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
422

Validation error

GET
/api/v1/operator/missions/:id Web Session

Get mission details

Description

Returns details of a specific mission.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission details

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Mission not found

PUT
/api/v1/operator/missions/:id Web Session

Update mission

Description

Updates an existing mission's attributes.

Auth

Web Session
Request Body
Field Type Required Description
mission object Yes Mission attributes to update
mission.name string No Mission name
mission.priority string No Priority level
mission.description string No Description
mission.payload object No Payload data
mission.waypoints object No Waypoints
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission updated

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Mission not found

422

Validation error

POST
/api/v1/operator/missions/:id/assign Web Session

Assign robot to mission

Description

Assigns a robot to a pending or assigned mission.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
robot_id query string Yes Robot UUID to assign
Responses
200

Robot assigned

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid mission status for assignment

404

Mission or robot not found

POST
/api/v1/operator/missions/:id/start Web Session

Start mission

Description

Starts a pending or assigned mission. Creates a compliance trace automatically.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission started

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid mission status for starting

404

Mission not found

POST
/api/v1/operator/missions/:id/cancel Web Session

Cancel mission

Description

Cancels a non-terminal mission.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission cancelled

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid mission status for cancellation

404

Mission not found

POST
/api/v1/operator/missions/:id/pause Web Session

Pause mission

Description

Pauses an in-progress mission.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission paused

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid mission status for pausing

404

Mission not found

POST
/api/v1/operator/missions/:id/resume Web Session

Resume mission

Description

Resumes a paused mission.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission resumed

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid mission status for resuming

404

Mission not found

POST
/api/v1/operator/missions/:id/complete Web Session

Complete mission

Description

Completes an in-progress mission. Finalizes the associated trace with status :ok.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission completed

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid mission status for completing

404

Mission not found

POST
/api/v1/operator/missions/:id/fail Web Session

Fail mission

Description

Fails an in-progress or paused mission. Finalizes the associated trace with status :error.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission failed

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid mission status for failing

404

Mission not found

GET
/api/v1/operator/robots/:id/diagnostics Web Session

List robot diagnostics

Description

Returns diagnostic metrics for a robot, with optional metric name, status, and time range filters.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Robot UUID
metric_name query string No Filter by metric name (e.g. battery_health, motor_temp)
status query string No Filter by diagnostic status
since query datetime (ISO 8601) No ISO 8601 datetime lower bound for recorded_at
cohort_id query string No Restrict to entities whose robot belongs to this cohort, statically or by rule
tag query string No Restrict to entities whose robot carries this tag (lowercased and trimmed). Exactly one tag; a value that does not resolve to a single tag matches nothing rather than being ignored.
Responses
200

List of diagnostics

Returns: DiagnosticList

Example
{
  "diagnostics": [
    {
      "id": "b3ec0b4e-64be-44f3-a5f6-e6f54c8bf190",
      "inserted_at": "2026-03-27T09:11:30Z",
      "metadata": {},
      "metric_name": "battery_health",
      "metric_value": 76.5,
      "recorded_at": "2026-03-27T09:11:30Z",
      "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "status": "warning",
      "unit": "percent",
      "updated_at": "2026-03-27T09:11:30Z",
      "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
    }
  ]
}
POST
/api/v1/operator/robots/:id/diagnostics Web Session

Record robot diagnostic

Description

Records a new diagnostic metric reading for a robot.

Auth

Web Session
Request Body
Field Type Required Description
diagnostic object No Optional wrapper. The same fields are accepted at the top level when the wrapper is omitted.
diagnostic.status string (normal, warning, critical) No Diagnostic status
diagnostic.unit string No Unit of measurement (e.g. %, C, mm)
diagnostic.metadata object No Arbitrary metadata key-value pairs
diagnostic.metric_name string Yes Metric name (e.g. battery_health, motor_temp)
diagnostic.metric_value number Yes Numeric metric value
diagnostic.recorded_at datetime (ISO 8601) No When the metric was recorded (defaults to now)
Parameters
Name In Type Required Description
id path string Yes Robot UUID
Responses
201

Diagnostic recorded

Returns: Diagnostic

Example
{
  "id": "b3ec0b4e-64be-44f3-a5f6-e6f54c8bf190",
  "inserted_at": "2026-03-27T09:11:30Z",
  "metadata": {},
  "metric_name": "battery_health",
  "metric_value": 76.5,
  "recorded_at": "2026-03-27T09:11:30Z",
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "status": "warning",
  "unit": "percent",
  "updated_at": "2026-03-27T09:11:30Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Robot not found

410

The robot has been decommissioned and can no longer report

422

Validation error

GET
/api/v1/operator/robots/:id/health Web Session

Robot health summary

Description

Returns the latest metric reading for each diagnostic category and an overall health status.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Robot UUID
Responses
200

Health summary with per-metric latest readings

Returns: RobotHealthSummary

Example
{
  "metrics": [
    {
      "metric_name": "battery_health",
      "metric_value": 76.5,
      "recorded_at": "2026-03-27T09:11:30Z",
      "status": "warning",
      "unit": "percent"
    }
  ],
  "overall_status": "warning",
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22"
}
404

Robot not found

GET
/api/v1/operator/fleet-alerts Web Session

List fleet alerts

Description

Returns all fleet alerts for the workspace, with optional filters for severity, status, robot, and alert type.

Auth

Web Session
Parameters
Name In Type Required Description
severity query string No Filter by severity
status query string No Filter by alert status
robot_id query string No Filter by robot UUID
alert_type query string No Filter by alert type
cohort_id query string No Restrict to entities whose robot belongs to this cohort, statically or by rule
tag query string No Restrict to entities whose robot carries this tag (lowercased and trimmed). Exactly one tag; a value that does not resolve to a single tag matches nothing rather than being ignored.
Responses
200

List of fleet alerts

Returns: FleetAlertList

Example
{
  "alerts": [
    {
      "acknowledged_at": null,
      "acknowledged_by": null,
      "alert_type": "battery_low",
      "id": "804db680-c8f5-4280-b147-35fca5f754a6",
      "inserted_at": "2026-03-27T09:12:00Z",
      "message": "Battery dropped below 15% during active shift.",
      "metadata": {},
      "resolved_at": null,
      "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "severity": "critical",
      "status": "active",
      "title": "Battery below critical threshold",
      "updated_at": "2026-03-27T09:12:00Z",
      "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
    }
  ]
}
GET
/api/v1/operator/fleet-alerts/:id Web Session

Get fleet alert

Description

Returns details of a specific fleet alert.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Fleet alert UUID
Responses
200

Fleet alert details

Returns: FleetAlert

Example
{
  "acknowledged_at": null,
  "acknowledged_by": null,
  "alert_type": "battery_low",
  "id": "804db680-c8f5-4280-b147-35fca5f754a6",
  "inserted_at": "2026-03-27T09:12:00Z",
  "message": "Battery dropped below 15% during active shift.",
  "metadata": {},
  "resolved_at": null,
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "severity": "critical",
  "status": "active",
  "title": "Battery below critical threshold",
  "updated_at": "2026-03-27T09:12:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Alert not found

POST
/api/v1/operator/fleet-alerts/:id/acknowledge Web Session

Acknowledge fleet alert

Description

Acknowledges an active fleet alert, marking it as seen by an operator.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Fleet alert UUID
Responses
200

Alert acknowledged

Returns: FleetAlert

Example
{
  "acknowledged_at": null,
  "acknowledged_by": null,
  "alert_type": "battery_low",
  "id": "804db680-c8f5-4280-b147-35fca5f754a6",
  "inserted_at": "2026-03-27T09:12:00Z",
  "message": "Battery dropped below 15% during active shift.",
  "metadata": {},
  "resolved_at": null,
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "severity": "critical",
  "status": "active",
  "title": "Battery below critical threshold",
  "updated_at": "2026-03-27T09:12:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid alert status

404

Alert not found

POST
/api/v1/operator/fleet-alerts/:id/resolve Web Session

Resolve fleet alert

Description

Resolves an active or acknowledged fleet alert.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Fleet alert UUID
Responses
200

Alert resolved

Returns: FleetAlert

Example
{
  "acknowledged_at": null,
  "acknowledged_by": null,
  "alert_type": "battery_low",
  "id": "804db680-c8f5-4280-b147-35fca5f754a6",
  "inserted_at": "2026-03-27T09:12:00Z",
  "message": "Battery dropped below 15% during active shift.",
  "metadata": {},
  "resolved_at": null,
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "severity": "critical",
  "status": "active",
  "title": "Battery below critical threshold",
  "updated_at": "2026-03-27T09:12:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid alert status

404

Alert not found

GET
/api/v1/operator/fleet/alerts/summary Web Session

Fleet alert summary

Description

Returns counts of fleet alerts grouped by status and severity.

Auth

Web Session
Responses
200

Alert counts by status and severity

Returns: FleetAlertSummary

Example
{
  "acknowledged": 4,
  "active": 3,
  "by_severity": {
    "critical": 3,
    "error": 4,
    "info": 1,
    "warning": 6
  },
  "resolved": 7,
  "total": 14
}
GET
/api/v1/operator/ota-updates Web Session

List OTA updates

Description

Returns all OTA updates in the current workspace. Filters are read only from the nested `filter` map — `?status=pending` is ignored. Use `filter[status]`, `filter[update_type]`, and `filter[robot_id]`.

Auth

Web Session
Parameters
Name In Type Required Description
filter[status] query string No Filter by OTA update status. Top-level `?status=` is ignored.
filter[update_type] query string No Filter by update type. Top-level `?update_type=` is ignored.
filter[robot_id] query string No Filter by robot UUID. Top-level `?robot_id=` is ignored.
Responses
200

List of OTA updates

Returns: OTAUpdateList

Example
{
  "ota_updates": [
    {
      "completed_at": null,
      "error_message": null,
      "firmware_version": "3.3.0",
      "id": "5ed7cc57-e9a0-44b9-b345-8d8cc6ddf1aa",
      "inserted_at": "2026-03-27T09:12:00Z",
      "metadata": {},
      "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "rollback_version": null,
      "rollout_percentage": 100,
      "scheduled_at": "2026-03-27T09:25:00Z",
      "status": "downloading",
      "update_type": "firmware",
      "updated_at": "2026-03-27T09:14:00Z",
      "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
    }
  ]
}
POST
/api/v1/operator/ota-updates Web Session

Schedule OTA update

Description

Creates an OTA update for one required robot. OTAUpdateWorker advances that row from `pending` to `downloading` to `installing`, then leaves the terminal `completed` or `failed` result to that robot's explicit device acknowledgement. Fleet-wide fan-out is not implemented. Treat `rollout_percentage` as stored metadata, not a shipped rollout contract.

Auth

Web Session
Request Body
Field Type Required Description
ota_update object Yes OTA update attributes
ota_update.update_type string (firmware, software, config, security_patch) Yes Type of update
ota_update.scheduled_at datetime (ISO 8601) No When to apply the update
ota_update.robot_id string Yes Target robot UUID
ota_update.firmware_version string Yes Target firmware/software version
ota_update.rollout_percentage integer No Stored integer 0-100 (default 100). The worker does not read this field and does not fan out a rollout.
Responses
201

OTA update scheduled

Returns: OTAUpdate

Example
{
  "completed_at": null,
  "error_message": null,
  "firmware_version": "3.3.0",
  "id": "5ed7cc57-e9a0-44b9-b345-8d8cc6ddf1aa",
  "inserted_at": "2026-03-27T09:12:00Z",
  "metadata": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "rollback_version": null,
  "rollout_percentage": 100,
  "scheduled_at": "2026-03-27T09:25:00Z",
  "status": "downloading",
  "update_type": "firmware",
  "updated_at": "2026-03-27T09:14:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
422

Validation error

GET
/api/v1/operator/ota-updates/:id Web Session

Get OTA update details

Description

Returns details of a specific OTA update.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes OTA update UUID
Responses
200

OTA update details

Returns: OTAUpdate

Example
{
  "completed_at": null,
  "error_message": null,
  "firmware_version": "3.3.0",
  "id": "5ed7cc57-e9a0-44b9-b345-8d8cc6ddf1aa",
  "inserted_at": "2026-03-27T09:12:00Z",
  "metadata": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "rollback_version": null,
  "rollout_percentage": 100,
  "scheduled_at": "2026-03-27T09:25:00Z",
  "status": "downloading",
  "update_type": "firmware",
  "updated_at": "2026-03-27T09:14:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

OTA update not found

POST
/api/v1/operator/ota-updates/:id/rollback Web Session

Rollback OTA update

Description

Rolls back a completed or failed OTA update to the rolled_back status.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes OTA update UUID
Responses
200

OTA update rolled back

Returns: OTAUpdate

Example
{
  "completed_at": null,
  "error_message": null,
  "firmware_version": "3.3.0",
  "id": "5ed7cc57-e9a0-44b9-b345-8d8cc6ddf1aa",
  "inserted_at": "2026-03-27T09:12:00Z",
  "metadata": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "rollback_version": null,
  "rollout_percentage": 100,
  "scheduled_at": "2026-03-27T09:25:00Z",
  "status": "downloading",
  "update_type": "firmware",
  "updated_at": "2026-03-27T09:14:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

Invalid status for rollback

404

OTA update not found

GET
/api/v1/operator/ota-updates/:id/status Web Session

Get OTA update status

Description

Returns the current status of an OTA update.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes OTA update UUID
Responses
200

OTA update status

Returns: OTAUpdate

Example
{
  "completed_at": null,
  "error_message": null,
  "firmware_version": "3.3.0",
  "id": "5ed7cc57-e9a0-44b9-b345-8d8cc6ddf1aa",
  "inserted_at": "2026-03-27T09:12:00Z",
  "metadata": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "rollback_version": null,
  "rollout_percentage": 100,
  "scheduled_at": "2026-03-27T09:25:00Z",
  "status": "downloading",
  "update_type": "firmware",
  "updated_at": "2026-03-27T09:14:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

OTA update not found

PUT
/api/v1/operator/missions/:id/waypoints Web Session

Update mission waypoints

Description

Replaces the waypoints for a mission with the provided list. Each waypoint must include lat, lng, and an optional action.

Auth

Web Session
Request Body
Field Type Required Description
waypoints array<object> Yes List of waypoints
waypoints[].params object No Additional parameters for the action
waypoints[].action string No Action at waypoint (pickup, deliver, etc.)
waypoints[].lat number Yes Latitude
waypoints[].lng number Yes Longitude
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Waypoints updated

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Mission not found

POST
/api/v1/operator/missions/:id/auto-assign Web Session

Auto-assign mission to robot

Description

Automatically assigns the best available online robot to a pending mission. Selection prefers higher battery and, when `payload.required_capabilities` is a non-empty array, robots whose capabilities overlap that list.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Mission UUID
Responses
200

Mission auto-assigned

Returns: Mission

Example
{
  "completed_at": null,
  "description": "Collect 3 bins from aisle A and deliver to packing.",
  "id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
  "inserted_at": "2026-03-27T09:10:00Z",
  "name": "Pick order #4821",
  "payload": {
    "order_id": "4821"
  },
  "priority": "high",
  "result": {},
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "scheduled_at": "2026-03-27T09:20:00Z",
  "started_at": null,
  "status": "assigned",
  "trace_id": "6646e3ff-8f2f-4204-ad5c-f4ebc1830f9e",
  "updated_at": "2026-03-27T09:12:00Z",
  "waypoints": {
    "waypoints": [
      {
        "lat": 41.717,
        "lng": 44.793,
        "order": 0
      }
    ]
  },
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
400

No available robots or invalid status

POST
/api/v1/operator/missions/auto-assign-all Web Session

Auto-assign all pending missions

Description

Automatically assigns all pending missions to available robots, prioritized by mission priority. The JSON view returns `%{results: results}` with the context tuples from `auto_assign_pending_missions/1` unchanged — each item is `{:ok, %{mission_id, robot_id}}` or `{:error, %{mission_id, reason}}`. It does not remap those tuples to `{status, mission_id, robot_id}`.

Auth

Web Session
Responses
200

Assignment results. `results` is the dumped list of context tuples, not remapped maps.

Returns: MissionAutoAssignResults

Example
{
  "results": [
    [
      "ok",
      {
        "mission_id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b1",
        "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22"
      }
    ],
    [
      "error",
      {
        "mission_id": "d11b00f4-74fd-4fe5-a2d2-0f0b8ef8d6b2",
        "reason": "no_available_robot"
      }
    ]
  ]
}
GET
/api/v1/operator/robots/:id/maintenance-check Web Session

Check robot maintenance needs

Description

Analyzes recent diagnostics for a robot and predicts maintenance needs. Creates fleet alerts for detected issues.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Robot UUID
Responses
200

Maintenance analysis results

Returns: MaintenanceCheckResult

Example
{
  "alerts_created": 1,
  "predictions": {
    "battery_health": "warning",
    "critical_metrics": "normal",
    "motor_temperature": "normal"
  },
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22"
}
404

Robot not found

GET
/api/v1/operator/fleet/maintenance-predictions Web Session

Fleet maintenance predictions

Description

Returns all robots predicted to need maintenance soon based on recent diagnostic trends.

Auth

Web Session
Responses
200

List of robots needing maintenance

Returns: FleetMaintenancePredictions

Example
{
  "predictions": [
    {
      "predictions": {
        "battery_health": "warning",
        "critical_metrics": "normal",
        "motor_temperature": "normal"
      },
      "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22"
    }
  ]
}
GET
/api/v1/operator/cohorts Web Session

List cohorts

Description

Returns the groups and sites defined in the current workspace, each with its static member count.

Auth

Web Session
Parameters
Name In Type Required Description
kind query string No Filter by cohort kind
query query string No Case-insensitive match on name or description
limit query integer No Maximum cohorts to return (default 100, server maximum 500)
Responses
200

List of cohorts

Returns: CohortList

Example
{
  "cohorts": [
    {
      "description": "Cold storage aisles",
      "id": "0b1f4a52-9de7-4a2f-93de-4a94f38f4a11",
      "inserted_at": "2026-08-03T08:00:00Z",
      "kind": "site",
      "member_count": 2,
      "name": "Warehouse B",
      "rules": {
        "robot_type": "amr",
        "tags_any": [
          "night-shift"
        ]
      },
      "site_meta": {
        "building": "B",
        "floor": "1",
        "zone": "cold-storage"
      },
      "updated_at": "2026-08-03T08:00:00Z",
      "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
    }
  ]
}
POST
/api/v1/operator/cohorts Web Session

Create cohort

Description

Creates a group or site cohort. Names are unique per workspace. Supplying `rules` makes membership dynamic: robots matching the rule appear as members at read time without membership rows.

Auth

Web Session
Request Body
Field Type Required Description
name string Yes Cohort name (2-120 characters)
description string No Free-form description
kind string (group, site) No Cohort kind (defaults to group)
rules object No Dynamic membership rule. Supported keys: robot_type, manufacturer, model, firmware_version, capabilities (array), tags_any (array). Keys combine with AND.
site_meta object No Site metadata: building, floor, zone. Other keys are ignored.
Responses
201

Cohort created

Returns: Cohort

Example
{
  "description": "Cold storage aisles",
  "id": "0b1f4a52-9de7-4a2f-93de-4a94f38f4a11",
  "inserted_at": "2026-08-03T08:00:00Z",
  "kind": "site",
  "member_count": 2,
  "name": "Warehouse B",
  "rules": {
    "robot_type": "amr",
    "tags_any": [
      "night-shift"
    ]
  },
  "site_meta": {
    "building": "B",
    "floor": "1",
    "zone": "cold-storage"
  },
  "updated_at": "2026-08-03T08:00:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
422

Validation error

GET
/api/v1/operator/cohorts/:id Web Session

Get cohort details

Description

Returns a cohort with a bounded page of its static membership rows. Rule-matched members are not membership rows and are not listed here — query the robots endpoint with `cohort_id` for the full membership.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Cohort UUID
limit query integer No Maximum membership rows to return (default 100, server maximum 500)
Responses
200

Cohort details

Returns: Cohort

Example
{
  "description": "Cold storage aisles",
  "id": "0b1f4a52-9de7-4a2f-93de-4a94f38f4a11",
  "inserted_at": "2026-08-03T08:00:00Z",
  "kind": "site",
  "member_count": 2,
  "name": "Warehouse B",
  "rules": {
    "robot_type": "amr",
    "tags_any": [
      "night-shift"
    ]
  },
  "site_meta": {
    "building": "B",
    "floor": "1",
    "zone": "cold-storage"
  },
  "updated_at": "2026-08-03T08:00:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Cohort not found

PATCH
/api/v1/operator/cohorts/:id Web Session

Update cohort

Description

Updates a cohort's name, kind, description, site metadata or rules.

Auth

Web Session
Request Body
Field Type Required Description
cohort object Yes Cohort attributes to update
cohort.name string No Cohort name
cohort.description string No Description
cohort.kind string (group, site) No Cohort kind
cohort.rules object No Dynamic membership rule, or null to make membership static only
cohort.site_meta object No building / floor / zone
Parameters
Name In Type Required Description
id path string Yes Cohort UUID
Responses
200

Cohort updated

Returns: Cohort

Example
{
  "description": "Cold storage aisles",
  "id": "0b1f4a52-9de7-4a2f-93de-4a94f38f4a11",
  "inserted_at": "2026-08-03T08:00:00Z",
  "kind": "site",
  "member_count": 2,
  "name": "Warehouse B",
  "rules": {
    "robot_type": "amr",
    "tags_any": [
      "night-shift"
    ]
  },
  "site_meta": {
    "building": "B",
    "floor": "1",
    "zone": "cold-storage"
  },
  "updated_at": "2026-08-03T08:00:00Z",
  "workspace_id": "4ce4d170-e6d5-4118-8f4d-fac69dc099ea"
}
404

Cohort not found

422

Validation error

DELETE
/api/v1/operator/cohorts/:id Web Session

Delete cohort

Description

Deletes a cohort and its membership rows. Member robots and service agents are untouched.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Cohort UUID
Responses
204

Cohort deleted

404

Cohort not found

POST
/api/v1/operator/cohorts/:cohort_id/members Web Session

Add cohort member

Description

Adds a robot or a service agent to a cohort. Supply exactly one of `robot_id` / `service_agent_id`. Robots that have not been claimed yet can be added — a linked service agent is not required.

Auth

Web Session
Request Body
Field Type Required Description
service_agent_id string No Service agent UUID to enroll
robot_id string No Robot UUID to enroll
Parameters
Name In Type Required Description
cohort_id path string Yes Cohort UUID
Responses
201

Member added

Returns: CohortMembership

Example
{
  "cohort_id": "0b1f4a52-9de7-4a2f-93de-4a94f38f4a11",
  "id": "6d1b1a5e-0f27-4f2b-9f4b-4f2f0a5f9c31",
  "inserted_at": "2026-08-03T08:00:00Z",
  "robot_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
  "service_agent_id": null
}
400

Member does not belong to this workspace

404

Cohort not found

422

Validation error

GET
/api/v1/operator/batch_operations Web Session

List bulk operations

Description

Returns bulk fleet operations newest first, with their live counts. Always bounded: `limit` defaults to 25 and is clamped to 100.

Auth

Web Session
Parameters
Name In Type Required Description
status query string No Filter by batch status
kind query string No Filter by action kind
limit query integer No Maximum batches to return (default 25, server maximum 100)
Responses
200

List of bulk operations

Returns: BatchOperationList

Example
{
  "batch_operations": [
    {
      "failed_count": 1,
      "filter_snapshot": {
        "cohort_id": "6f1c0f2a-1b2c-4d5e-8f90-1a2b3c4d5e6f"
      },
      "id": "0a0f1f5c-4f4c-4a2e-8f2b-6c0a2c1f0d11",
      "kind": "apply_tags",
      "params": {
        "tags": [
          "audit-2026q3"
        ]
      },
      "parent_id": null,
      "progress": {
        "failed": 1,
        "queued": 0,
        "running": 0,
        "skipped": 1,
        "succeeded": 40
      },
      "reason": "Q3 physical audit",
      "selection_mode": "filter",
      "skipped_count": 1,
      "status": "completed_with_errors",
      "succeeded_count": 40,
      "targets": [
        {
          "attempts": 1,
          "error": null,
          "id": "d5a1c7f0-1e2d-4c3b-9a8f-7e6d5c4b3a21",
          "skip_reason": "robot_decommissioned",
          "status": "skipped",
          "target_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
          "target_type": "robot"
        }
      ],
      "total_count": 42,
      "workspace_id": "9a2f0d3e-2b7b-4a1f-9c2a-9a0b1c2d3e4f"
    }
  ]
}
POST
/api/v1/operator/batch_operations Web Session

Start a bulk operation

Description

Applies one action to many robots and returns immediately; the work runs on the `fleet` queue and progress is readable from the show endpoint or the `fleet.batch_operation.*` realtime events. Supply exactly one selection: `robot_ids` (an explicit list) or `filter` (the same filter the fleet board uses). A `filter` selection is **snapshotted at creation** — robots that start matching afterwards are not swept in. Selections are capped at 5000 targets. Decommissioned robots are never targeted, and a robot retired between selection and execution is recorded as `skipped` rather than mutated. `set_status` accepts only operator-settable statuses (online, offline, charging, error, maintenance); `pending` and `decommissioned` belong to the claim and decommission flows and are rejected.

Auth

Web Session
Request Body
Field Type Required Description
reason string No Why this was run. Recorded on the audit event (max 500 characters).
filter object No Fleet-board filter to expand into targets: `query`, `status`, `robot_type`, `cohort_id`, `tag`. An empty map means every in-service robot.
params object Yes Action parameters: `status` for set_status; `tags` (array) for apply_tags/remove_tags; `cohort_id` for add_to_cohort/remove_from_cohort; `command_type` and optional `payload` for dispatch_command; none for acknowledge_alerts.
kind string (set_status, apply_tags, remove_tags, add_to_cohort, remove_from_cohort, dispatch_command, acknowledge_alerts) Yes The action to apply to every target
robot_ids array<object> No Explicit robot UUIDs. Ids outside this workspace and retired units are dropped.
Responses
201

Batch created and queued

Returns: BatchOperation

Example
{
  "failed_count": 1,
  "filter_snapshot": {
    "cohort_id": "6f1c0f2a-1b2c-4d5e-8f90-1a2b3c4d5e6f"
  },
  "id": "0a0f1f5c-4f4c-4a2e-8f2b-6c0a2c1f0d11",
  "kind": "apply_tags",
  "params": {
    "tags": [
      "audit-2026q3"
    ]
  },
  "parent_id": null,
  "progress": {
    "failed": 1,
    "queued": 0,
    "running": 0,
    "skipped": 1,
    "succeeded": 40
  },
  "reason": "Q3 physical audit",
  "selection_mode": "filter",
  "skipped_count": 1,
  "status": "completed_with_errors",
  "succeeded_count": 40,
  "targets": [
    {
      "attempts": 1,
      "error": null,
      "id": "d5a1c7f0-1e2d-4c3b-9a8f-7e6d5c4b3a21",
      "skip_reason": "robot_decommissioned",
      "status": "skipped",
      "target_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "target_type": "robot"
    }
  ],
  "total_count": 42,
  "workspace_id": "9a2f0d3e-2b7b-4a1f-9c2a-9a0b1c2d3e4f"
}
400

Unknown kind, invalid params for the kind, an empty selection, or more than 5000 targets

GET
/api/v1/operator/batch_operations/:id Web Session

Get bulk operation progress

Description

Returns a batch with counts derived from its target rows and a bounded page of per-target outcomes, each carrying its error or skip reason.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Batch operation UUID
target_status query string No Only return targets in this state
target_limit query integer No Maximum target rows to return (default 100, server maximum 500)
Responses
200

Batch with progress and targets

Returns: BatchOperation

Example
{
  "failed_count": 1,
  "filter_snapshot": {
    "cohort_id": "6f1c0f2a-1b2c-4d5e-8f90-1a2b3c4d5e6f"
  },
  "id": "0a0f1f5c-4f4c-4a2e-8f2b-6c0a2c1f0d11",
  "kind": "apply_tags",
  "params": {
    "tags": [
      "audit-2026q3"
    ]
  },
  "parent_id": null,
  "progress": {
    "failed": 1,
    "queued": 0,
    "running": 0,
    "skipped": 1,
    "succeeded": 40
  },
  "reason": "Q3 physical audit",
  "selection_mode": "filter",
  "skipped_count": 1,
  "status": "completed_with_errors",
  "succeeded_count": 40,
  "targets": [
    {
      "attempts": 1,
      "error": null,
      "id": "d5a1c7f0-1e2d-4c3b-9a8f-7e6d5c4b3a21",
      "skip_reason": "robot_decommissioned",
      "status": "skipped",
      "target_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "target_type": "robot"
    }
  ],
  "total_count": 42,
  "workspace_id": "9a2f0d3e-2b7b-4a1f-9c2a-9a0b1c2d3e4f"
}
404

Batch not found

POST
/api/v1/operator/batch_operations/:id/cancel Web Session

Cancel a bulk operation

Description

Stops a queued or running batch. Cancellation is cooperative: targets already claimed by the running chunk finish, every target still queued becomes `skipped`, and the batch records who cancelled it. A batch that already finished returns 400.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Batch operation UUID
Responses
200

Batch cancelled

Returns: BatchOperation

Example
{
  "failed_count": 1,
  "filter_snapshot": {
    "cohort_id": "6f1c0f2a-1b2c-4d5e-8f90-1a2b3c4d5e6f"
  },
  "id": "0a0f1f5c-4f4c-4a2e-8f2b-6c0a2c1f0d11",
  "kind": "apply_tags",
  "params": {
    "tags": [
      "audit-2026q3"
    ]
  },
  "parent_id": null,
  "progress": {
    "failed": 1,
    "queued": 0,
    "running": 0,
    "skipped": 1,
    "succeeded": 40
  },
  "reason": "Q3 physical audit",
  "selection_mode": "filter",
  "skipped_count": 1,
  "status": "completed_with_errors",
  "succeeded_count": 40,
  "targets": [
    {
      "attempts": 1,
      "error": null,
      "id": "d5a1c7f0-1e2d-4c3b-9a8f-7e6d5c4b3a21",
      "skip_reason": "robot_decommissioned",
      "status": "skipped",
      "target_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "target_type": "robot"
    }
  ],
  "total_count": 42,
  "workspace_id": "9a2f0d3e-2b7b-4a1f-9c2a-9a0b1c2d3e4f"
}
400

The batch already finished

404

Batch not found

POST
/api/v1/operator/batch_operations/:id/retry_failed Web Session

Retry a bulk operation's failures

Description

Creates a child batch — same kind, same params, `parent_id` pointing at the original — carrying only the targets that failed. The original batch is left exactly as it was, so the record of the first attempt survives. Returns 400 when nothing failed.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Batch operation UUID
Responses
201

Child batch created

Returns: BatchOperation

Example
{
  "failed_count": 1,
  "filter_snapshot": {
    "cohort_id": "6f1c0f2a-1b2c-4d5e-8f90-1a2b3c4d5e6f"
  },
  "id": "0a0f1f5c-4f4c-4a2e-8f2b-6c0a2c1f0d11",
  "kind": "apply_tags",
  "params": {
    "tags": [
      "audit-2026q3"
    ]
  },
  "parent_id": null,
  "progress": {
    "failed": 1,
    "queued": 0,
    "running": 0,
    "skipped": 1,
    "succeeded": 40
  },
  "reason": "Q3 physical audit",
  "selection_mode": "filter",
  "skipped_count": 1,
  "status": "completed_with_errors",
  "succeeded_count": 40,
  "targets": [
    {
      "attempts": 1,
      "error": null,
      "id": "d5a1c7f0-1e2d-4c3b-9a8f-7e6d5c4b3a21",
      "skip_reason": "robot_decommissioned",
      "status": "skipped",
      "target_id": "d2c9a4df-c6ad-4016-9ba4-30c1c6d53a22",
      "target_type": "robot"
    }
  ],
  "total_count": 42,
  "workspace_id": "9a2f0d3e-2b7b-4a1f-9c2a-9a0b1c2d3e4f"
}
400

The batch has no failed targets

404

Batch not found

DELETE
/api/v1/operator/cohorts/:cohort_id/members/:membership_id Web Session

Remove cohort member

Description

Removes a membership row. The member entity itself is untouched.

Auth

Web Session
Parameters
Name In Type Required Description
cohort_id path string Yes Cohort UUID
membership_id path string Yes Membership UUID
Responses
204

Member removed

404

Membership not found