DevelopersTablet version · pilot
Read the room and send an action
Snapshots, versions and idempotent commands for the tablet workflow.
Read the snapshot
GET /api/room returns serverNow, plan, service, tables and groups. plan and service may be null. Plan tables carry geometry and labels; service tables carry state, version, timer, level, available actions and undo availability.
The current client polls the snapshot every second. No public WebSocket or SSE stream is provided yet. Timestamps are UTC; the interface displays them in Europe/Paris.
const response = await fetch("/api/room", {
credentials: "same-origin",
cache: "no-store",
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const room = await response.json();Example without a prepared plan
{
"serverNow": "2026-10-21T18:30:00.000Z",
"plan": null,
"service": null,
"tables": [],
"groups": []
}Write a command
POST /api/room/services opens a service with { id }. Here id is the new service UUID. Other commands use a UUID id unique to the action. A table mutation also requires expectedVersion from the latest snapshot.
Actions are seat, greet, order, serve, request_bill, deliver_bill, pay, depart, clear and undo. Use the snapshot’s available actions: not every transition is allowed.
In the example, service and table come from the latest snapshot and the table is open and ungrouped. The browser supplies Origin automatically.
const command = {
id: crypto.randomUUID(),
type: "seat",
expectedVersion: table.version,
};
const response = await fetch(
`/api/room/services/${service.id}/tables/${table.tableId}/commands`,
{
method: "POST",
credentials: "same-origin",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(command),
},
);
// Keep the same command object when retrying an uncertain response.Retries and concurrency
After an uncertain network response, replay exactly the same identifier and content. A duplicate: true response confirms that an identical command is already recorded. It does not replace a fresh room read.
A version conflict requires rereading the snapshot and checking the operator’s intent. Do not automatically change expectedVersion to force an outdated action.
For a joined table, add groupId and members: [{ tableId, version }]. Group operations require id, type, groupId, expectedVersion, primaryTableId and members. type is join, split, undo_join or undo_split; expectedVersion is the group version, or zero for its first join.
{ "duplicate": false }
// A successful retry of the same command:
{ "duplicate": true }Need a hand?
Describe the step that failed and the message shown. Keep passwords and sign-in codes private.
Contact the Kelna team