Skip to content

Reference Fleet

github-actions[bot] edited this page Oct 28, 2026 · 3 revisions

fleet API

Mowers, sites, groups, linked cloud accounts, base stations and commands.

Base path /api/v1/fleet behind the gateway. Authentication, rate limits and the error format are the same for every service: see Scripting MowDeck. Rendered from apps/web/openapi/fleet.json (OpenAPI 3.1), which you can also load into any OpenAPI tool.

Operations

base-stations

GET /api/v1/fleet/base-stations

List Base Stations

The RTK base stations of the caller's account with their linked mowers (can_view).

Status Meaning Body
200 Successful Response application/json BaseStationList
403 The caller lacks the relation on the account. no body
404 No such base station in the caller's account. no body

POST /api/v1/fleet/base-stations

Register Base Station

Register an RTK base station (can_manage_mowers): a device of a linked account that its device list marks rtk_base, or (source simulated) the simulator's base station. 409 base-station-already-registered when that physical base station is registered already (in this or another account, which is not named).

Request body (required): application/json BaseStationIn

Status Meaning Body
201 Successful Response application/json BaseStationOut
403 The caller lacks the relation on the account. no body
404 No such base station in the caller's account. no body
409 base-station-already-registered, or the account's limit. no body
422 Unknown linked account or device, or not an RTK base station. no body

GET /api/v1/fleet/base-stations/{base_station_id}

Get Base Station

One base station (can_view).

Parameter In Type Required Notes
base_station_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json BaseStationOut
403 The caller lacks the relation on the account. no body
404 No such base station in the caller's account. no body
422 Validation Error application/json HTTPValidationError

PATCH /api/v1/fleet/base-stations/{base_station_id}

Update Base Station

Rename the base station (can_manage_mowers).

Parameter In Type Required Notes
base_station_id path string (uuid) yes

Request body (required): application/json BaseStationPatch

Status Meaning Body
200 Successful Response application/json BaseStationOut
403 The caller lacks the relation on the account. no body
404 No such base station in the caller's account. no body
422 Validation Error application/json HTTPValidationError

DELETE /api/v1/fleet/base-stations/{base_station_id}

Delete Base Station

Remove the base station (can_manage_mowers); its mowers lose the link.

Parameter In Type Required Notes
base_station_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
403 The caller lacks the relation on the account. no body
404 No such base station in the caller's account. no body
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/base-stations/{base_station_id}/firmware/check

Check Base Station Firmware

Ask the vendor for the base station's firmware through a linked mower (can_view); the answer also lands in the linked mowers' state (MowerState.base_station).

Parameter In Type Required Notes
base_station_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json FirmwareInfo
403 The caller lacks the relation on the account. no body
404 No such base station in the caller's account. no body
409 base-station-not-linked: no mower is linked to it. no body
422 Validation Error application/json HTTPValidationError
503 No Device-Gateway holding a linked mower answered. no body

POST /api/v1/fleet/base-stations/{base_station_id}/firmware/update

Update Base Station Firmware

Install the offered firmware (can_manage_mowers and the plan feature control): the command base_station_firmware_update goes to a linked mower, which relays it to the vendor; follow it at status_url. The mower refuses it while it mows, returns, updates or drives, or when the version is not the offered one.

Parameter In Type Required Notes
base_station_id path string (uuid) yes

Request body (required): application/json BaseStationFirmwareUpdateIn

Status Meaning Body
202 Successful Response application/json CommandAccepted
403 The caller lacks the relation on the account. no body
404 No such base station in the caller's account. no body
409 base-station-not-linked: no mower is linked to it. no body
422 mower_id is not linked to the base station. no body

PUT /api/v1/fleet/mowers/{mower_id}/base-station

Set Mower Base Station

Link the mower to an RTK base station of the account, or unlink it with null (can_manage_mowers on the mower). A cloud base station serves cloud mowers of its own linked account, the simulated one simulated mowers. Publishes mower.updated: the Device-Gateway reconnects the mower with the base station.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json MowerBaseStationIn

Status Meaning Body
200 Successful Response application/json MowerOut
403 The caller sees the mower but has no can_manage_mowers. no body
404 The mower or the base station does not exist in the account. no body
409 base-station-not-applicable: it cannot serve this mower. no body
422 Validation Error application/json HTTPValidationError

linked-accounts

GET /api/v1/fleet/linked-accounts

List Linked Accounts

The linked Mammotion accounts of the caller's account (no passwords).

Status Meaning Body
200 Successful Response application/json LinkedAccountList
403 The caller lacks can_manage_mowers on the account. no body
404 No such linked account in the caller's account. no body

POST /api/v1/fleet/linked-accounts

Create Linked Account

Link a Mammotion account: Fleet asks the Device-Gateway to log in and list the devices (gateway.cloud.discover) and stores the account with its password encrypted. Use a second Mammotion account the mowers are shared with: a login with the main account logs the phone app out.

Request body (required): application/json LinkedAccountIn

Status Meaning Body
201 Successful Response application/json LinkedAccountDetail
403 The caller lacks can_manage_mowers on the account. no body
404 No such linked account in the caller's account. no body
409 Linked. no body
422 linked-account-login-failed: the cloud refused the credentials. no body
429 Too many failed logins for this e-mail (Retry-After). no body
503 No credential encryption key, or no Device-Gateway or vendor cloud answered. no body

GET /api/v1/fleet/linked-accounts/{linked_account_id}

Get Linked Account

One linked account.

Parameter In Type Required Notes
linked_account_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json LinkedAccountOut
403 The caller lacks can_manage_mowers on the account. no body
404 No such linked account in the caller's account. no body
422 Validation Error application/json HTTPValidationError

DELETE /api/v1/fleet/linked-accounts/{linked_account_id}

Delete Linked Account

Remove the link. Refused (409, the mowers in errors) while mowers use it. Step-up (ADR 0057): 401 reauth-required without a recent confirmation, 403 for API tokens.

Parameter In Type Required Notes
linked_account_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
403 The caller lacks can_manage_mowers on the account. no body
404 No such linked account in the caller's account. no body
409 linked-account-in-use: mowers still connect through it. no body
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/linked-accounts/{linked_account_id}/devices

List Linked Devices

The devices of the last device list: name, model, IoT id, online flag, whether it is a mower and whether it is registered here or in another MowDeck account.

Parameter In Type Required Notes
linked_account_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json LinkedDeviceList
403 The caller lacks can_manage_mowers on the account. no body
404 No such linked account in the caller's account. no body
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/linked-accounts/{linked_account_id}/mowers

Register Linked Mowers

Register several mowers of the linked account at once. Each one is an ordinary registration (target site and groups checked, tuples, mower.registered); devices that fail are listed in failed with the problem they would have answered. When none could be added the first problem is the answer.

Parameter In Type Required Notes
linked_account_id path string (uuid) yes

Request body (required): application/json LinkedMowersIn

Status Meaning Body
201 Successful Response application/json LinkedMowersOut
403 The caller lacks can_manage_mowers on the account. no body
404 No such linked account in the caller's account. no body
409 mower-already-registered (when no device could be added). no body
422 Unknown device, not a mower, or a device given twice. no body

POST /api/v1/fleet/linked-accounts/{linked_account_id}/sync

Sync Linked Account

Read the device list again ("Konto neu einlesen"), optionally with a new password. The gateway answers from the session the account's connected mowers share when there is one (a second login would log them out). A failure is kept in last_sync_error.

Parameter In Type Required Notes
linked_account_id path string (uuid) yes

Request body (required): application/json LinkedAccountSyncIn

Status Meaning Body
200 Successful Response application/json LinkedAccountDetail
403 The caller lacks can_manage_mowers on the account. no body
404 No such linked account in the caller's account. no body
422 linked-account-login-failed: the cloud refused the credentials. no body
429 Too many failed logins for this e-mail (Retry-After). no body
503 No credential encryption key, or no Device-Gateway or vendor cloud answered. no body

mowers

GET /api/v1/fleet/commands/{command_id}

Get Command

One command record of the caller's account whose mower the caller may view (404 otherwise).

Parameter In Type Required Notes
command_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json CommandView
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/connection-kinds

List Connection Kinds

The connection kinds this installation accepts (MOWDECK_ALLOWED_CONNECTION_KINDS) with the option schema of each: required, optional, secret and alternative options. The web app generates its connection forms from it, so a new adapter kind needs no UI change.

