Skip to content

Polling Orders & Commands

After receiving a message event on the SSE stream, the client polls GET /orders/location to retrieve all pending orders and commands. This endpoint returns both regular orders and command objects in a single response.

Endpoint

text
GET https://{host}/orders/location

Headers:

HeaderRequiredDescription
api_keyYesService device API key

Query parameters:

ParameterTypeDefaultDescription
orderNumberlong0Only return orders with number greater than this value
commandNumberlong0Only return commands with ID greater than this value

Response: 200 OK with body ExternalOrder[] (JSON array)

Response Schema

The endpoint returns a JSON array of ExternalOrder objects. Each object can represent either a food/beverage order or a command (e.g., read table state, request bill, export data).

ExternalOrder

json
{
  "number": 12345,
  "orderTime": "10:30:00",
  "tableNumber": 12,
  "userNumber": 5,
  "guestCount": 1,
  "rows": [
    {
      "category": {
        "order": 0,
        "id": 0,
        "description": "Beverages"
      },
      "itemType": "Beverages",
      "name": "Espresso",
      "number": 1,
      "factor": 2,
      "price": 3.50,
      "subrows": []
    }
  ],
  "state": "PLACED",
  "isCommand": false
}

Fields that are not set are omitted from the response — null values are never serialized. The payload above shows a regular order; commands carry the same envelope but replace rows with a single type marker (see Distinguishing Orders from Commands).

Top-Level Fields

FieldTypeDescription
numberlongUnique order/command identifier. Use this for idempotency and offset tracking
orderTimestringTime the order was placed (commands: when the command was created), format HH:mm:ss
tableNumberlong or nullTable number (absent for takeout orders)
userNumberlong or nullUser number who placed the order (absent if no user session)
guestCountintNumber of guests. Currently always 1 on orders
readTableStatebooleanPresent (true) only on read-table-state commands
paymentNumberintPresent only on request-bill commands (always 1)
exportMainDatabooleanPresent (true) only on export-data / fetch-remote-menu commands
rowsarrayOrder line items. Only present on orders; commands have no rows
statestringOrder state. Always present; commands always report PLACED
isCommandbooleantrue for commands, false for orders. Use it to dispatch on payload type

The DTO also defines togo, moveTableTo, receipt, paymentDiscount, and customer, but the current backend never populates them, so they never appear in responses.

OrderRow

FieldTypeDescription
categoryobject or nullProduct category with order, id, and description (order/id are currently always 0)
itemTypestringType of item. One of Menu item, Food, Takeout, Condiments, Beverages, Arrangement
namestringProduct name
infotextstringSpecial instructions or notes (omitted when empty)
numberintRow number
factorintQuantity
pricenumberUnit price
priceTogonumberTakeout price if different (currently never populated)
discountarrayDiscounts applied to this row (currently never populated)
subrowsarraySub-items (modifiers, sides). Always an array; [] when there are none

Category

FieldTypeDescription
orderintSort order
idintCategory ID
descriptionstring or nullCategory name

Distinguishing Orders from Commands

The response array contains a mix of regular orders and commands. Every object carries an isCommand boolean — true for commands, false for orders — so clients can dispatch on it directly. The equivalent derivation, if you prefer not to rely on the flag, is: an ExternalOrder is a command if any of these fields is present:

  • isCommand is true
  • readTableState is true
  • exportMainData is true
  • paymentNumber is not null

The DTO also defines a moveTableTo field for a potential move-table command, but the current backend never produces it.

Detection pseudo-code:

javascript
function isCommand(item) {
  return item.isCommand === true
      || item.readTableState === true
      || item.exportMainData === true
      || item.paymentNumber !== null;
}

function processResponse(items) {
  for (const item of items) {
    if (isCommand(item)) {
      handleCommand(item);
    } else {
      handleOrder(item);
    }
  }
}

Command Types

