Skip to main content
Authenticated API

This endpoint requires a valid JWT Bearer token. Accessible via the API gateway at /v1/commerce/*.

Orders API

Create, manage, and track restaurant orders across all channels.

Authentication Required

All endpoints require a valid Bearer token. See Authentication for details.

Overview

The Orders API supports all order types:

Order TypeDescriptionChannel
Dine-inTable service ordersStaff Shell, Voice AI
TakeoutCustomer pickupStaff Shell, Kiosk, Mobile
DeliveryThird-party or in-houseMobile App, Delivery Platforms
CateringLarge event ordersPlatform Portal
Bar TabOpen tabsStaff Shell

Order Lifecycle

DRAFT → OPEN → SENT → PREPARING → READY → SERVED → CLOSED
↓ ↓
MODIFIED PAID
StatusDescription
draftOrder being built, not submitted
openOrder created, items can be added
sentSent to kitchen, tickets created
preparingKitchen actively working
readyFood ready for pickup/service
servedDelivered to customer
closedOrder complete and paid

Create Order

Request

POST /api/v1/orders
Authorization: Bearer {access_token}
Content-Type: application/json
{
"location_id": "loc-xyz789",
"order_type": "dine_in",
"table_id": "table-7",
"customer_id": "cust-123",
"guests": 4,
"notes": "Birthday celebration"
}

Parameters

FieldTypeRequiredDescription
location_idstringYesRestaurant location
order_typestringYesdine_in, takeout, delivery, catering
table_idstringDine-inTable for dine-in orders
customer_idstringNoLink to customer profile
guestsnumberNoParty size
notesstringNoOrder-level notes

Response

{
"id": "order-12345",
"order_number": "1234",
"location_id": "loc-xyz789",
"order_type": "dine_in",
"status": "open",
"table": {
"id": "table-7",
"name": "Table 7"
},
"customer": {
"id": "cust-123",
"name": "John Smith"
},
"guests": 4,
"items": [],
"subtotal": 0,
"tax": 0,
"total": 0,
"created_at": "2026-01-18T12:00:00Z",
"created_by": "user-456"
}

Add Items to Order

Request

POST /api/v1/orders/{order_id}/items
Authorization: Bearer {access_token}
Content-Type: application/json
{
"items": [
{
"menu_item_id": "item-burger-01",
"quantity": 2,
"modifiers": [
{
"modifier_id": "mod-cheese",
"option_id": "opt-cheddar"
},
{
"modifier_id": "mod-temp",
"option_id": "opt-medium"
}
],
"special_instructions": "No onions",
"seat_number": 1
},
{
"menu_item_id": "item-fries-01",
"quantity": 2,
"seat_number": 1
}
]
}

Response

{
"order_id": "order-12345",
"items_added": [
{
"id": "line-001",
"menu_item": {
"id": "item-burger-01",
"name": "Classic Burger"
},
"quantity": 2,
"unit_price": 14.99,
"modifiers": [
{
"name": "Cheese",
"option": "Cheddar",
"price": 1.50
}
],
"special_instructions": "No onions",
"line_total": 32.98,
"status": "pending"
}
],
"subtotal": 42.96,
"tax": 3.65,
"total": 46.61
}

Send to Kitchen

Submit order items to the kitchen display system.

Request

POST /api/v1/orders/{order_id}/send
Authorization: Bearer {access_token}
Content-Type: application/json
{
"items": ["line-001", "line-002"],
"rush": false,
"fire_immediately": false
}

Parameters

FieldTypeRequiredDescription
itemsarrayNoSpecific items to send (default: all pending)
rushbooleanNoMark as rush order
fire_immediatelybooleanNoSkip hold for courses

Response

{
"order_id": "order-12345",
"tickets_created": [
{
"ticket_id": "ticket-001",
"station": "Grill",
"items": ["line-001"]
},
{
"ticket_id": "ticket-002",
"station": "Fry",
"items": ["line-002"]
}
],
"status": "sent"
}

Get Order

Request

GET /api/v1/orders/{order_id}
Authorization: Bearer {access_token}

Response

{
"id": "order-12345",
"order_number": "1234",
"status": "preparing",
"order_type": "dine_in",
"table": {
"id": "table-7",
"name": "Table 7"
},
"items": [
{
"id": "line-001",
"name": "Classic Burger",
"quantity": 2,
"unit_price": 14.99,
"modifiers": ["Cheddar"],
"status": "preparing",
"line_total": 32.98
}
],
"subtotal": 42.96,
"tax": 3.65,
"discounts": [],
"total": 46.61,
"payments": [],
"balance_due": 46.61,
"created_at": "2026-01-18T12:00:00Z",
"updated_at": "2026-01-18T12:05:00Z"
}

List Orders

Request

GET /api/v1/orders?
location_id=loc-xyz789&
status=open,sent,preparing&
order_type=dine_in&
start_date=2026-01-18&
limit=50
Authorization: Bearer {access_token}

Query Parameters

ParameterTypeDescription
location_idstringFilter by location
statusstringComma-separated statuses
order_typestringFilter by order type
table_idstringFilter by table
server_idstringFilter by server
start_datedateOrders from this date
end_datedateOrders until this date
limitnumberResults per page (default: 50)
offsetnumberPagination offset

Response

{
"orders": [
{
"id": "order-12345",
"order_number": "1234",
"status": "preparing",
"table": "Table 7",
"total": 46.61,
"created_at": "2026-01-18T12:00:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}

Modify Order Item

Request

PATCH /api/v1/orders/{order_id}/items/{item_id}
Authorization: Bearer {access_token}
Content-Type: application/json
{
"quantity": 1,
"special_instructions": "No onions, extra pickles",
"reason": "Customer request"
}

Void Order Item

Manager Approval Required

Voiding an order item requires a manager PIN. This action is audit-logged and cannot be undone. The voided item will be removed from the kitchen ticket if it has not yet been prepared.

Request

POST /api/v1/orders/{order_id}/items/{item_id}/void
Authorization: Bearer {access_token}
Content-Type: application/json
{
"reason": "Customer changed mind",
"manager_pin": "1234"
}

Apply Discount

Request

POST /api/v1/orders/{order_id}/discounts
Authorization: Bearer {access_token}
Content-Type: application/json
{
"discount_type": "percentage",
"value": 10,
"reason": "Birthday discount",
"item_ids": ["line-001"]
}

Discount Types

TypeValueDescription
percentage0-100Percentage off
fixedAmountFixed dollar amount
promo_codeCodePromotional code
comp-Full comp (requires approval)

Close Order

Request

POST /api/v1/orders/{order_id}/close
Authorization: Bearer {access_token}

Response

{
"id": "order-12345",
"status": "closed",
"closed_at": "2026-01-18T13:30:00Z",
"total": 46.61,
"payments": [
{
"id": "payment-001",
"method": "card",
"amount": 50.00,
"tip": 8.00
}
],
"balance_due": 0
}

Order Events (WebSocket)

Subscribe to real-time order updates:

ws.subscribe('orders', {
location_id: 'loc-xyz789',
events: ['created', 'updated', 'item_ready', 'closed']
});
EventDescription
order.createdNew order created
order.updatedOrder modified
order.item_readyItem ready from kitchen
order.closedOrder completed

Error Responses

Order Not Found (404)

{
"error": {
"code": "ORDER_NOT_FOUND",
"message": "Order does not exist"
}
}

Item Unavailable (400)

{
"error": {
"code": "ITEM_UNAVAILABLE",
"message": "Classic Burger is currently unavailable",
"item_id": "item-burger-01"
}
}