Status Meaning Body
200 Successful Response application/json ConnectionKindList

GET /api/v1/fleet/mowers

List Mowers

Mowers of the caller's account that the caller may view (can_view per mower).

Parameter In Type Required Notes
site_id query string (uuid) or null no
group_id query string (uuid) or null no
Status Meaning Body
200 Successful Response application/json MowerList
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/mowers

Register Mower

Register a mower: can_manage_mowers on the target site (the account for the default site) and on each group. Publishes mower.registered after the commit. A cloud mower names a linked account and its device; 409 mower-already-registered when that physical mower is registered already (in this or another account, which is not named).

Request body (required): application/json MowerIn

Status Meaning Body
201 Successful Response application/json MowerOut
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/mowers/{mower_id}

Get Mower

One mower (can_view, hidden otherwise).

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json MowerOut
422 Validation Error application/json HTTPValidationError

PATCH /api/v1/fleet/mowers/{mower_id}

Update Mower

Change name, model, serial, connection or site (can_manage_mowers; a new site needs it too). Publishes mower.updated when name, connection or site changed.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json MowerPatch

Status Meaning Body
200 Successful Response application/json MowerOut
422 Validation Error application/json HTTPValidationError

DELETE /api/v1/fleet/mowers/{mower_id}

Delete Mower

Remove the mower and its tuples; publishes mower.removed. Step-up: 401 reauth-required without a recent passkey or password confirmation, 403 for API tokens (ADR 0057).

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/mowers/{mower_id}/area-names

Get Area Names

The custom names of the mower's map areas (can_view, hidden otherwise). The same names come with the mower (MowerOut.area_names).

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json AreaNamesOut
422 Validation Error application/json HTTPValidationError

PUT /api/v1/fleet/mowers/{mower_id}/area-names/{area_id}

Set Area Name

Name one map area in MowDeck (can_control; 403 when the mower is visible, else 404). null or a blank name drops the custom name. The mower keeps its own names: nothing is sent to the mower. Publishes fleet.mower.area_names_changed after a change; answers all custom names of the mower.

Parameter In Type Required Notes
mower_id path string (uuid) yes
area_id path string yes MowerMap.areas[].id; min length 1; max length 128

Request body (required): application/json AreaNameIn

Status Meaning Body
200 Successful Response application/json AreaNamesOut
403 The caller sees the mower but has no can_control. no body
404 The mower does not exist or is not visible to the caller. no body
422 The name has more than 60 characters after trimming. no body

POST /api/v1/fleet/mowers/{mower_id}/camera/session

Open Camera Session

A short-lived live camera session: can_view on the mower (hidden otherwise) and the plan feature camera; audited as mower.camera_opened with the transport used.

transport (ADR 0045, default auto): relay opens a lease on MowDeck's camera relay and answers its session (provider relay: WHEP URLs per camera, a ticket, lease_id; renew it every heartbeat_seconds, delete it when the page goes away). direct asks the Device-Gateway for the vendor session (ADR 0032; provider agora: the browser joins with the Agora Web SDK, fake: a test pattern). auto uses the relay and falls back to direct only when the relay cannot serve the mower's camera provider or is not deployed. The token or ticket is a secret: the response is never cached; ask again before expires_at.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body: application/json CameraSessionIn or null

Status Meaning Body
200 Successful Response application/json CameraSession
403 The plan does not include the feature camera. no body
404 The mower does not exist or is not visible to the caller. no body
409 camera-unsupported: the mower's connection has no camera; camera-relay-unsupported: transport relay, but the relay has no source for the mower's camera provider; camera-budget: a camera limit refused the stream. no body
422 Validation Error application/json HTTPValidationError
503 The Device-Gateway, the vendor cloud or (transport relay) the camera relay did not answer, or the mower is offline. no body

DELETE /api/v1/fleet/mowers/{mower_id}/camera/session/{lease_id}

Close Camera Session

End a relay camera lease (ADR 0045): the page was left or hidden. Idempotent: an unknown or already closed lease, or no relay at all, is 204 as well. can_view on the mower; only the user who opened the lease ends it (another user's lease is 404 and keeps running); no plan check (ending a stream is always allowed).

Parameter In Type Required Notes
mower_id path string (uuid) yes
lease_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
404 The mower is not visible, or the lease is another account's or was opened by another user. no body
422 Validation Error application/json HTTPValidationError
503 The camera relay did not answer in time. no body

POST /api/v1/fleet/mowers/{mower_id}/camera/session/{lease_id}/renew

Renew Camera Session

The heartbeat of a relay camera lease (ADR 0045): extends it and answers the same session with a fresh ticket (for reconnects). can_view on the mower and the plan feature camera; only the user who opened the lease renews it; never cached.

Parameter In Type Required Notes
mower_id path string (uuid) yes
lease_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json CameraSession
403 The plan does not include the feature camera. no body
404 The mower is not visible, or the lease is unknown, expired, detached, of another account or opened by another user. no body
422 Validation Error application/json HTTPValidationError
503 The camera relay is not deployed or did not answer. no body

GET /api/v1/fleet/mowers/{mower_id}/camera/snapshot

Camera Snapshot

A still image of the mower's camera for API clients (can_view on the mower, hidden otherwise, and the plan feature camera): taken by the Device-Gateway with the mower's own photo function or through the camera relay, keeping every camera limit (a sleeping mower is not woken). At most one new image per mower every MOWDECK_CAMERA_SNAPSHOT_MIN_INTERVAL_SECONDS (30 s); requests in between get the last one. A new image is audited as mower.camera_snapshot; Fleet never stores it.

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
200 The image, with X-Snapshot-Taken-At (ISO 8601). image/jpeg any, image/png any
403 The plan does not include the feature camera. no body
404 The mower does not exist or is not visible to the caller. no body
409 camera-unsupported: the mower's connection cannot take a photo. no body
422 Validation Error application/json HTTPValidationError
503 No Device-Gateway holds the mower or none answered in time, the mower is offline or asleep, or a camera limit (battery, budget) refused the image. no body

GET /api/v1/fleet/mowers/{mower_id}/commands

List Mower Commands

Command records of the mower (can_view, hidden otherwise).

Parameter In Type Required Notes
mower_id path string (uuid) yes
before query string (date-time) or null no
limit query integer no min 1; max 200; default 50
Status Meaning Body
200 Successful Response application/json CommandPageOut
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/mowers/{mower_id}/commands

Send Command

Send a command. The relation depends on the kind: can_control (start, pause, resume, dock, blade height, speed), can_drive (manual drive, spot mow, drive calibration, drive speed setting), can_emergency_stop (emergency stop, equals can_view). Checked before any database or bus access: 403 when the mower is visible, 404 when not.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json CommandRequest

Status Meaning Body
202 Successful Response application/json CommandAccepted
422 Validation Error application/json HTTPValidationError

PUT /api/v1/fleet/mowers/{mower_id}/drive-calibration

Set Drive Calibration

Store the result of a drive calibration (can_drive, 403 when the mower is visible, else 404): the values a finished drive_calibrate reported in MowerState.drive_calibration.result.calibration. Fleet keeps them as managed options of the mower's ble_bridge link (the link's key stays as it is), or in the connection options of a connection kind that takes them (the simulator), and replaces a stored calibration. Audits mower.drive_calibration_set and publishes mower.updated, so the Device-Gateway hands the calibration to every spot run. Answers the stored calibration; the mower shows it as MowerOut.drive_calibration.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json DriveCalibration

Status Meaning Body
200 Successful Response application/json DriveCalibration
403 The caller sees the mower but has no can_drive. no body
404 The mower does not exist or is not visible to the caller. no body
409 drive-calibration-not-applicable: the mower has no ble_bridge link and its connection options take no calibration. no body
422 A value out of range. no body

DELETE /api/v1/fleet/mowers/{mower_id}/drive-calibration

Delete Drive Calibration

Forget the stored drive calibration (can_drive, 403 when the mower is visible, else 404); spot runs then go without one. Without a stored calibration nothing changes. Audits mower.drive_calibration_removed and publishes mower.updated.

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
403 The caller sees the mower but has no can_drive. no body
404 The mower does not exist or is not visible to the caller. no body
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/mowers/{mower_id}/drive-sessions

List Drive Sessions

Manual drive sessions of the mower (the joystick audit: who, when, how it ended, frame counts; can_view, hidden otherwise). Frames themselves are not stored.