Detection FieldCommand TypeWhat To Do
readTableState: trueRead table stateQuery your local table state and POST response to /commands/{id}/response
exportMainData: trueFetch remote menu / export dataExport your menu data (e.g., for Vectron integration)
paymentNumber: 1Request billProcess the customer's bill request (paymentNumber is always 1)

Command Payloads

Each command carries the same envelope as an order (number, orderTime, state, isCommand) plus exactly one type marker:

Request bill (paymentNumber):

json
{
  "number": 42,
  "orderTime": "14:32:05",
  "tableNumber": 12,
  "paymentNumber": 1,
  "state": "PLACED",
  "isCommand": true
}

Fetch remote menu / export data (exportMainData):

json
{
  "number": 43,
  "orderTime": "14:33:10",
  "exportMainData": true,
  "state": "PLACED",
  "isCommand": true
}

Read table state (readTableState):

json
{
  "number": 44,
  "orderTime": "14:34:22",
  "tableNumber": 7,
  "readTableState": true,
  "state": "PLACED",
  "isCommand": true
}

The number field is the command ID — use it when responding via POST /commands/{id}/response.

OrderState Enum

The state field on orders uses these values:

text
SELECTING  — Customer is still selecting items (not yet placed)
NEW        — Order was just created by a client application
PLACED     — Customer has submitted the order, ready for processing
ABORTED    — Order was cancelled (e.g., session closed)
FAILED     — Order processing failed in the backend system
COMPLETED  — Order was completed successfully

For polling, the endpoint returns orders with state PLACED. Commands always have state PLACED.

Polling Guidance

  1. Poll on SSE message event — When the SSE stream sends a message event, call this endpoint immediately.
  2. Fallback interval poll — As a safety net, poll at a reasonable interval (every 5 seconds) even without SSE notifications.
  3. Use order offset — Track the highest number you have processed and pass it as orderNumber to avoid receiving already-processed orders.
  4. Use command offset — Similarly, track the highest command ID and pass it as commandNumber.
  5. Batch processing — You may receive multiple orders in one response. Process them in sequence, updating status for each.

Curl Examples

Success Response with Multiple Orders

bash
curl -i -H "api_key: abc123-def456-ghi789" \
  "https://{host}/orders/location"

Response:

http
HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "number": 12345,
    "orderTime": "10:30:00",
    "tableNumber": 12,
    "userNumber": 5,
    "rows": [
      {
        "category": { "order": 0, "id": 0, "description": "Beverages" },
        "itemType": "Beverages",
        "name": "Espresso",
        "number": 1,
        "factor": 2,
        "price": 3.50
      }
    ],
    "state": "PLACED",
    "isCommand": false
  },
  {
    "number": 12346,
    "orderTime": "10:32:00",
    "tableNumber": 5,
    "userNumber": 3,
    "rows": [
      {
        "category": { "order": 0, "id": 0, "description": "Main Course" },
        "itemType": "Food",
        "name": "Caesar Salad",
        "number": 1,
        "factor": 1,
        "price": 12.90
      }
    ],
    "state": "PLACED",
    "isCommand": false
  }
]

With Offset Parameters (after processing)

bash
curl -i -H "api_key: abc123-def456-ghi789" \
  "https://{host}/orders/location?orderNumber=12346&commandNumber=42"

Empty Response (no pending items)

bash
curl -i -H "api_key: abc123-def456-ghi789" \
  "https://{host}/orders/location"

Response:

http
HTTP/1.1 200 OK
Content-Type: application/json

[]

Response Containing a Command

bash
curl -i -H "api_key: abc123-def456-ghi789" \
  "https://{host}/orders/location"

Response:

json
[
  {
    "number": 99,
    "orderTime": "11:05:00",
    "readTableState": true,
    "tableNumber": 12,
    "state": "PLACED",
    "isCommand": true
  }
]

This is a Read Table State command for table 12. The readTableState: true indicates it is a command, not an order.

Error Handling

StatusMeaning
200Success (may return empty array [])
401Unauthorized (invalid or expired API key)
500Internal server error (retry with backoff)

Next Steps