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"
}

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

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 mixes regular orders and commands. Classify commands using their type markers rather than depending on a computed isCommand flag:

  • 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.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) plus exactly one type marker:

Request bill (paymentNumber):

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

Fetch remote menu / export data (exportMainData):

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

Read table state (readTableState):

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

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 message and after connecting or reconnecting. Use a bounded fallback interval, for example five seconds, to check pending work.
  2. Prevent overlapping poll loops in the same worker. Coordinate multiple workers before external processing.
  3. Classify each result before using its number: order numbers and command IDs are separate sequences.
  4. Persist the external processing outcome, then acknowledge through the appropriate endpoint.
  5. Advance each offset only past work that has been resolved. If a lower-numbered item failed, advancing to a later success can hide that earlier item from subsequent polls.
  6. Treat an empty array as no pending work returned for those offsets, not proof that every previous operation completed.

Verify one order and one supported command at a test location before enabling continuous processing.

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"
  },
  {
    "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"
  }
]

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"
  }
]

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 ​