Skip to content

Serving tasks

A serving task is one physical run: carry this order’s tray to this dining spot, or courier this order to its delivery address. Tasks are offered by Sitora, claimed by your controller, and driven through a strict state machine.

offered ──claim──▶ claimed ──staff loads──▶ loaded ──▶ en_route ──▶ arrived ──▶ completed
│ │ │
└─ expired └─ failed(code) ◀────────────────────────────────┘ any: cancelled

POST /serving-tasks/{id}/claim/. First claim wins; a lost race returns 409 with code already_claimed; an elapsed offer window returns 410 with code offer_expired. Expired offers fall back to human staff — do not treat expiry as an error to retry.

Your robot waits at the pass; a human confirms the tray matches the manifest in Sitora Pro. You cannot report loaded — attempting to returns 400 with code status_not_reportable. Custody of food is granted by a person, never self-declared by a machine.

loaded → en_route → arrived → completed

Section titled “loaded → en_route → arrived → completed”

POST /serving-tasks/{id}/report/ with {"status": "..."}. Reports are strictly ordered; an out-of-order report returns 409 with code task_<current_status> (for example task_claimed) and a detail naming the task’s current state. An optional telemetry object may accompany any report; it is stored in the task’s event log.

Reportable from any post-claim state, with a coded reason:

failure_code Meaning
obstacle_blocked Path blocked and unrecoverable.
hardware_fault Mechanical or electrical failure.
navigation_lost Localization lost.
payload_disturbed Tray/payload compromised in transit.
battery_critical Insufficient charge to finish the run.
operator_abort Your operator intervened.
other Anything else — include a reason.

Failure is safe: the order instantly falls back to the human workflow and staff are alerted. Report failures honestly and immediately.

Arrives from Sitora — staff served the order first, the order was cancelled, or staff cancelled the run. Stop the run and return to base. Cancellation after loaded alerts staff to recover the tray.

Completion never writes the order’s status directly. What happens next is the filial’s confirmation policy:

  • human_confirmed (default) — staff serve the order in Sitora Pro as usual; their confirmation closes the loop and is back-linked to the task.
  • auto_confirm — the backend applies the order transition itself after your completed report. The report must arrive at least the configured dwell (auto_confirm_dwell_seconds in the fleet snapshot) after arrived — completing faster than a guest could plausibly take the tray is rejected with 409 (arrival_dwell_pending).

Each task carries the work description — and nothing else:

{
"order_display_number": 118,
"leg": "dine_in_tray",
"items": [
{ "name": "Grilled trout", "quantity": "1" },
{ "name": "Green tea", "quantity": "2" }
],
"dining_spot": { "id": 12, "number": 4, "label": "Table 4", "spot_type": "table" }
}

Courier-leg manifests carry delivery_address instead of dining_spot. No customer record, phone number, order note, price, or payment data is ever present — those fields are never read into the manifest.

The manifest is served only on the polling endpoints, where your credential is checked on every read. It is never sent in a webhook.