Repository navigation
Reference Vision
AI assisted recovery: proposals, approvals and the provider settings.
Base path /api/v1/vision behind the gateway. Authentication, rate limits and the error format are the same for every service: see Scripting MowDeck. Rendered from apps/web/openapi/vision.json (OpenAPI 3.1), which you can also load into any OpenAPI tool.
My Preferences
The caller's AI assist preferences (the defaults until saved): stereo_frames and the opt-in to automatic AI analyses on errors (off until saved) with the installation's limits (cooldown per mower, analyses per mower and day).
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json PreferencesOut
|
Put My Preferences
Change the caller's AI assist preferences; a field left out keeps its value.
auto_analysis: when a mower of the account enters a recoverable error (stuck, blocked, outside the work area, wheel slip), the service takes a photo, analyses it with the caller's provider (or the installation's) and asks for approval like a manual request; nothing is executed automatically. Enabling needs the plan feature ai_recover (403 feature-not-in-plan; nothing is saved then).
Request body (required): application/json PreferencesIn
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json PreferencesOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
My Provider
The caller's own provider (the key only as api_key_set) and the provider a request would use now (effective).
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProviderOut
|
Put My Provider
Save the caller's provider. 422 for an unknown family, a refused base URL or bad headers; 409 vision-secrets-unavailable when a key is sent but cannot be stored.
Request body (required): application/json ProviderIn
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProviderOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Delete My Provider
Delete the caller's provider (404 when there is none).
| Status | Meaning | Body |
|---|---|---|
| 204 | Successful Response | no body |
Test My Provider
One minimal vision call with a tiny generated image: model, latency, tokens and the estimated cost. 429 vision-quota beyond the hourly limit.
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProviderTestOut
|
Mower Proposals
Proposals of the mower, newest first.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
mower_id |
path | string (uuid) | yes | |
limit |
query | integer | no | min 1; max 100; default 20
|
before |
query | string (date-time) or null | no |
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProposalPageOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Recover
Start AI assist for the mower: task recover or find_dock, optional camera snapshots (base64, each optionally with camera, side and captured_at; a left and a right frame of the same moment are analysed as a stereo pair when the caller's preference stereo_frames is on, else only the left one). The analysis runs in the background; poll GET /proposals/{id}. Without images the mower's gateway is asked for one. 403 feature-not-in-plan without ai_recover, 409 vision-provider-missing without a usable provider, 409 when a proposal for the mower is open, 429 vision-quota beyond the daily cap.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
mower_id |
path | string (uuid) | yes |
Request body (required): application/json RecoverIn
| Status | Meaning | Body |
|---|---|---|
| 202 | Successful Response |
application/json ProposalOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Recover Upload
recover with the snapshots as multipart/form-data files (field images).
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
mower_id |
path | string (uuid) | yes |
Request body: multipart/form-data Body_recover_upload_api_v1_vision_mowers__mower_id__recover_upload_post
| Status | Meaning | Body |
|---|---|---|
| 202 | Successful Response |
application/json ProposalOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Get Proposal
One proposal with its step audit; poll while final is false.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
proposal_id |
path | string (uuid) | yes |
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProposalOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Approve
Approve: the chosen option runs on the caller's behalf (blades off, dead-man 1 s). The optional body picks the option (model or fallback; omitted: the default action). One approval per proposal; 409 vision-proposal-expired after expires_at; 422 for an option the proposal does not offer.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
proposal_id |
path | string (uuid) | yes |
Request body: application/json ApproveIn or null
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProposalOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Proposal Image
An image the model saw; 404 once it was purged (after the proposal TTL).
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
index |
path | integer | yes | min 0; max 7 |
proposal_id |
path | string (uuid) | yes |
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
image/jpeg any, image/png any |
| 422 | Validation Error |
application/json HTTPValidationError
|
Reject
Reject a waiting proposal, or stop a running execution at once.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
proposal_id |
path | string (uuid) | yes |
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProposalOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Retry
Another round after one that did not help (can_retry), with fresh snapshots.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
proposal_id |
path | string (uuid) | yes |
Request body (required): application/json RetryIn
| Status | Meaning | Body |
|---|---|---|
| 202 | Successful Response |
application/json ProposalOut
|
| 422 | Validation Error |
application/json HTTPValidationError
|
Providers
The model families users can configure and whether the installation's model may be used by the caller's account.
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json ProvidersOut
|
Vision Status
What the operator configured: whether a hosted default exists and its model string (never a key), whether users can store keys, the base URL policy.
| Status | Meaning | Body |
|---|---|---|
| 200 | Successful Response |
application/json StatusOut
|
POST /proposals/{id}/approve: which option runs (the body is optional).
| Field | Type | Required | Notes |
|---|---|---|---|
option |
"model" | "fallback" or null |
no |
model: the model's recommendation (also a low-confidence one offered next to the fallback); fallback: the rule based return to dock. Omitted: the default option (action). An option the proposal does not offer answers 422. |
What the model thinks (without the steps, which are listed separately).
| Field | Type | Required | Notes |
|---|---|---|---|
abort_reasons |
array of string | yes | |
action |
ProposalAction | no | What the model recommended: drive, return_to_dock, resume or none.; default "drive"
|
confidence |
number | yes | |
rationale |
string | yes | |
risk |
array of RiskFlag | yes | |
situation |
string | yes |
| Field | Type | Required | Notes |
|---|---|---|---|
images |
array of string or null | no | |
task |
VisionTask | no | default "recover"
|
A model family the settings page offers.
| Field | Type | Required | Notes |
|---|---|---|---|
default_api_base |
string or null | yes | |
examples |
array of string | yes | |
key |
string | yes | |
key_env |
string or null | yes | Variable LiteLLM reads for the operator's key. |
label |
string | yes | |
local |
boolean | yes | Runs on own hardware: images stay local. |
needs_api_base |
boolean | yes | |
needs_key |
boolean | yes | |
prefix |
string | yes | Model strings look like <prefix>/<model>. |
What one image of the proposal was (fetch it from images/{index}).
| Field | Type | Required | Notes |
|---|---|---|---|
camera |
string or null | no | |
captured_at |
string (date-time) or null | no | |
index |
integer | yes | |
side |
"left" | "right" or null |
no | |
source |
"upload" | "mower" | "map"
|
yes |
upload: sent by the app; mower: the mower's own photo; map: the top-down map rendering around the mower (heading up) that Vision adds. |
| Field | Type | Required | Notes |
|---|---|---|---|
detail |
array of ValidationError | no |
A camera snapshot, base64 encoded (JPEG or PNG), optionally with the camera that took it. Two frames with side left and right captured at most MOWDECK_VISION_STEREO_MAX_SKEW_MS apart form a stereo pair.
| Field | Type | Required | Notes |
|---|---|---|---|
camera |
string or null | no | The camera's display name, e.g. Front left. |
captured_at |
string (date-time) or null | no | When the frame was grabbed (with a time zone). |
data |
string | yes | Base64 (standard) of the image bytes.; max length 14000000 |
media_type |
"image/jpeg" | "image/png"
|
yes | |
side |
"left" | "right" or null |
no |
left or right: the frame is one of the two front cameras (stereo). |
One planned area of the job, in driving order.
| Field | Type | Required | Notes |
|---|---|---|---|
id |
string | yes | |
name |
string or null | no | |
status |
"done" | "current" | "next" | "planned"
|
yes |
The mowing job the mower was running when the scene was analysed (what resume continues).
| Field | Type | Required | Notes |
|---|---|---|---|
areas |
array of JobAreaOut | yes | Planned areas in driving order. |
current_area |
string or null | no | |
entry_distance_m |
number or null | no | Distance to the entry of the way to the next area. |
mower_at_entry |
boolean | no | The mower stood at the entry of the way to the next area.; default false
|
next_area |
string or null | no | |
progress_percent |
integer or null | no | |
resumable |
boolean | yes | |
status |
"running" | "paused" | "paused_by_error" | "returning" | "spot_run"
|
yes |
The outcome of the last provider test.
| Field | Type | Required | Notes |
|---|---|---|---|
at |
string (date-time) | yes | |
cost_usd |
number or null | no | |
detail |
string or null | no | |
input_tokens |
integer or null | no | |
latency_ms |
integer or null | no | |
ok |
boolean | yes | |
output_tokens |
integer or null | no |
One option a waiting proposal offers; the user approves one of them.
| Field | Type | Required | Notes |
|---|---|---|---|
action |
ProposalAction | yes | |
confidence |
number or null | no | The model's confidence (null for the fallback). |
default |
boolean | yes | What an approval without an option runs (action). |
low_confidence |
boolean | yes | The model recommends it with a confidence below the threshold. |
option |
"model" | "fallback"
|
yes |
model: the model's recommendation; fallback: the rule based return to dock. Pass it to approve. |
steps |
array of StepOut | no | The drive steps (blades off) of this option. |
PUT /me/preferences: a field left out (null) keeps its value.
| Field | Type | Required | Notes |
|---|---|---|---|
auto_analysis |
boolean or null | no | Opt in to (or out of) automatic AI analysis on errors. |
stereo_frames |
boolean or null | no | Send both front camera frames when both views are live. |
GET /me/preferences: the caller's AI assist preferences and the installation's limits of automatic analyses.
| Field | Type | Required | Notes |
|---|---|---|---|
auto_analysis |
boolean | yes | Automatic AI analysis on errors for the caller (opt-in, default off). |
auto_analysis_available |
boolean | yes | False when the installation switched automatic analyses off. |
auto_cooldown_minutes |
integer | yes | No automatic analysis for a mower within this time after the previous one. |
auto_daily_per_mower |
integer | yes | Automatic analyses per mower and UTC day. |
stereo_frames |
boolean | yes | Send both front camera frames when both views are live (a stereo pair: two images, about twice the image share of the cost). |
updated_at |
string (date-time) or null | yes | Null while the defaults apply. |
What kind of subject a principal is.
Type: "user" | "subuser" | "api_token" | "service"
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. |
What a proposal does once a human approves it.
Type: "drive" | "return_to_dock" | "resume" | "none"
A proposal of AI assist (poll it while final is false).
| Field | Type | Required | Notes |
|---|---|---|---|
action |
ProposalAction | no | The default option, what an approval without a choice executes (after an approval: what runs): drive (the steps, blades off), return_to_dock (the normal dock command; no steps) or resume (the steps, if any, then the paused job continues with resume_mow). none only on rejected rows.; default "drive"
|
alternative_action |
ProposalAction or null | no | The model's low-confidence recommendation next to the fallback action; approve it with option model. |
analysed_at |
string (date-time) or null | yes | |
approved_at |
string (date-time) or null | yes | |
approved_by |
PrincipalRef or null | yes | |
approved_option |
"model" | "fallback" or null |
no | Which option the approval ran. |
assessment |
AssessmentOut or null | yes | |
can_retry |
boolean | yes | |
chain_id |
string (uuid) | yes | |
created_at |
string (date-time) | yes | |
decided_at |
string (date-time) or null | yes | |
decided_by |
PrincipalRef or null | yes | Who rejected or cancelled it. |
detail |
string or null | yes | Why it was rejected, failed or how it ended. |
drive_session_id |
string (uuid) or null | yes | |
expires_at |
string (date-time) or null | yes | Approval is refused after this time. |
fallback |
boolean | no |
action is the rule based return to dock fallback, not the model's recommendation: it applies (mower in a mapped area linked to the dock, no safety stop). It still needs an approval.; default false
|
final |
boolean | yes | |
finished_at |
string (date-time) or null | yes | |
frames |
array of FrameOut | yes | What each image was, in the order the model saw them (left first in stereo). |
hosted |
boolean | yes | |
id |
string (uuid) | yes | |
image_count |
integer | yes | |
job |
JobOut or null | no | The mowing job as the model saw it (with action resume the job that continues); null when no job was known. |
light_used |
boolean | yes | The photo was taken with the mower's light switched on (it was too dark). |
low_confidence |
boolean | no | The model's recommendation is offered although its confidence is below the threshold: as action, or as alternative_action next to the fallback.; default false
|
model_refused |
string or null | no | Why the model's low-confidence recommendation is not offered (it failed a safety check: not applicable, step limits, position, geofence or no-go zone). |
mower_id |
string (uuid) | yes | |
options |
array of OptionOut | no | While proposed: the options to choose from, the default first. |
photo_problem |
VisionPhotoProblem or null | no | The mower's camera delivered no photo, and why: weak_wifi or weak_mobile (with signal_dbm), offline or no_frame. With state failed and trigger error the automatic analysis could not run; otherwise the model saw only the map and uploaded images. |
provider_family |
string or null | yes | |
provider_model |
string or null | yes | |
requested_by |
PrincipalRef | yes | |
return_command_id |
string (uuid) or null | yes | The command sent after approval: return_to_dock, or resume_mow for action resume. |
round |
integer | yes | |
rounds_left |
integer | yes | |
signal_dbm |
integer or null | no | With a weak signal: the mower's signal in dBm. |
started_at |
string (date-time) or null | yes | |
state |
ProposalState | yes | |
steps |
array of StepOut | yes | |
stereo |
boolean | yes | The model saw a stereo pair: the left and right front camera, same moment. |
task |
VisionTask | yes | |
trigger |
VisionTrigger | no |
manual (a user asked) or error (started automatically when the mower entered a recoverable error; the requester is the user who opted in).; default "manual"
|
trigger_error_code |
string or null | no | With trigger error: the error code that started it. |
updated_at |
string (date-time) | yes |
GET /mowers/{id}/proposals: newest first; pass next_before as before.
| Field | Type | Required | Notes |
|---|---|---|---|
items |
array of ProposalOut | yes | |
next_before |
string (date-time) or null | yes |
Lifecycle of a proposal.
Type: "analysing" | "proposed" | "rejected_by_ai" | "failed" | "rejected" | "expired" | "executing" | "verifying" | "recovered" | "not_recovered" | "aborted"
PUT /me/provider. api_key and headers are write-only: omit them to keep the stored values, send an empty string (or object) to delete them.
| Field | Type | Required | Notes |
|---|---|---|---|
api_base |
string or null | no | |
api_key |
string or null | no | |
enabled |
boolean | no | default true
|
headers |
map of string or null | no | |
model |
string | yes | min length 3; max length 200 |
GET /me/provider: the caller's provider (never the key) and the effective choice.
| Field | Type | Required | Notes |
|---|---|---|---|
api_base |
string or null | yes | |
api_key_set |
boolean | yes | |
configured |
boolean | yes | |
effective |
"own" | "hosted" | "none"
|
yes | Which provider a request would use now. |
enabled |
boolean | yes | |
family |
string or null | yes | |
header_names |
array of string | yes | |
hosted_available |
boolean | yes | |
hosted_model |
string or null | yes | |
last_test |
LastTestOut or null | yes | |
model |
string or null | yes | |
secrets_available |
boolean | yes | |
updated_at |
string (date-time) or null | yes |
GET /providers: families, and whether the installation's model may be used.
| Field | Type | Required | Notes |
|---|---|---|---|
families |
array of FamilyOut | yes | |
hosted_available |
boolean | yes | |
hosted_model |
string or null | yes | |
secrets_available |
boolean | yes | Whether API keys can be stored here. |
POST /me/provider/test: one minimal vision call with a tiny generated image.
| Field | Type | Required | Notes |
|---|---|---|---|
cost_usd |
number or null | yes | LiteLLM's estimate; null when unknown. |
detail |
string or null | yes | |
family |
string | yes | |
input_tokens |
integer or null | yes | |
latency_ms |
integer | yes | |
model |
string | yes | |
ok |
boolean | yes | |
output_tokens |
integer or null | yes |
POST /mowers/{id}/recover as JSON. Without images the service asks the mower's gateway for one (capture_photo) and otherwise analyses the context alone.
| Field | Type | Required | Notes |
|---|---|---|---|
images |
array of ImageIn | no | max items 8 |
task |
VisionTask | no | default "recover"
|
POST /proposals/{id}/retry: optional fresh snapshots.
| Field | Type | Required | Notes |
|---|---|---|---|
images |
array of ImageIn | no | max items 8 |
Hazards the model saw; any flag means the maneuver is never executed.
Type: "people_visible" | "animals_visible" | "drop_off" | "water" | "road"
GET /status: what the operator configured (never a key).
| Field | Type | Required | Notes |
|---|---|---|---|
allow_fake_provider |
boolean | yes | |
hosted_default_enabled |
boolean | yes | |
hosted_default_model |
string or null | yes | Only when the default is enabled. |
secrets_available |
boolean | yes | |
user_api_base_policy |
string | yes |
One drive step (blades are always off).
| Field | Type | Required | Notes |
|---|---|---|---|
angular |
number | yes | Turn right (-1) to left (1). |
detail |
string or null | no | |
ended_at |
string (date-time) or null | no | |
frames |
integer | no | default 0
|
index |
integer | yes | |
linear |
number | yes | Backward (-1) to forward (1). |
outcome |
StepOutcome | yes | |
seconds |
number | yes | |
started_at |
string (date-time) or null | no |
What happened to one drive step.
Type: "pending" | "done" | "aborted" | "skipped"
| Field | Type | Required | Notes |
|---|---|---|---|
ctx |
object | no | |
input |
any | no | |
loc |
array of string or integer | yes | |
msg |
string | yes | |
type |
string | yes |
Why an analysis got no camera photo from the mower (the most likely cause, judged from the mower's state at the time and the gateway's answer).
Type: "weak_wifi" | "weak_mobile" | "offline" | "no_frame"
What AI assist is asked to do.
Type: "recover" | "find_dock"
Who started an analysis.
Type: "manual" | "error"
Mirrored from docs/reference/api/vision.md at commit 4c3787f99a906065181b05e960a83f0aca64bbe4. Edit the file in the repository, not this wiki page.
Mirrored from the docs/ directory at commit 4c3787f99a906065181b05e960a83f0aca64bbe4. Edit the files in the repository, not this wiki.
MowDeck documentation
- Home
- Phases
- Architecture
-
Decisions (ADR)
- Architecture decisions
- ADR 0001: OpenFGA instead of self-built authorization
- ADR 0002: Self-built Identity service in FastAPI instead of Keycloak or Zitadel
- ADR 0003: SvelteKit for the web app
- ADR 0004: Monorepo with a uv workspace
- ADR 0005: AGPL-3.0 for services and apps, Apache-2.0 for libraries
- ADR 0006: PostgreSQL for all persistence, no SQLite
- ADR 0007: NATS JetStream as event bus
- ADR 0008: Traefik as gateway
- ADR 0009: Command and event envelopes, subject naming and de-duplication
- ADR 0010: Python 3.13 for all services and libraries
- ADR 0011: Separate GPL-3.0 package for the PyMammotion adapter
- ADR 0012: Mower control interface and safety rules
- ADR 0013: Device-Gateway registry, sharding and per-mower concurrency
- ADR 0014: Authorization model, tuple ownership and the mowdeck-authz client
- ADR 0015: Tokens, sessions and key rotation
- ADR 0016: Fleet commands and authorization per command kind
- ADR 0017: Telemetry storage and retention
- ADR 0018: Realtime WebSocket protocol
- ADR 0019: Mammotion adapter transports, manual drive and secrets
- ADR 0020: Web app architecture
- ADR 0021: Browser authentication flow
- ADR 0022: Notifications: rules, recipients and delivery
- ADR 0023: Map rendering and projection
- ADR 0024: Scheduler: recurrence, rain pause and command issuing
- ADR 0025: Home Assistant integration as a pure API client
- ADR 0026: Manual drive channel over the Realtime WebSocket
- ADR 0027: Health history and theft alarm
- ADR 0028: Entitlements: plans as data and enforcement
- ADR 0029: Helm chart and release pipeline
- ADR 0030: Mowing patterns as plug-ins and the Planner
- ADR 0031: Billing with a Stripe adapter
- ADR 0032: Live camera over Agora, joined directly by the browser
- ADR 0033: Vision-assisted recovery with human approval
- ADR 0034: Linked cloud accounts and device discovery
- ADR 0035: Server-side camera frames and automatic AI analysis on errors
- ADR 0036: Native app shells with Capacitor, loading the web app from the server
- ADR 0037: Camera panorama calibration in the browser, with the AI supplying points only
- ADR 0038: Dual link per mower and firmware updates
- ADR 0039: Spot mowing by MowDeck-driven paths
- ADR 0040: Link heartbeat for online status
- ADR 0041: Spot runs from the dock: undock, transit and return
- ADR 0042: Drive calibration
- ADR 0043: Turn styles
- ADR 0044: Drive view with camera
- ADR 0045: Camera relay
- ADR 0046: Device settings as capabilities
- ADR 0047: The RTK base station as a Fleet device
- ADR 0048: Maintenance commands
- ADR 0049: Manual driving over the Mammotion cloud
- ADR 0050: Passkeys and the app login hand-off
- ADR 0051: Sign in with GitHub
- ADR 0052: Sign in with Apple
- ADR 0053: Retention and downsampling of the position track
- ADR 0054: Aerial photo under the mower map
- ADR 0055: Deploy maintenance window
- ADR 0056: Camera photo in push notifications for errors and theft alarms
- ADR 0057: Step-up re-authentication for critical actions
- ADR 0058: Theft tracking mode
- ADR 0059: iOS widgets and the mowing Live Activity
- ADR 0060: Apple Watch app
- ADR 0061: Mowing angle rotation
- ADR 0062: Setup tour for new users
- ADR 0063: Matter server (mowers in Apple Home and Google Home)
- ADR 0064: Personal access tokens and the public API documentation
- ADR 0065: Security center and new-login alerts
- ADR 0066: Cloud provider plugins and adapters for more vendors
- ADR 0067: Error code lexicon, provider independent
- ADR 0068: Public demo mode
- ADR 0069: Provider conformance kit and provider package template
- ADR 0070: Virtual zones for mowers without a vendor map
- ADR 0071: Capability matrix generated from the adapters
- ADR 0072: API explorer in the web app, for the public demo
-
Development
- Getting started
- Service template
- Shared libraries
- Cloud providers: adding a vendor
- Adding a provider: template and conformance kit
- Adding an error lexicon for a vendor
- Design: identity and authorization
- Design: fleet, telemetry, realtime
- Design: web app
- Web app
- Home Assistant integration
- Camera source bridge protocol
- Fuzzing and property-based tests
- GitHub wiki mirror
-
Operations
- Operating the Compose stack
- Operating MowDeck on Kubernetes (Helm)
- Building the Bluetooth bridge (ESPHome on a XIAO ESP32-S3)
- Releases
- Vendor library updates
- Billing operations
- Telemetry: retention and position downsampling
- iPhone and Android apps
- Passkeys
- Sign in with GitHub
- Aerial photo under the map
- Sign in with Apple
- Theft tracking mode
- Matter server
- Source code offer (AGPL-3.0 section 13)
- Public demo
- Spikes
-
Guides
- Guides
- ESP32 bridge: purchase and setup
- Signing in with a passkey
- Signing in with GitHub
- Error codes in plain words
- Aerial photo under the map
- Signing in with Apple
- Confirming critical actions
- Your security page
- iPhone widgets and the mowing Live Activity
- Apple Watch
- The setup tour
- Apple Home and Google Home (Matter)
- Worx Landroid, Kress and LandXcape mowers
- Scripting MowDeck
- Capability matrix
- API reference
- Original plan (German)