Parameter In Type Required Notes
mower_id path string (uuid) yes
before query string (date-time) or null no
limit query integer no min 1; max 200; default 50
Status Meaning Body
200 Successful Response application/json DriveSessionPageOut
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/mowers/{mower_id}/firmware/check

Check Firmware

Ask the vendor for firmware updates now (can_view, hidden otherwise; ADR 0038). Fleet relays the request to the Device-Gateway that holds the mower, which asks through the mower's connection and answers the fresh FirmwareInfo (installed and available version, release notes, update state); the same information arrives with telemetry as MowerState.firmware_info. Installing is the command firmware_update (can_manage_mowers).

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json FirmwareInfo
404 The mower does not exist or is not visible to the caller. no body
409 firmware-check-unsupported: the mower's connection cannot ask the vendor (no cloud link). no body
422 Validation Error application/json HTTPValidationError
503 The mower is offline, the vendor did not answer, or no Device-Gateway answered in time. no body

PUT /api/v1/fleet/mowers/{mower_id}/groups

Set Mower Groups

Make the mower a member of exactly these groups (can_manage_mowers on the mower and on every added or removed group).

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json MowerGroupsIn

Status Meaning Body
200 Successful Response application/json MowerOut
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/mowers/{mower_id}/links/ble_bridge

Get Bridge Link

The mower's Bluetooth bridge link (can_view, hidden otherwise): its options with the key masked and the cached bridge information of the last scan. The live link state comes with telemetry (MowerState.links.ble_bridge).

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json LinkOut
404 The mower is not visible or has no bridge link. no body
422 Validation Error application/json HTTPValidationError

PUT /api/v1/fleet/mowers/{mower_id}/links/ble_bridge

Set Bridge Link

Create or replace the mower's Bluetooth bridge link (can_manage_mowers, hidden otherwise): the bridge's host, port and API encryption key, the mower's Bluetooth address and name (from the scan) and the blade settings for manual driving. The options are validated with the ble_bridge schema of GET /connection-kinds; the key is stored encrypted and never returned (***; sending *** keeps it). Audits mower.link_set and publishes mower.updated with the full registration, so the Device-Gateway opens the link.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json BridgeLinkIn

