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.
Lifecycle
Section titled “Lifecycle”offered ──claim──▶ claimed ──staff loads──▶ loaded ──▶ en_route ──▶ arrived ──▶ completed │ │ │ └─ expired └─ failed(code) ◀────────────────────────────────┘ any: cancelledoffered → claimed
Section titled “offered → claimed”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.
claimed → loaded is staff-attested
Section titled “claimed → loaded is staff-attested”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.
failed
Section titled “failed”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.
cancelled
Section titled “cancelled”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 and confirmation
Section titled “Completion and confirmation”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 yourcompletedreport. The report must arrive at least the configured dwell (auto_confirm_dwell_secondsin the fleet snapshot) afterarrived— completing faster than a guest could plausibly take the tray is rejected with409(arrival_dwell_pending).
The manifest
Section titled “The manifest”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.