Status Meaning Body
200 Successful Response application/json LinkOut
403 The caller sees the mower but has no can_manage_mowers. no body
404 The mower does not exist or is not visible to the caller. no body
409 link-not-applicable: the mower's connection kind carries no Bluetooth bridge link (decided by the connection-kind registry, GET /connection-kinds). no body
422 An option the ble_bridge schema refuses (#/links/ble_bridge/<key>). no body
503 Fleet has no credential encryption key. no body

DELETE /api/v1/fleet/mowers/{mower_id}/links/ble_bridge

Delete Bridge Link

Remove the mower's Bluetooth bridge link (can_manage_mowers, hidden otherwise). Audits mower.link_removed and publishes mower.updated without the link, so the Device-Gateway closes it.

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
403 The caller sees the mower but has no can_manage_mowers. no body
404 The mower is not visible or has no bridge link. no body
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/mowers/{mower_id}/links/ble_bridge/check

Check Bridge Link

Scan again through the stored link ("re-check", can_manage_mowers, hidden otherwise): the stored host, port and key; the reply is as for the scan and the link's proxy_info (bridge firmware, outdated flag) is refreshed. While the Device-Gateway holds the link open it answers from the live scanner.

Parameter In Type Required Notes
mower_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json BridgeScanReply
403 The caller sees the mower but has no can_manage_mowers. no body
404 The mower is not visible or has no bridge link. no body
409 link-not-applicable: the connection kind carries no bridge link; bridge-scan-unsupported: the Device-Gateway cannot scan through this bridge. no body
422 Validation Error application/json HTTPValidationError
503 No Device-Gateway answered in time or holds the mower right now. no body

POST /api/v1/fleet/mowers/{mower_id}/links/ble_bridge/scan

Scan Bridge

Look for the mower through a Bluetooth bridge before storing the link (can_manage_mowers, hidden otherwise). Fleet relays the request to the Device-Gateway that holds the mower; the gateway connects to the bridge at host:port with the key, reads the bridge's information and collects mower advertisements for up to 30 s (early when the expected name shows up). The answer is the gateway's BridgeScanReply: proxy as soon as the bridge answered, devices seen so far, and error for the outcomes the user must act on (unreachable, auth_failed, timeout, busy) — these are a 200 with the reply, so a timeout still shows the bridge and the other mowers seen. When the mower already has a link to the same bridge its proxy_info is refreshed. *** as key means the stored key. The key is never returned or logged.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json BridgeScanIn

Status Meaning Body
200 Successful Response application/json BridgeScanReply
403 The caller sees the mower but has no can_manage_mowers. no body
404 The mower does not exist or is not visible to the caller. no body
409 link-not-applicable: the connection kind carries no bridge link; bridge-scan-unsupported: the Device-Gateway cannot scan through this bridge. no body
422 *** as key without a stored link (#/links/ble_bridge/noise_psk). no body
503 No Device-Gateway answered in time or holds the mower right now. no body

PUT /api/v1/fleet/mowers/{mower_id}/mow-defaults

Set Mow Defaults

Keep the mowing defaults of the mower (can_control; 403 when the mower is visible, else 404): the pattern settings every client starts with (web start sheet, Home Assistant, schedules). pattern: null drops them. Nothing is sent to the mower; a start still names its own pattern in StartMow.pattern. Whether the mower runs the pattern is its capabilities' business (native_patterns). Answers the mower with mow_defaults.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json MowDefaultsIn

Status Meaning Body
200 Successful Response application/json MowerOut
403 The caller sees the mower but has no can_control. no body
404 The mower does not exist or is not visible to the caller. no body
422 Unknown pattern, a value out of range or an unknown key. no body

POST /api/v1/fleet/mowers/{mower_id}/path-preview

Preview Mow Path

Let the mower plan the route of a start (areas and pattern as for start_mow) without starting it, as the vendor app does before a start: can_control on the mower (hidden otherwise) and the plan feature control. Fleet relays the request to the Device-Gateway that holds the mower; planning and fetching the route take a few seconds to about a minute (over 4G longer), so clients show progress and allow up to 90 s. The route is not stored; the start uses the same areas and pattern and the mower plans the same route again.

Parameter In Type Required Notes
mower_id path string (uuid) yes

Request body (required): application/json PathPreviewRequest

Status Meaning Body
200 Successful Response application/json MowPath
403 The plan does not include the feature control. no body
404 The mower does not exist or is not visible to the caller. no body
409 path-preview-unsupported: the connection cannot plan without starting; path-preview-rejected: a job runs, or the areas or pattern do not fit. no body
422 Validation Error application/json HTTPValidationError
503 The Device-Gateway did not answer or the mower is offline. no body
504 gateway-timeout: the mower did not hand back its route in time. no body

sites and groups

GET /api/v1/fleet/groups

List Groups

Groups of the caller's account that the caller may view, optionally of one site.

Parameter In Type Required Notes
site_id query string (uuid) or null no
Status Meaning Body
200 Successful Response application/json GroupList
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/groups

Create Group

A new group (can_manage_mowers on the parent site, or the account if cross-site).

Request body (required): application/json GroupIn

Status Meaning Body
201 Successful Response application/json GroupOut
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/groups/{group_id}

Get Group

One group with the mowers the caller may view (can_view, hidden otherwise).

Parameter In Type Required Notes
group_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json GroupOut
422 Validation Error application/json HTTPValidationError

PATCH /api/v1/fleet/groups/{group_id}

Update Group

Rename or move to another site (can_manage_mowers on the group and the new site).

Parameter In Type Required Notes
group_id path string (uuid) yes

Request body (required): application/json GroupPatch

Status Meaning Body
200 Successful Response application/json GroupOut
422 Validation Error application/json HTTPValidationError

DELETE /api/v1/fleet/groups/{group_id}

Delete Group

Delete an empty group (409 while it has mowers).

Parameter In Type Required Notes
group_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/groups/{group_id}/commands

Bulk Group Command

The command for every mower of the group, checked per mower (see the site variant).

Parameter In Type Required Notes
group_id path string (uuid) yes

Request body (required): application/json CommandRequest

Status Meaning Body
202 Successful Response application/json BulkCommandAccepted
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/sites

List Sites

Sites of the caller's account that the caller may view (can_view per site).

Parameter In Type Required Notes
include_default query boolean no default false
Status Meaning Body
200 Successful Response application/json SiteList
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/sites

Create Site

A new site (can_manage_mowers on the account, else 403).

Request body (required): application/json SiteIn

Status Meaning Body
201 Successful Response application/json SiteOut
422 Validation Error application/json HTTPValidationError

GET /api/v1/fleet/sites/{site_id}

Get Site

One site (can_view, hidden otherwise).

Parameter In Type Required Notes
site_id path string (uuid) yes
Status Meaning Body
200 Successful Response application/json SiteOut
422 Validation Error application/json HTTPValidationError

PATCH /api/v1/fleet/sites/{site_id}

Update Site

Change name, timezone, address or coordinates (can_manage_mowers; the default site keeps its name).

Parameter In Type Required Notes
site_id path string (uuid) yes

Request body (required): application/json SitePatch

Status Meaning Body
200 Successful Response application/json SiteOut
422 Validation Error application/json HTTPValidationError

DELETE /api/v1/fleet/sites/{site_id}

Delete Site

Delete an empty site (409 for the default site or while mowers or groups use it).

Parameter In Type Required Notes
site_id path string (uuid) yes
Status Meaning Body
204 Successful Response no body
422 Validation Error application/json HTTPValidationError

POST /api/v1/fleet/sites/{site_id}/commands

Bulk Site Command

The command for every mower of the site, checked per mower.

Gate: can_bulk_command on the site (can_emergency_stop, i.e. view, for an emergency stop). Per mower: the relation of the command kind; invisible mowers are omitted.

Parameter In Type Required Notes
site_id path string (uuid) yes

Request body (required): application/json CommandRequest

Status Meaning Body
202 Successful Response application/json BulkCommandAccepted
422 Validation Error application/json HTTPValidationError

Schemas

Address

Postal address of a site (all optional).

Field Type Required Notes
city string or null no
country string or null no ISO 3166-1 alpha-2
postal_code string or null no
street string or null no

AreaNameIn

PUT /mowers/{id}/area-names/{area_id}: the custom name; null or blank drops it. Surrounding blanks are trimmed; at most 60 characters remain (422 otherwise).

Field Type Required Notes
name string or null yes

AreaNamesOut

The custom area names of a mower, by area id (areas without one are absent).

Field Type Required Notes
names map of string yes

BaseStationFirmwareUpdate

Install the firmware the vendor offers for the mower's RTK base station (MowerState.base_station.firmware_info.available, ADR 0047).

Sent to a mower linked to the base station: its connection asks the vendor's firmware service with the base station's id. Refused unless the base station's update_state is available and version equals available, no update of the base station is already installing, and the mower runs no job, spot run or drive session (it loses its RTK corrections while the base station restarts).

Field Type Required Notes
kind "base_station_firmware_update" no default "base_station_firmware_update"
version string yes The version to install, as offered.; min length 1; max length 64

BaseStationFirmwareUpdateIn

POST /base-stations/{id}/firmware/update.

Field Type Required Notes
mower_id string (uuid) or null no The linked mower that relays the request; default the first by name.
version string yes The offered version (firmware_info.available).; min length 1; max length 64

BaseStationIn

POST /base-stations: a device of a linked account (source cloud) or the simulator's base station (simulated).

Field Type Required Notes
device_name string or null no cloud: the device (device_type rtk_base in the device list).
linked_account_id string (uuid) or null no cloud: the linked account whose device list names it.
name string or null no Defaults to the device name (Simulated base station).
source "cloud" | "simulated" no default "cloud"

BaseStationList

GET /base-stations.

Field Type Required Notes
items array of BaseStationOut yes

BaseStationOut

An RTK base station. Its live state comes with the linked mowers' telemetry (MowerState.base_station).

Field Type Required Notes
created_at string (date-time) yes
device_name string or null yes
id string (uuid) yes
iot_id string or null yes The vendor's device id (unique across accounts).
linked_account_id string (uuid) or null yes
model string or null yes
mower_ids array of string (uuid) yes The mowers linked to it, by name.
name string yes
source "cloud" | "simulated" yes
updated_at string (date-time) yes

BaseStationPatch

PATCH /base-stations/{id}.

Field Type Required Notes
name string yes min length 1; max length 100

BridgeLinkIn

PUT /mowers/{id}/links/ble_bridge: a Bluetooth bridge (an ESPHome Bluetooth proxy) next to the mower's connection. noise_psk is write-only; *** keeps the stored key.

Field Type Required Notes
allow_manual_blades boolean no Blades may run while the mower is driven manually.; default false
ble_address string yes The mower's Bluetooth address (from the scan).; min length 1; max length 32
device_name string or null no The mower's Bluetooth name (from the scan); the cloud device name when omitted.
host string yes Host name or IP of the bridge.; min length 1; max length 253
manual_blade_height_mm integer or null no Blade height for manual driving.
manual_drive_speed_mps number or null no max_run_speed the mower gets when a drive session opens (ADR 0042); omitted: the mower's own speed setting for manual driving, at most 1.0 m/s.
noise_psk string yes The bridge's API encryption key (api.encryption.key of an ESPHome bridge); *** keeps the stored key.; min length 1; max length 256
port integer no The bridge's API port.; min 1.0; max 65535.0; default 6053

BridgeScanError

The error of a :class:BridgeScanReply; detail never echoes the key.

Field Type Required Notes
code BridgeScanErrorCode yes
detail string yes max length 500
held_by string or null no For already_connected: the name of the mower entry whose connection holds the mower through this bridge.

BridgeScanErrorCode

Why a bridge scan gave no result.

Type: "unreachable" | "auth_failed" | "timeout" | "busy" | "unsupported" | "not_found" | "forbidden" | "already_connected"

BridgeScanIn

POST /mowers/{id}/links/ble_bridge/scan: where the bridge is and its key (***: the stored key of the existing link).

Field Type Required Notes
host string yes min length 1; max length 253
noise_psk string no The bridge's API encryption key; *** means the stored key.; min length 1; max length 256; default "***"
port integer no min 1.0; max 65535.0; default 6053

BridgeScanReply

Reply to :class:BridgeScanRequest.

proxy is set as soon as the proxy answered, also with a timeout error (the bridge works, the mower was not seen); devices lists every mower advertisement seen, so the client can offer a different mower than expected. error is null when the scan succeeded.

Field Type Required Notes
devices array of ScannedDevice no max items 50
error BridgeScanError or null no
proxy ProxyInfo or null no

BulkCommandAccepted

Answer (202) to a command for every mower of a site or group.

Field Type Required Notes
bulk_id string (uuid) yes
items array of BulkCommandItem no
kind string yes min length 1; max length 64
target_id string (uuid) yes
target_type "site" | "group" yes

BulkCommandItem

One mower of a bulk command. Mowers the caller cannot see are omitted.

Field Type Required Notes
command_id string (uuid) or null no
expires_at string (date-time) or null no
mower_id string (uuid) yes
outcome BulkCommandOutcome yes

BulkCommandOutcome

What happened to one mower of a bulk command.

Type: "accepted" | "forbidden" | "not_published"

CameraEncryption

Channel encryption the client must configure before joining (Agora setEncryptionConfig).

Field Type Required Notes
key string yes The secret, used verbatim.; min length 1; max length 256
mode string yes Agora encryption mode, for Mammotion aes-256-gcm2.; max length 32
salt string or null no Base64 salt (32 bytes decoded) for the gcm2 modes; null when not sent.

CameraInfo

One camera of the mower.

Field Type Required Notes
id string yes Camera id as the vendor names it.; min length 1; max length 64
name string yes A short display name, e.g. Front left.; max length 100
placement CameraPlacement or null no Where the camera sits, if known. A front_left and a front_right camera form a stereo pair the client may show side by side.
uid integer or null no Agora uid the mower publishes this camera under, if known. Clients fall back to the first remote user that publishes video.

CameraPlacement

Where a camera sits on the mower. Clients pair front_left and front_right for the side-by-side view and stereo frames (both front cameras of a LUBA 2 AWD X).

Type: "front_left" | "front_right" | "front" | "rear"

CameraProvider

Who delivers the video.

Type: "agora" | "fake" | "relay"

CameraQuota

The vendor's video budget (Mammotion meters video over 4G only).

Field Type Required Notes
total_minutes number yes min 0.0
used_minutes number yes min 0.0

CameraSession

Credentials for one viewer to join the live video of one mower.

Provider relay needs the relay endpoint and carries no vendor secrets (token and app_id empty, no encryption); expires_at is then the ticket's expiry. Every other provider has no relay endpoint.

Field Type Required Notes
app_id string yes Agora app id (empty for fake).; max length 128
cameras array of CameraInfo no max items 8
channel string yes Agora channel name (64 bytes at most).; max length 64
encryption CameraEncryption or null no Set when the channel is encrypted.
expires_at string (date-time) yes When the token stops working; clients request a new session before.
provider CameraProvider yes
quota CameraQuota or null no The video budget, when the vendor reports one.
relay RelayEndpoint or null no Set exactly when provider is relay (ADR 0045).
token string yes Short-lived Agora token. Never log it.; max length 2048
uid integer yes The viewer's Agora uid (bound to the token).; min 0.0; max 4294967295.0

CameraSessionIn

POST /mowers/{id}/camera/session (optional body): how the client wants the video.

Field Type Required Notes
transport CameraTransport no auto (default): the camera relay, the direct vendor path only when the relay cannot serve the mower's camera provider or is not deployed; relay: only the relay, its errors are answered; direct: the vendor session (ADR 0032).; default "auto"

CameraTransport

How a client wants to reach the camera (ADR 0045). Chosen per browser; Fleet decides.

Type: "auto" | "relay" | "direct"

CommandAccepted

Answer (202) to a command for one mower: Fleet published it; results follow.

Field Type Required Notes
command_id string (uuid) yes
correlation_id string yes pattern ^[A-Za-z0-9._:\-]{1,128}$
expires_at string (date-time) yes
issued_at string (date-time) yes
kind string yes min length 1; max length 64
mower_id string (uuid) yes
priority CommandPriority yes
status "accepted" no default "accepted"
status_url string yes Where to read the command record, e.g. /api/v1/fleet/commands/<id>.

CommandPageOut

GET /mowers/{id}/commands: newest first; pass next_before as before.

Field Type Required Notes
items array of CommandView yes
next_before string (date-time) or null yes

CommandPriority

Delivery priority of a command. Only :class:EmergencyStop uses emergency.

Type: "normal" | "emergency"

CommandRequest

Body of POST .../commands for a mower, a group or a site.

ttl_seconds shortens or extends the expiry within the service's limit; Fleet ignores it for manual_drive and emergency_stop, which always use their own short expiry.

Field Type Required Notes
command StartMow or PauseMow or ResumeMow or ReturnToDock or EmergencyStop or SetBladeHeight or SetSpeed or SetLight or FirmwareUpdate or BaseStationFirmwareUpdate or SpotMow or SpotStop or DriveCalibrate or SetDriveSpeed or SetSetting or RestartMower or SyncMap or RelocateDock or LeaveDock or ResyncRtk or ManualDrive yes
ttl_seconds integer or null no

CommandState

Status of a command record in Fleet.

Type: "pending" | "accepted" | "rejected" | "executed" | "expired" | "failed"

CommandView

A command record as clients read it (GET /commands/{id}).

Field Type Required Notes
bulk_id string (uuid) or null no
command_id string (uuid) yes
correlation_id string yes pattern ^[A-Za-z0-9._:\-]{1,128}$
end_job boolean or null no For a return_to_dock: whether it also ended the job; None for other kinds.
expires_at string (date-time) yes
issued_at string (date-time) yes
issued_by PrincipalRef yes
kind string yes min length 1; max length 64
mower_id string (uuid) yes
origin string or null no Service that issued the command on behalf of issued_by (e.g. scheduler); None for commands sent through the API.
pattern object or null no For a start_mow on map areas: the pattern settings it was sent with (StartMow.pattern, mostly MowPattern keys); None otherwise or when it had none.
plan_hash string or null no Hash of the spot plan of a start_mow with spot_plan, if any.
priority CommandPriority yes
reason string or null no
result_at string (date-time) or null no Time of the latest result applied to the record.
schedule_id string (uuid) or null no The schedule that issued the command, if any.
status CommandState yes

ConnectionGroupOut

A set of alternative options (e.g. password or credential reference).

Field Type Required Notes
key string yes
title string yes

ConnectionKind

How the Device-Gateway is connected to the mower.

Type: "ble_bridge" | "wifi" | "cloud" | "simulated"

ConnectionKindList

GET /connection-kinds: the kinds accepted here, in the order the app offers them.

Field Type Required Notes
items array of ConnectionKindOut yes

ConnectionKindOut

A connection kind this installation accepts, with its option schema.

Field Type Required Notes
description string yes
extra_options boolean yes Keys outside options are accepted and kept (adapter specific).
groups array of ConnectionGroupOut yes
kind string yes
linked_account boolean no Mowers of this kind come from a linked vendor account (/linked-accounts): register them with linked_account_id and device_name.; default false
options array of ConnectionOptionOut yes
title string yes

ConnectionOptionOut

One option of a connection kind (the web app builds its form from these).

Field Type Required Notes
advanced boolean yes
default string or integer or number or boolean or null yes
description string yes
examples array of string yes
format_hint string or null yes
group string or null yes Options with the same group are alternatives: one of them is required.
key string yes
managed boolean no Set by Fleet (from the linked account's device list, or a stored drive calibration): shown, not editable.; default false
maximum number or null yes
minimum number or null yes
pattern string or null yes Regular expression a string value must match.
required boolean yes
secret boolean yes Write-only: answered as ***; sending *** back keeps the stored value.
title string yes English label; the app translates the options it knows.
type "string" | "integer" | "number" | "boolean" yes

DeviceType

What a discovered device is (ADR 0047).

Type: "mower" | "rtk_base" | "other"

DriveCalibrate

Measure what the stick values mean on the ground (ADR 0042).

MowDeck drives a few short steps with the blades off (forward at linear 0.3, 0.5, 0.7 and 1.0, then turns in place at angular ±0.3, ±0.6 and ±1.0, each step_s long, zero frames in between). Each step is measured over its steady window only (without the first 1.5 s, while the mower reacts), and MowDeck fits the full-scale ground speed, the full-scale yaw rate and the dead zone. Needs MowerCapabilities.manual_drive, an idle mower out of its dock with a fixed RTK position and about 2 m of free lawn straight ahead. Progress and the result arrive in MowerState.drive_calibration; SpotStop and EmergencyStop end it.

Field Type Required Notes
kind "drive_calibrate" no default "drive_calibrate"
step_s number no Duration of each step in seconds.; min 5.0; max 12.0; default 6.0

DriveCalibration

The fitted drive behaviour of one mower, as stored in the drive link's options.

Field Type Required Notes
calibrated_at string (date-time) yes
dead_zone number no linear below which the mower stands.; min 0.0; max 0.9; default 0.0
drive_speed_setting number or null no The vendor's manual-driving speed setting during the calibration (MowerState.drive_speed_mps); null when the connection has none.
full_speed_mps number yes Ground speed at linear = 1.; max 5.0; greater than 0.0
full_yaw_rate_dps number yes Yaw rate at angular = ±1 in degrees per second.; max 720.0; greater than 0.0
turn_dead_zone number no angular below which the mower does not turn.; min 0.0; max 0.9; default 0.0

DriveEndReason

Why a drive session ended.

Type: "client_stop" | "socket_closed" | "revoked" | "token_expired" | "max_duration" | "mower_refused" | "mower_busy" | "replaced" | "expired" | "completed" | "aborted"

DriveSessionPageOut

GET /mowers/{id}/drive-sessions: newest first; pass next_before as before.

Field Type Required Notes
items array of DriveSessionView yes
next_before string (date-time) or null yes

DriveSessionView

A drive session as the audit API shows it (GET /mowers/{id}/drive-sessions).

Field Type Required Notes
blade_on_allowed boolean yes
end_reason DriveEndReason or null no
ended_at string (date-time) or null no
expires_at string (date-time) yes
frames integer or null no
frames_dropped integer or null no
mower_id string (uuid) yes
origin string or null no Service that drove on behalf of started_by (e.g. vision); None for the joystick.
session_id string (uuid) yes
started_at string (date-time) yes
started_by PrincipalRef yes

EmergencyStop

Stop blades and wheels immediately. Always sent with priority = emergency.

Field Type Required Notes
kind "emergency_stop" no default "emergency_stop"

FirmwareInfo

The firmware state of a mower (MowerState.firmware_info).

Field Type Required Notes
available string or null no The newest version the vendor offers for this mower; null when none or unknown.
checked_at string (date-time) or null no When the vendor was last asked; null when never.
failure_reason string or null no Why the last update failed, if known.
installed string or null no The version running on the mower.
progress integer or null no Percent done while installing, if reported.
release_notes string or null no Release notes of available, if given.
update_state "idle" | "available" | "installing" | "failed" | "unknown" no default "unknown"

FirmwareUpdate

Install the firmware version the vendor offers (MowerState.firmware_info.available).

The adapter refuses it unless update_state is available and version equals available (a stale client), the mower is docked with enough battery (it need not be charging: a full mower stops charging), no job or drive session runs and no update is already installing. While it runs the mower reports the activity updating.

Field Type Required Notes
kind "firmware_update" no default "firmware_update"
version string yes The version to install, as offered.; min length 1; max length 64

GroupIn

POST /groups: site_id null or missing makes a cross-site group.

Field Type Required Notes
name string yes min length 1; max length 100
site_id string (uuid) or null no

GroupList

GET /groups.

Field Type Required Notes
items array of GroupOut yes

GroupOut

A group; mower_ids lists only the mowers the caller may view.

Field Type Required Notes
created_at string (date-time) yes
created_by string (uuid) yes
id string (uuid) yes
mower_ids array of string (uuid) or null no
name string yes
site_id string (uuid) or null yes
updated_at string (date-time) yes

GroupPatch

PATCH /groups/{id}: site_id: null makes it a cross-site group.

Field Type Required Notes
name string or null no
site_id string (uuid) or null no

HTTPValidationError

Field Type Required Notes
detail array of ValidationError no

LeaveDock

Drive out of the charging station and stop a short way in front of it (needs MowerCapabilities.undock). A motion command: only from the dock, never during a sensor stop; it ends an open drive session like a job command.

Field Type Required Notes
kind "leave_dock" no default "leave_dock"

LinkedAccountDetail

A linked account with its devices (answer of create and sync).

Field Type Required Notes
created_at string (date-time) yes
device_count integer yes
devices array of LinkedDeviceOut yes
email string yes
id string (uuid) yes
last_sync_error string or null yes Why the last re-read failed, if it did.
last_synced_at string (date-time) or null yes When the device list was last read successfully.
mower_count integer yes Mowers of this account that connect through it.
provider string yes
updated_at string (date-time) yes

LinkedAccountIn

POST /linked-accounts: the Mammotion account to link (the only provider so far). The password is write-only.

Field Type Required Notes
email string yes min length 3; max length 254
password string yes min length 1; max length 256

LinkedAccountList

GET /linked-accounts.

Field Type Required Notes
items array of LinkedAccountOut yes

LinkedAccountOut

A linked account; the password is never returned.

Field Type Required Notes
created_at string (date-time) yes
device_count integer yes
email string yes
id string (uuid) yes
last_sync_error string or null yes Why the last re-read failed, if it did.
last_synced_at string (date-time) or null yes When the device list was last read successfully.
mower_count integer yes Mowers of this account that connect through it.
provider string yes
updated_at string (date-time) yes

LinkedAccountSyncIn

POST /linked-accounts/{id}/sync: optionally a new password (write-only).

Field Type Required Notes
password string or null no

LinkedDeviceList

GET /linked-accounts/{id}/devices.

Field Type Required Notes
items array of LinkedDeviceOut yes
last_synced_at string (date-time) or null yes

LinkedDeviceOut

A device of a linked account as its last device list showed it.

Field Type Required Notes
base_station_id string (uuid) or null no That base station, when registered as a base station.
device_name string yes
device_type DeviceType no mower, rtk_base (register it with POST /base-stations, ADR 0047) or other (not registrable).; default "other"
iot_id string or null yes
is_mower boolean yes False for RTK base stations and other non-mowers.
model string or null yes
mower_id string (uuid) or null yes That mower, when registered as a mower.
online boolean or null yes
product_key string or null yes
registered boolean yes Registered in this account: as a mower, or as a base station.
registered_elsewhere boolean yes Registered in another MowDeck account (which one is not revealed); it cannot be added here.

LinkedMowerFailure

A device that could not be registered, with the problem it would have answered.

Field Type Required Notes
detail string yes
device_name string yes
status integer yes
type string yes

LinkedMowerIn

One mower of POST /linked-accounts/{id}/mowers.

Field Type Required Notes
device_name string yes min length 1; max length 100
group_ids array of string (uuid) no max items 50
name string or null no
serial string or null no
site_id string (uuid) or null no

LinkedMowersIn

POST /linked-accounts/{id}/mowers: several devices of the account at once.

Field Type Required Notes
mowers array of LinkedMowerIn yes min items 1; max items 50

LinkedMowersOut

Answer of the bulk registration: created mowers and failures per device.

Field Type Required Notes
created array of MowerOut yes
failed array of LinkedMowerFailure yes

LinkOut

An additional link of a mower (MowerOut.links[kind], the link routes).

Field Type Required Notes
created_at string (date-time) yes
kind string yes
options object yes The link's options (host, port, ble_address, device_name, allow_manual_blades, manual_blade_height_mm, manual_drive_speed_mps and the managed drive calibration keys); secret keys show *** and sending *** back keeps the stored value.
proxy_info ProxyInfo or null no What the last scan or check learnt about the bridge; null until one answered. The live link state is MowerState.links[kind] from telemetry.
updated_at string (date-time) yes

ManualDrive

One joystick sample. The mower stops when no new sample arrives within ttl_ms.

This is the dead-man switch: clients resend samples continuously while the stick is held.

Field Type Required Notes
angular number yes Turn left (+) / right (-), normalised.; min -1.0; max 1.0
blade_on boolean no default false
kind "manual_drive" no default "manual_drive"
linear number yes Forward (+) / backward (-), normalised.; min -1.0; max 1.0
ttl_ms integer no Dead-man timeout in milliseconds.; min 100.0; max 2000.0; default 1000

MowDefaults

The saved mowing defaults of a mower (MowerOut.mow_defaults).

Field Type Required Notes
pattern MowPattern yes

MowDefaultsIn

PUT /mowers/{id}/mow-defaults: the mowing defaults every client starts with. pattern: null drops them (clients then use stripes, 0 degrees, one border lap).

Field Type Required Notes
pattern MowPatternIn or null yes

MowerBaseStationIn

PUT /mowers/{id}/base-station: link the mower to a base station, or unlink it.

Field Type Required Notes
base_station_id string (uuid) or null yes null removes the link.

MowerGroupsIn

PUT /mowers/{id}/groups: the complete set of groups.

Field Type Required Notes
group_ids array of string (uuid) yes max items 50

MowerIn

POST /mowers: without site_id the mower goes to the account's default site.

A cloud mower comes from a linked Mammotion account: linked_account_id and the device_name of its device list (connection_options then hold only adapter extras such as refresh_seconds); name defaults to the device name and model to the listed model.

Field Type Required Notes
connection_kind ConnectionKind yes
connection_options object no Adapter specific (simulator: time_scale, battery_percent; cloud: account, device_name or iot_id, credential_ref or password; ble_bridge: host, port, noise_psk, ble_address). Secret values (password, noise_psk) are never returned: responses show ***, and sending *** back keeps the stored value.
device_name string or null no
group_ids array of string (uuid) no max items 50
linked_account_id string (uuid) or null no
model string or null no
name string or null no
serial string or null no
site_id string (uuid) or null no

MowerList

GET /mowers.

Field Type Required Notes
items array of MowerOut yes

MowerOut

A mower.

Field Type Required Notes
area_names map of string no Custom names of map areas by area id (MowerMap.areas[].id); areas without one show the mower's own name, else Area N in map order.
base_station_id string (uuid) or null no The RTK base station the mower is linked to (PUT /mowers/{id}/base-station, ADR 0047); its state is in the mower's telemetry (MowerState.base_station).
connection_kind string yes
connection_options object yes
created_at string (date-time) yes
created_by string (uuid) yes
drive_calibration DriveCalibration or null no The stored drive calibration (PUT /mowers/{id}/drive-calibration): from the ble_bridge link, else from the connection options; null until one is stored.
group_ids array of string (uuid) yes
id string (uuid) yes
iot_id string or null no The vendor's device id (unique across MowDeck accounts).
linked_account_id string (uuid) or null no The linked account a cloud mower connects through.
links map of LinkOut no Additional links next to the connection by kind (ble_bridge: a Bluetooth bridge, PUT /mowers/{id}/links/ble_bridge); empty for a mower with only its connection.
model string or null yes
mow_defaults MowDefaults or null no The mowing defaults every client starts with (PUT /mowers/{id}/mow-defaults); null until saved: then stripes at 0 degrees with one border lap.
name string yes
serial string or null yes
site_id string (uuid) yes
updated_at string (date-time) yes

MowerPatch

PATCH /mowers/{id}: only the given fields change.

Field Type Required Notes
connection_kind ConnectionKind or null no
connection_options object or null no
model string or null no
name string or null no
serial string or null no
site_id string (uuid) or null no

MowPath

The route a mower planned, in the local metres of its map.

Field Type Required Notes
area_ids array of string no The map areas the route covers, in order.
kinds array of "mow" | "edge" | "transfer" | "other" or null no The kind of every polyline (same length), when known.
path_hash string yes The vendor's id of the planned route.; min length 1; max length 32
planned_at string (date-time) yes When MowDeck received the route (UTC).
points_total integer yes Number of points over all polylines.; min 0.0
polylines array of array of array of any no The route as polylines in driving order.
progress MowPathProgress or null no Progress of the running job; None for a preview.

MowPathProgress

Where the mower is along its path.

Field Type Required Notes
direction integer no The vendor's traversal direction flag (0 or 1).; min 0.0; max 255.0; default 0
index integer yes Points done so far, counted over all polylines in order: the points with a flat index below this value are mowed.; min 0.0

MowPattern

The pattern settings of a native start (StartMow.pattern) that every client offers: the pattern, its base angle, the border laps and the path spacing, plus the job options a mower may declare in MowerCapabilities.start_options (obstacle detection, laps around no-go zones, path order, start progress; ADR 0030 amendment of 2026-10-24). An option left None is not sent, so the mower keeps its own default.

Adapters may accept further keys in StartMow.pattern; this is the common, validated part, also kept per mower as the mowing defaults in Fleet (MowerOut.mow_defaults). Whether the mower runs the pattern is decided with MowerCapabilities.native_patterns.

Field Type Required Notes
angle_deg number no Base angle of the stripes in degrees (diagonal adds 45, checkerboard crosses at 90; ignored for edge_only and random_angle).; min 0.0; max 180.0; default 0.0
border_laps integer no Laps along the area edge before the fill (edge_only: at least one).; min 0.0; max 4.0; default 1
name "stripes" | "diagonal" | "checkerboard" | "edge_only" | "random_angle" no The native pattern.; default "stripes"
obstacle_detection ObstacleDetection or null no Obstacle detection mode of the job; None keeps the mower's default. Offered modes: MowerCapabilities.start_options.obstacle_detection.
obstacle_laps integer or null no Laps around each no-go zone; None keeps the mower's default. Model limits: MowerCapabilities.start_options.obstacle_laps_range.
order PathOrder or null no Border laps before or after the fill; None keeps the mower's default. Offered orders: MowerCapabilities.start_options.orders.
spacing_m number or null no Distance between neighbouring paths in metres; None for the mower's own default. Model limits: MowerCapabilities.path_spacing_range_mm.
start_progress_pct integer or null no Start the job at this progress in percent, skipping the first part of the route; None (or 0) starts at the beginning. Model limits: MowerCapabilities.start_options.start_progress_range_pct.

MowPatternIn

MowPattern as a request body: unknown keys are refused (422).

Field Type Required Notes
angle_deg number no Base angle of the stripes in degrees (diagonal adds 45, checkerboard crosses at 90; ignored for edge_only and random_angle).; min 0.0; max 180.0; default 0.0
border_laps integer no Laps along the area edge before the fill (edge_only: at least one).; min 0.0; max 4.0; default 1
name "stripes" | "diagonal" | "checkerboard" | "edge_only" | "random_angle" no The native pattern.; default "stripes"
obstacle_detection ObstacleDetection or null no Obstacle detection mode of the job; None keeps the mower's default. Offered modes: MowerCapabilities.start_options.obstacle_detection.
obstacle_laps integer or null no Laps around each no-go zone; None keeps the mower's default. Model limits: MowerCapabilities.start_options.obstacle_laps_range.
order PathOrder or null no Border laps before or after the fill; None keeps the mower's default. Offered orders: MowerCapabilities.start_options.orders.
spacing_m number or null no Distance between neighbouring paths in metres; None for the mower's own default. Model limits: MowerCapabilities.path_spacing_range_mm.
start_progress_pct integer or null no Start the job at this progress in percent, skipping the first part of the route; None (or 0) starts at the beginning. Model limits: MowerCapabilities.start_options.start_progress_range_pct.

ObstacleDetection

How eagerly the mower avoids obstacles during a native job (MowPattern).

Which modes a mower offers depends on its model and firmware (MowerCapabilities.start_options.obstacle_detection). The names follow the vendor apps: off is the plain bump-and-turn behaviour, standard avoids obstacles it sees ahead, sensitive additionally avoids areas that are not lawn; slow_touch and less_touch exist only on older firmware.

Type: "off" | "slow_touch" | "less_touch" | "standard" | "sensitive"

PathOrder

Whether the border laps run before or after the fill of a native job.

Type: "border_first" | "grid_first"

PathPreviewRequest

Body of POST /api/v1/fleet/mowers/{id}/path-preview: the areas and pattern of a start whose route the mower should plan without starting.

Field Type Required Notes
area_ids array of string yes Map area ids, in order.; min items 1; max items 64
pattern object or null no Pattern settings as for StartMow.pattern.

PauseMow

Pause the current job.

Field Type Required Notes
kind "pause_mow" no default "pause_mow"

PrincipalKind

What kind of subject a principal is.

Type: "user" | "subuser" | "api_token" | "service"

PrincipalRef

A compact reference to a principal, embedded in commands and audit records.

Field Type Required Notes
display_name string or null no
kind PrincipalKind yes Kind of subject.
subject string (uuid) yes Stable subject id (JWT sub).
token_id string (uuid) or null no Token id (JWT jti), if known.

ProxyInfo

What a scan learnt about the bridge itself (ESPHome device_info).

Field Type Required Notes
bluetooth_mac string or null no The bridge's own Bluetooth address.
checked_at string (date-time) yes When the gateway read this information.
compiled_at string or null no
esphome_version string or null no
outdated boolean no default false
outdated_reason string or null no
project_name string or null no esphome.project.name, if set.
project_version string or null no esphome.project.version, if set.
proxy_name string yes The ESPHome node name.; max length 100

RelayEndpoint

Where and with what a client plays a relay session (provider relay).

Field Type Required Notes
heartbeat_seconds integer no How often the client renews the lease while the page is visible.; min 5.0; max 60.0; default 15
lease_id string (uuid) yes The viewer's lease; renew and detach name it.
ticket string yes Short-lived ticket signed by the relay, bound to account, mower, lease and paths. Sent as the WHEP bearer token. Never log it.; min length 1; max length 2048
tiles array of RelayTile yes min items 1; max items 8

RelayTile

One camera as the relay serves it: a WHEP endpoint per camera.

Field Type Required Notes
available boolean or null no Whether this camera delivers video: true once its stream appeared, false when it has not appeared a while after the session went live (a camera the vendor lists but the mower never publishes), null while not known yet. Clients offer only cameras that are not false.
camera_id string yes The CameraInfo.id this endpoint shows.; min length 1; max length 64
whep_url string yes WHEP endpoint of this camera: an absolute path on the MowDeck origin or an http(s) URL. The path carries a random session token, never the mower id.; min length 2; max length 512; pattern `^(/

RelocateDock

Delete the stored position of the charging station, so the mower learns it again (after the station was moved). Only while the mower stands in its dock (docked or charging): out on the lawn it would lose its way home.

Field Type Required Notes
kind "relocate_dock" no default "relocate_dock"

RestartMower

Restart the mower. Only at rest (docked, charging or idle), without an open drive session or a command waiting for its confirmation; the mower is offline while it boots.

Field Type Required Notes
kind "restart_mower" no default "restart_mower"

ResumeMow

Resume a paused job.

Field Type Required Notes
kind "resume_mow" no default "resume_mow"

ResyncRtk

Read the RTK origin and the dock pose again; the map is rebuilt with what the mower answers. No motion; allowed in every activity except during a firmware update.

Field Type Required Notes
kind "resync_rtk" no default "resync_rtk"

ReturnToDock

Pause or end the job and drive back to the charging station.

Field Type Required Notes
end_job boolean no default false
kind "return_to_dock" no default "return_to_dock"

ScannedDevice

One mower advertisement the bridge saw during a scan.

Field Type Required Notes
address string yes Bluetooth address.; min length 1; max length 32
name string yes The Bluetooth name the mower advertises.; min length 1; max length 100
rssi integer yes Signal strength at the bridge in dBm.; min -128.0; max 20.0

SetBladeHeight

Set the cutting height.

Field Type Required Notes
kind "set_blade_height" no default "set_blade_height"
mm integer yes Blade height in millimetres.; min 10.0; max 120.0

SetDriveSpeed

Change the vendor's speed setting for manual driving (MowerCapabilities.drive_speed_setting; the mower scales the stick by it).

Field Type Required Notes
kind "set_drive_speed" no default "set_drive_speed"
speed_mps number yes max 5.0; greater than 0.0

SetLight

Switch the mower's light (the camera's headlamp on Mammotion mowers) on or off.

Needs MowerCapabilities.light. Allowed in every activity, also during an error: the light is harmless and AI assist switches it on to photograph a stuck mower at night.

Field Type Required Notes
kind "set_light" no default "set_light"
on boolean yes True switches the light on, False off.

SetSetting

Change one of the mower's own settings (ADR 0046).

The key must be declared in MowerCapabilities.settings and the value must fit its declaration (type, range, step, options); the controller rejects anything else before it reaches the mower. A setting never makes the mower move. The new value arrives in MowerState.settings once the mower reports it.

Field Type Required Notes
key string yes pattern ^[a-z][a-z0-9_]{0,47}$
kind "set_setting" no default "set_setting"
value boolean or integer or string or TimeWindow or null yes The new value: true or false, a whole number, an option, a time window {start, end}, or null to switch a time window off.

SetSpeed

Set the driving speed while mowing.

Field Type Required Notes
kind "set_speed" no default "set_speed"
mps number yes Speed in metres per second.; max 2.0; greater than 0.0

SiteIn

POST /sites. latitude and longitude (both or none) locate the site for the Scheduler's rain pause.

Field Type Required Notes
address Address or null no
latitude number or null no WGS84 latitude in degrees
longitude number or null no WGS84 longitude in degrees
name string yes min length 1; max length 100
timezone string or null no IANA name

SiteList

GET /sites.

Field Type Required Notes
items array of SiteOut yes

SiteOut

A site.

Field Type Required Notes
address object or null yes
created_at string (date-time) yes
created_by string (uuid) or null yes
id string (uuid) yes
is_default boolean yes
latitude number or null no
longitude number or null no
name string yes
timezone string yes
updated_at string (date-time) yes

SitePatch

PATCH /sites/{id}: only the given fields change (address: null clears it).

Field Type Required Notes
address Address or null no
latitude number or null no WGS84 latitude in degrees
longitude number or null no WGS84 longitude in degrees
name string or null no
timezone string or null no

SpotCircle

A round spot: radius_m around center_wgs84 ([lat, lon]).

Field Type Required Notes
center_wgs84 array of any yes min items 2; max items 2
radius_m number yes max 10.0; greater than 0.0

SpotMow

Mow a small spot by driving the mower along plan with joystick frames (ADR 0039).

Unlike StartMow.spot_plan the mower runs no job of its own: MowDeck's gateway steers it over the drive link (needs MowerCapabilities.manual_drive, a fixed RTK position and an idle mower, or a docked one when the connection can leave the dock by itself: MowerCapabilities.undock, ADR 0041). A transit with the blades off takes the mower from where it stands to the start of the plan; with return_to_dock it is sent home after the run (also after an abort that left it healthy, never after a stop). The blades stay off (a dry run) unless blades and confirm_blades are both true and the mower allows blades while driving (manual_drive_blades). spot records what the user chose; the route is plan. Progress arrives in MowerState.spot_run; SpotStop ends the run.

Field Type Required Notes
blades boolean no Cut while driving (else a dry run).; default false
confirm_blades boolean no The user confirmed the blades separately; required with blades.; default false
kind "spot_mow" no default "spot_mow"
plan SpotMowPlan yes
return_to_dock boolean no Send the mower back to its charging station after the run (also after an abort that left it healthy; never after a stop).; default true
speed_mps number no Driving speed of the run in metres per second (at most 0.3).; max 0.3; greater than 0.0; default 0.2
spot SpotCircle or SpotPolygon or null no The spot as the user chose it (audit only).
turn_style TurnStyle or null no How the run turns at lane ends (ADR 0043); null: the mower's own setting (MowerState.turn_style), else arc. multi_point falls back to arc on a drive link without drive_reverse. The plan should be computed with the same style.

SpotMowPlan

A computed mowing route for StartMow.spot_plan.

Field Type Required Notes
covered_area_m2 number no min 0.0; default 0.0
estimated_duration_s number no min 0.0; default 0.0
native SpotNativeJob or null no
pattern_chain array of string yes min items 1; max items 16
plan_hash string yes SHA-256 of the chain and the segments (spot_plan_hash); must match.; pattern ^[0-9a-f]{64}$
segments array of SpotSegment yes min items 1; max items 10000

SpotNativeJob

The plan expressed as a native job of the mower: whole map areas and one pattern.

Present only when the chain is exactly one pattern the mower may run by itself (stripes, diagonal, checkerboard, edge_only, or border_fill with one of them) on map areas, so a mower without custom_paths can still execute it as an ordinary StartMow(area_ids, pattern).

Field Type Required Notes
area_ids array of string yes min items 1
pattern object yes Settings in the form of StartMow.pattern (name, angle_deg, spacing_m, border_laps, order).

SpotPolygon

A drawn spot: a closed ring of WGS84 [lat, lon] corners (first point not repeated).

Field Type Required Notes
polygon_wgs84 array of array of any yes min items 3; max items 64

SpotSegment

One part of a spot plan: drive along path with the blades on or off (backwards with reverse: the mower faces against the direction of travel, part of a three-point turn).

Field Type Required Notes
blades_on boolean yes
kind "mow" | "turn" | "transfer" no default "mow"
path string yes Encoded polyline of local metres (x, y), centimetre precision (encode_polyline), at least two points.; min length 4; max length 200000
reverse boolean no Drive the polyline backwards (negative linear speed, the mower faces against the direction of travel); always with the blades off (ADR 0043).; default false
speed_mps number yes max 2.0; greater than 0.0

SpotStop

End the running spot run or drive calibration: zero frame, blades off, the mower stays where it is.

Field Type Required Notes
kind "spot_stop" no default "spot_stop"

StartMow

Start mowing the given areas, a stored plan or an inline spot plan (exactly one).

Field Type Required Notes
area_ids array of string no Map area ids to mow, in order.
kind "start_mow" no default "start_mow"
pattern object or null no Pattern settings (validated by the pattern's own JSON Schema).
plan_ref string or null no Reference to a stored mowing plan.
spot_plan SpotMowPlan or null no A route computed by the Planner (spot mowing). Runs only on mowers with custom_paths, or natively when the plan carries a native job.

SyncMap

Read the mower's map again in full (areas, zones, paths, dock) and publish it. No motion; refused while a manual drive session is open (the transfer occupies the mower's command queue).

Field Type Required Notes
kind "sync_map" no default "sync_map"

TimeWindow

A daily window in the mower's local time, HH:MM on a 24-hour clock. end before start crosses midnight (22:00 to 06:00).

Field Type Required Notes
end string yes End, HH:MM (24-hour clock).; pattern `^([01]\d
start string yes Start, HH:MM (24-hour clock).; pattern `^([01]\d

TurnStyle

How a spot run turns at the end of a lane (ADR 0043).

in_place: the mower rotates on the spot (fast, but an all-wheel-drive mower scuffs the turf). arc: a forward U-turn with a radius of at least half the lane spacing, or a bulb turn over the neighbouring lane when the spacing is narrower than the turning radius. multi_point: a three-point turn (forward arc, reverse arc with the blades off, forward arc); needs a drive link that can reverse (MowerCapabilities.drive_reverse).

Type: "in_place" | "arc" | "multi_point"

ValidationError

Field Type Required Notes
ctx object no
input any no
loc array of string or integer yes
msg string yes
type string yes

Mirrored from docs/reference/api/fleet.md at commit 11a94afbcace55924c9675ef400e93c7785b4ac5. Edit the file in the repository, not this wiki page.

MowDeck documentation

Clone this wiki locally